One of the major projects we have kicked off over the past few months is an online National Park Service-styled basemap we are calling Park Tiles. In this blog post, I’ll briefly discuss the design rationale behind Park Tiles and give a brief overview of the data and technology we are using to drive this project.
Background
As more and more Park Service groups and partners move to the web, we’ve found a need for a customized NPS basemap that can be used as a backdrop to display the wide variety of spatial data that are collected and maintained by the service.
Currently, the NPS uses basemaps from various providers, including Bing, Esri, Google, and MapBox. For certain projects, however, we are looking for more stylistic control over these basemaps. Some of these providers allow us to modify colors and turn some layers on and off, but often when we mash up our content on these basemaps there is a lot of overlap and our information doesn’t come to the foreground as much as we would like.
Park Tiles is not meant to be a total replacement for any of the basemaps we currently use. It is, rather, meant to give us an alternative basemap we can use in custom projects where we’d like to see our National Parks highlighted. We’d also like to incorporate more detailed park information (such as campsites, visitor centers, trails, etc.) at larger scales that can serve both NPS employees and visitors.
Most importantly, the National Park Service has a strong cartographic tradition that has been developed by the cartography team at the Harpers Ferry Center in West Virginia. Our primary goal with this online map is to transfer that tradition to the web. We are doing this by using NPS fonts, colors, and symbols. It is also important for us to maintain the graphic identity of the NPS so when we embed web maps in park pages, the maps compliment the existing style.
Design
We have designed Park Tiles with a subdued style and a limited number of colors and information. As you can see below, the shaded relief and reference information on the map are designed using colors that are low in saturation. To contrast, the National Park points, polygons, and labels are symbolized and labeled using colors with higher saturation so they come to the foreground. We have limited the features displayed on the map knowing that if we need to add additional reference information, we have the freedom to do so. All of this has been done with the goal of clearly identifying National Park units and creating a basemap that can support multiple overlay types symbolized using a wide variey of colors.

Data
The data we are using to build this map come from a variety of publicly available sources. The ScaleMaster diagram below shows the data source of each feature by zoom level (or scale). We are using data from the NPS at all scales for park units. Natural Earth data is used for reference information like administrative boundaries, administrative labels, roads, urban areas, and hydrography at small scales. We are using DEMs of varying resolutions for relief from NASA and the USGS.
At larger scales (zoom level 8 and above), we begin to switch data sources. Urban areas switch from Natural Earth to the US Census Bureau, coastlines are drawn from NOAA, and the majority of other features come from OpenStreetMap (OSM). Specifically, we are experimenting with OSM data at large scales to display features like points of interest, trails, and more detailed base data.
Larger scale designs (zoom level 10 and above) are still being prototyped. We prefer to use data from Parks, when available. In cases where individual Parks do not have data, we are currently exploring alternatives, particularly OSM.

Technology
We are using a combination of technologies to build and serve this map. To read in data from OSM we are using a couple of different approaches, including Imposm and osm2pgsql. Both of these tools allow us to manage and query OSM data using PostgreSQL and PostGIS. Park units are managed in a SQLite database, and the remainder of the data (for now) are managed in shapefiles.
The primary tool we are using to design Park Tiles is TileMill. TileMill is an open source design studio where multiple data formats can be read, queried, and styled. To create the shaded relief, we’re using Natural Scene Designer and Photshop. For icons like highway shields and POI’s (at larger scales), we are using Inkscape. We’re also using some other tools, including Dymo for labeling and High Road to query and symbolize our road layers at zoom levels 8 and above.
We’re serving our map using MapBox Hosting and consuming services with web maps built with the NPMap JavaScript library. In order to give ourselves the greatest flexibility of use, we’re thinking of innovative ways to serve and consume our basemap.
Take a Tour
So far, Park Tiles is available for zoom levels 4-9. We’re actively working on incorporating more zoom levels – we’ll keep you updated!
You can view Park Tiles here. If you click on the “Switch” button, you’ll see our initial large scale prototype of Mt. Rainier National Park that uses all OSM data.
Stay Tuned
Look for a follow-up blog post where we’ll describe, in detail, how we are looking to serve our basemap.
Posted on 26 Jul 2012 by Nate Irwin
I gave an introductory presentation about NPMap to a group of NPS web authors today, and thought it would be cool to post it to the web so others can take a look.
Here’s the link: http://www.nps.gov/npmap/decks/overview-of-npmap/.
The presentation itself is actually written entirely in HTML, CSS, and JavaScript. It includes some interactive examples of our team’s work and a live code editor that you can use to play around with NPMap’s config options. It is based off of the Google HTML5 slide template, although we added quite a bit of functionality on top of what was provided in the Google template. We are currently working on open sourcing a handful of our projects, including the NPMap library, and we’ll add the slide deck template to that list.
We plan on updating the presentation as we build new web maps and release new versions of our library, so it probably makes sense to consider it a “living document”. Enjoy, and please let us know if you have any suggestions to help us improve our communication! You can reach us by email: npmap at nps dot gov.
Back in March, we were asked by the NPS Office of Communications to design and develop a web map that displayed the National Parks which were good viewing places for the May 20th annular solar eclipse. Our goal was to make a simple web map that displayed the path of the annular eclipse, along with the parks which would have a view of full annularity (parks symbolized in yellow) and a view of the partial eclipse (parks symbolized in orange). The map we created was embedded in the Natural Resources Program Annular Eclipse website.
To create and serve this web map we used a combination of technologies: ArcGIS and QGIS for data processing, TileMill for design, Dymo for labeling, TileStream to serve the tiles, and the NPMap library to develop the web map.
This post specifically covers how we used the open source labeling tool, Dymo, to improve label placement on the map.
The challenge
We encountered one of the biggest challenges for this project while attempting to label the densely-packed National Parks in TileMill. As highlighted below in red, using TileMill’s labeling engine resulted in overlapping labels that made park names illegible.

While looking for a better labeling solution, we came across Dymo, a Python script that was created by Michal Migurski and GeoIQ while designing GeoIQ’s Acetate basemap.
Dymo ”converts lists of cities (or, in our case, National Parks) with included font information into GeoJSON point and label files suitable for use in geographic rendering.” To summarize: Dymo takes an input CSV file and creates a GeoJSON file based on a process it runs called simulated annealing. This process finds the best non-overlapping position for each label around a point. The GeoJSON files produced by Dymo can be added to TileMill, and used to add labels to tilesets.
Using Dymo, we were able to avoid label overlaps and improve the overall legibility of park names dramatically. The following image shows labels and parks for the same area as the first image after running Dymo.

Note: We only ran Dymo on our National Park labels and not on our cities or states. Because of this, you’ll notice there are park labels overlapping with both city and state labels on the map. In our more recent maps, we’ve run Dymo on all labels, avoiding any overlaps between labels.
Process
Here’s the process we went through to place the National Park labels:
1. Install Dymo
To install Dymo, follow the directions posted in the GitHub repository.
2. Data preparation
Note: A portion of the data preparation process outlined below is for ArcGIS Desktop. The same process can be done in QGIS. UPDATE: Thanks to Nathaniel Kelso for these instructions for QGIS.
The first step was to prepare our National Park point data (which was in Shapefile format). This was a three part process: First, we selected, by scale, which labels would appear, then we added additional attributes using ArcGIS and third, we created a CSV file for each zoom level.
-
We selected which parks should be labeled at each scale by using two attributes: the quality of the view the park would have of the solar eclipse and the park’s area.
-
Dymo requires latitude and longitude coordinates for each feature. We added this information to our National Park point dataset in ArcMap using the following steps:
-
Add two fields to the attribute table: “latitude” and “longitude”, in the "Add Field" dialog. Set “Type” to “Double”.
-
Right-click on both of the newly-added field and select “Calculate Geometry”. In the “Calculate Geometry” dialog, use the dropdown to calculate the “Y Coordinate of Point” for the “latitude” field and the “X Coordinate of Point” for the “longitude” field, ensuring that you set “Units” to “Decimal Degrees”.
-
Once the latitude and longitude coordinates are calculated, the next step is to export a set of given records by zoom level. To do this, we wrote a Definition Query in ArcMap that selected only the National Parks we wanted to label at a given zoom level. Once the records were selected, we exported the resulting shapefile into our project directory. (To export a shapefile from ArcMap right click on it in the Table of Contents and select Data>Export Data). For our map, we had National Park labels at zooms 5-7. This means we had three shapefiles -- one for each zoom level we were labeling.
3. Prepare a CSV to run with Dymo
Dymo requires the following fields in each zoom level’s CSV file:
|
name
|
the name of the feature you want to label
|
|
latitude
|
the latitude, in decimal degrees, of the point feature
|
|
longitude
|
the longitude, in decimal degrees, of the point feature
|
|
font size
|
the font size of the label you want placed
|
|
font file
|
the font type and location of the font file
|
|
point size
|
if you are symbolizing points to go along with your labels, the size of the points
|
|
preferred placement
|
if there is a particular label you want placed in a specific location around a point, you can add it here (example: top, right, left, etc.)
|
You can also add a population field if you want to add hierarchy to your labels. This is especially useful for city labels where categories of city labels (large, medium, small) are drawn using different font sizes. For this map, we did not implement any hierarchy for park names; they all were labeled using the same font size.
To prepare our CSV, we opened the DBF attribute information of each zoom level’s Shapefile in an OpenOffice Spreadsheet, formatted it accordingly, and saved it as a CSV.
Here is a portion of what our CSV for zoom level 5 of the Solar Eclipse web map looked like:

4. Run Dymo
When you install Dymo, folders are created in your working Dymo directory. The data folder is where each scale level’s CSV should be placed. Place a copy of the font you are using for your labels in the fonts folder.
In your Terminal window, cd to Dymo:
cd /Development/Dymo
Then run Dymo. We ran the following command in Terminal for zoom level 5:
python dymo-label.py -z 5 --minutes 2 --labels-file labelszoom5.json --places-file pointszoom5.json data/zoom5.csv
Here’s a basic description of the parameters. More information on the parameters can be found in the Dymo documentation:
|
-z
|
this defines the zoom level you are generating labels for, and should be adjusted each time you run the tool for a new zoom level
|
|
--minutes
|
this defines the amount of time the tool will run to find the best placement for labels, and can be adjusted if Dymo doesn't find an ideal placement for your labels within the default of 2 minutes
|
|
--labels-file
|
the name of the output file
|
|
--places-file
|
the name of the output point file
|
The tool creates two GeoJSON outputs that are placed in the root Dymo folder. Based on the information we entered in the command above, our two output files will be labelszoom5.json and pointszoom5.json.
The labelszoom5.json file contains the rectangular area in which the label has been placed given the font, font size, point size, and placement information from the CSV (the purple rectangles seen around each label in the image below). The pointszoom5.json file contains the center points of places successfully placed by Dymo. If you want to place point symbols along with your labels, you can use this file.
5. Symbolize the files in TileMill
Next, we brought the Dymo output into TileMill:
You’ll notice that the font style and size information from our CSV is used in the style rule. We’ve also defined the color of the labels and applied a small halo. The text-allow-overlap property ensures that TileMill will allow all of our labels to draw even if there is another feature close by. Based on these definitions, the labels for zoom 5 look like this (clean and without overlaps!):

You should repeat the steps outlined above for each zoom level.
6. Manual editing (optional)
There may be some instances where editing the location of labels is necessary. To do this, add the GeoJSON output from Dymo to QGIS. Next, right-click on the file in the Table of Contents and select “Save as…” In the “Save vector layer as…” format drop-down, select “ESRI Shapefile”.

Once the Shapefile is saved, you can add it to QGIS (or ArcGIS) and begin editing the position of the rectangular labels.
Conclusion
In this post, we’ve described the process we use to label our maps using Dymo and TileMill. We are extremely satisfied with the labeling results we get using this tool, especially when compared to the default labeling available in the current version of TileMill. Dymo becomes even more indispensable for us when generating labels at smaller scales where placement is even more difficult. We currently use Dymo for label placement for all of our web maps designed in TileMill.
Posted on 20 Jun 2012 by Nate Irwin
We were recently asked to help redesign the nps.gov park maps (you can see the current version of a park map by going to http://www.nps.gov/yell and clicking on “View Park Map” on the left-hand side of the page). The maps are simple “Zoomify” versions of the Harpers Ferry Center park maps. These tiles can be created by a variety of tools, including the Zoomify Converter and Adobe Photoshop.
There are a few problems with the current approach:
- Most of the maps haven’t been georeferenced, so they can’t be overlaid on a traditional web map
- The current park map interface is Flash-based, which means it doesn’t work on iPads and iPhones
Before starting work on the new interface, we came up with a few requirements. Namely, we wanted to:
- Use only standard web technologies (no plugins)
- Support tiles stored in both the Zoomify and standard XYZ formats
- Implement an approach that supports geolocation and the more traditional web mapping paradigm
Our approach
We decided to use NPMap’s Leaflet base API, as it has great mobile support, is lightweight, and uses hardware acceleration and animations (where supported) to make pretty maps. Leaflet, however, does not support simple (1:1) coordinate reference systems out of the box, so we had to extend the API ourselves. Thankfully Leaflet is open source, so we were able to piece together the different pieces with help from a few different sources: http://map.agent-orange.ca/, https://github.com/migurski/canvas-warp/blob/master/zoomify.html, and http://openlayers.org/dev/examples/zoomify.html.
We added this support directly into NPMap, so you can now add a Zoomify tile layer via the baseLayers or layers configs in the NPMap config object:
baseLayers: [{
height: 5180,
type: 'Zoomify',
url: 'http://www.nps.gov/npmap/support/examples/data/kefj/img/',
visible: true,
width: 5169
}]
A simple example is available here: http://www.nps.gov/npmap/support/examples/leaflet-zoomify.html.
We also wrote some code that pulls data in from the XML metadata file (created by Zoomify/Photoshop during the tile creation process) and uses the metadata to automatically set the min/max zoom levels and extent of the web map. You can see an example here: http://www.nps.gov/npmap/support/examples/leaflet-zoomify-automatic-extent.html.
Future plans
The redesigned maps have been tested in all of the desktop browsers we support, and they work well on modern mobile devices too. We hope to have the new interface built and deployed to the nps.gov park pages in the next few months. That said, there are still a few “to-dos”:
- As mentioned above, we want to migrate to georeferenced maps so we can support geolocation. Now that we’re using NPMap with Leaflet it should be easy to add this support in the future.
- We are still working on print support. This should be ready to go by the time we release the maps.
- We eventually want to take this even further by switching the park maps over to tilesets created and maintained in GIS. We’ve kicked this project off, and will have an update on it soon here on the blog.
Posted on 23 May 2012 by David Warren
Note: This is an excerpt from a tutorial I'm working on for the
support documentation. The example below uses the current development version of NPMap, 0.8.0, so the API may change slightly over the next couple of months. You can keep up with development on 0.8.0 by visiting the
releases page.
You’ve made a lot of progress: All the way from planning your web map, to setting up your development environment, creating your HTML page, and creating your web map. Now it’s time to start getting into the fun stuff – customizing your web map.
NPMap gives you a lot of customization options, making it easy to set the geographic extent when your map is initially loaded, add navigation tools, and toggle between different basemaps. You can find targeted examples that demonstrate NPMap’s capabilities in the examples section of the support documentation.
In this post, we’re going to take a look at a few of NPMap’s tools. Let’s say I have the following basic requirements for my web map:
- I want to use the Bing base API, with the ability to switch between different Bing base maps.
- I want to add a button that will allow the user to pan or zoom back to the initial extent of the map by clicking on it.
- I want to add zoom in/out navigation tools to my map.
Here’s the code I have so far:
<!doctype html>
<html>
<head>
</head>
<body>
<div id="map" style="height: 500px; width: 500px;">
</div>
<script>
var NPMap = NPMap || {};
NPMap.config = {
api: 'bing',
div: 'map'
};
(function() {
var s = document.createElement('script');
s.src = 'http://www.nps.gov/npmap/0.8.0/bootstrap.js';
s.type = 'text/javascript';
document.body.appendChild(s);
})();
</script>
</body>
</html>
When I open this in a browser, my web map appears with a simple Bing base map that uses the default configuration. The first thing I would like to do is add the ability to switch between different Bing basemaps. You can find an example of using the layer switcher with Bing Maps here: http://www.nps.gov/npmap/support/examples/npmap-tools-switcher-bing.html. To accomplish this, I’m going to add this snippet of Javascript to my NPMap.config object:
baseLayers: [{
code: 'aerial',
visible: false
},{
code: 'road',
visible: true
}],
So now my code looks like this (the new snippet is highlighted):
<!doctype html>
<html>
<head>
</head>
<body>
<div id="map" style="height: 500px; width: 500px;">
</div>
<script>
var NPMap = NPMap || {};
NPMap.config = {
api: 'bing',
baseLayers: [{
code: 'aerial',
visible: false
},{
code: 'road',
visible: true
}],
div: 'map'
};
(function() {
var s = document.createElement('script');
s.src = 'http://www.nps.gov/npmap/0.8.0/bootstrap.js';
s.type = 'text/javascript';
document.body.appendChild(s);
})();
</script>
</body>
</html>
The switcher tool is added to the top-right hand side of the map, with a dropdown arrow that allows the user to switch between street and aerial view.

Now I would like to add simple navigation tools to help the user zoom in and out and pan around the map. NPMap offers a few navigation tools that make it easy to zoom and pan. These can be adding by inserting this Javascript snippet:
tools: {
pan: 'home',
zoom: 'small'
},
So my code now looks like this (the new snippet is, again, highlighted below):
<!doctype html>
<html>
<head>
</head>
<body>
<div id="map" style="height: 500px; width: 500px;">
</div>
<script>
var NPMap = NPMap || {};
NPMap.config = {
api: 'bing',
baseLayers: [{
code: 'aerial',
visible: false
},{
code: 'road',
visible: true
}],
tools: {
pan: ‘home’,
zoom: ‘small’
},
div: 'map'
};
(function() {
var s = document.createElement('script');
s.src = 'http://www.nps.gov/npmap/0.8.0/bootstrap.js';
s.type = 'text/javascript';
document.body.appendChild(s);
})();
</script>
</body>
</html>
The pan property adds a button to the top-left of the map. It contains arrows that allow you to navigate north, south, east, and west. I can tell NPMap to add a 'home' button to the middle of the pan tool by setting pan: 'home'. When the home button is clicked, it pans/zooms the map back to the initial extent of the map.

And now we have a simple web map with navigation and base layer switcher tools.
This example demonstrates just a few of the tools that are available in the NPMap library. The library also gives you the ability to add an overview map, alert your users using the notification tool, and add functionality to your web map using the route and edit modules. Many more tools are coming in the next release (0.8.0) of the library, so stay tuned!