A Crash Course in Map-Making
for the National Day of Civic Hacking
June 6, 2015
courtesy of @MaptimePGH
What is Maptime?
- A time for learning about maps
- Hands-on
- Beginner-focused
- Emphasis on open source, programming, and web-mapping
PLEASE interrupt if you have questions!
For today, think about a map as a combination of four components:
Geography + Base Map + Data
Geography + Base Map + Data + Platform
Components
- Geography
- Base Map
- Data
- Platform
|
This list is:
- the way you conceptually organize a mapping product
- your map-making workflow
- your technology stack
|
Part 1: Geography
~
from Greek geographia,
literally "earth description"
(source)
Maps describe Earth.
Maps are a visualization of data in geographic space.
data -> visualization
places on Earth are represented as places on usually flat surfaces, like print-outs or computer screens
doing this requires a:
- a system for describing locations
- a method for projecting a location on Earth to a location on a flat map
A coordinate system describes locations.
Locations are identified using latitude / longitude (lat/lon) decimal degrees.
|
maps location: |
represented with: |
units: |
LATITUDE |
north-south |
horizontal lines, different circumferences |
-90 to +90 decimal degrees |
LONGITUDE |
east-west |
vertical lines, same circumferences |
0 to 180 decimal degrees |
Lat/Lon is used to represent location on both the Earth as a globe (a sphere-like 3-D object) and Earth as a map (a planar, 2-D object)
To go from a globe, which looks like this...
...we need a map projection
a method in the form of a mathematical equation for stretching and warping the lat/long grid of the globe to fit a planar map
There are lots of ways to project the globe
But there is no way to project the globe without distorting it.
Distortion is typically worst at the edges of the map, affecting relative scale.
To avoid distortion, many projections are purpose-built:
they are specific to an area, or are designed for functionality (e.g., measuring distances from a certain point).
Pennsylvania State Plane (South)
A few projections provide a decent balance between
- relative scale,
- visually-pleasing proportions,
- and straighforward measure-ability
on a global scale.
Web Mercator
EPSG code: 3857
East-West distance is constant. North-south distance is distorted close to the poles.
Why you need to know this:
Web Mercator is the projection commonly used for web maps and typical web map-making software/tools/libraries.
Local data in southwestern Pennsylvania is typically stored in PA State Plane (South) / EPSG 2272. It uses feet, not decimal degrees, and must be re-projected to use in a web map.
Part 2: Base map
~
Your map needs contextual data:
roads, rivers, points of interest, etc.
Fear not. Someone else has already pulled all of this this together for you in
Open Street Map
Two ways to view/edit OSM:
web (basic): iD
desktop (advanced): JOSM
What can I do with OSM? Suggestions:
- Use one of the editors to trace some buildings, add some POIs (points of interest), identify local place names
- Play MapRoulette
- Do some HOT tasks (Humanitarian OSM Team)
- Go outside and map with Field Papers
- Export some data for use in desktop GIS software
"I'm not interested in contributing to OSM right now, but I need a basemap."
- Quickly create and reference a custom-styled basemap with Map Stack
(We will use this later!)
- Create and host a custom web map with
MapBox Studio or
CartoDB
Why you need to know this:
Base maps provide context. Using the right base map can make your data POP.
The benefit of using a base map like OSM is that if you find a discrepancy, it is within your power to fix - and everyone wins.
Part 3: Data
~
the stuff you are interested
in putting on a map
Data that has geographic attributes is Geodata. It represents things that have a location.
This can include defined physical or abstract features like
- roads
- buildings
- census boundaries
Data can be either be Raster or Vector.
Raster data stores its geographic information in pixels.
Vector data stores geometry, attributes, and location information as points, lines, or polygons
Vecotr file formats
Vector geodata comes in a lot of formats. The most common are:
- Shapefile: actually collection of (usually) four files: .shp, .dbf, .shx, and .prj. Very common, but cannot be used for web-maps
- GeoJSON: a geographic implementation of Javascript Standard Objection Notation (JSON)
- KML: a geographic XML implementation. the zipped version is KMZ.
Most of these files are shapefile formant. To use on the web, you'll need to reproject them to Web Mercator and then convert them to either GeoJSON or KML.
For converting and reprojecting, you'll need to use desktop Geographic Information Systems (GIS) software like QGIS (free) or ArcGIS (not free, but is the industry standard).
"I have some data with addresses in a table, but I don't have coordinates."
You're in luck. You can take that spreadsheet of things you want to map and turn it into geodata through a process called Geocoding.
Part 4: Platform
~
use a web map to display and share your data
First: there are some great off-the-shelf tools for building web maps out there.
Consider using one of those if you're a beginner.
If you're comfortable with html, css, and javascript, then you can try your hand at something custom using some of the tools we've highlighted today.
Tech We'll Use
- A text editor, for writing some HTML and assembling the Leaflet script
- MapStack, for making a basemap.
- GeoJSON.io for creating, editing, viewing data.
- Leaflet, for generating the map
- Github Pages, for web hosting (optional)
Black n' Gold Basemap with MapStack
The base element of this project is the basemap. To keep it simple, we are going to use MapStack. The image filters and effects offer a wide variety of customization.
When you're happy with what you've created, copy the tile url of the live map by right clicking the map and follow your browser dialog to copy the link.
Paste the url text from your MapStack map ino a text editor - we need to make some tweaks to get it ready for use in our map.
The url should look something like:
http://d.sm.mapstack.stamen.com/toner/11/568/771.png
(Note that depending on how custom you made your map, it may be very long)
We need to tweak this to make it generic and useful for Leaflet. The portions highlighted in red need to change.
Change the variables in url like this:
http://{s}.sm.mapstack.stamen.com/toner/{z}/{x}/{y}.png
The bracketed pieces of the url example above -- {s},{z},{x}, and {y} -- are placeholders that allow for the correct tiles to be loaded by Leaflet into our web map.
Where are all the Pierogies?
We've collected some pierogie geodata as GeoJSON.
The .geojson file contains some of the pierogie sources from the region. You can load up this file in GeoJSON.io to add more data in an easy-to-read tabular format, or edit the GeoJSON text directly.
Generate the map with Leaflet
Leaflet is a JavasScript library that does the work of pulling our data and basemap together within HTML.
Using the documentation from the starter tutorial on Leafletjs.com, we are going to start with the most basic components needed for a map:
- Add Leaflet starter code
- Create the Map element
- Add our tile layer URL from MapStack
The result will be a web map that displays your MapStack basemap in the browser, with the ability to pan and zoom around.
Add Leaflet starter code
See the leaflet tutorial.
References to Leaflet javascript and css must be included in the HTML header.
A div tag in the body must refer to the "map" element
css must specify the size of the "map" element
Create the Map element
Within the script tags:
var map = L.map('map').setView([40.4452, -79.9866], 10);
Note that SetView sets the longitude, latitude, and zoom
Add our tile layer URL from MapStack
Within the script tags:
L.tileLayer(
'http://{s}.sm.mapstack.stamen.com/toner/{z}/{x}/{y}.png',
{attribution:'credit where credit is due', maxZoom: 18, minZoom: 8,}
).addTo(map);
Note that we use the generic Map Stack url here.
Display the data
Use Leaflet to add our .geojson file.
L.geoJson(pierogie_geojson, {
pointToLayer: function(feature, latlng) {
var marker = L.marker(latlng, {icon: pierogie_icon});
marker.bindPopup(feature.properties.name);
return marker;}
}).addTo(map);
L.geoJson(pierogie_geojson...
Leaflet displays GeoJSON data, but does not load an externally-stored GeoJSON file. You have a few options to load it, including using JQuery.
But one simple way is to save the geojson object as a var in an external .js file.
var marker = L.marker(latlng, {icon: pierogie_icon});
We can use almost any image file for a marker, and we've got one suitable for pierogies.
marker.bindPopup(feature.properties.name);
Use Leaflet to dynamically generate a pop-up for each pierogie from the point's attributes:
- 'bind' a pop-up to the marker
- create the text and attribute references (using GeoJSON keys)
- optionally style the text using HTML/CSS