Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2018 updates #12

Open
wants to merge 11 commits into
base: gh-pages
Choose a base branch
from
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ anatomy-of-a-web-map

Slides for the Anatomy of a Web Map presentation!

View the presentation online here: http://maptime.github.io/anatomy-of-a-web-map/

Made with [@tmcw](https://github.com/tmcw)'s [big](http://macwright.org/big/) presentation software. Thanks to [@lyzidiamond](https://github.com/lyzidiamond) and the rest of the worldwide #maptime family!
NOTE! All the content will be on the gh-pages branch, not master. So go there! https://github.com/maptime/anatomy-of-a-web-map/?branch=gh-pages

Then you'll be able to view the presentation online here: http://maptime.github.io/anatomy-of-a-web-map/
Binary file added images/cleveland_at_bearing_pitch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/migration-economist-.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 43 additions & 46 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
};
</script></head><body>
<div>Anatomy of a <em>Web Map</em></div>
<div>By <a href="http://stamen.com/studio/alan">Alan McConchie</a> :) and <a href="http://stamen.com/studio/beth">Beth Schechter</a> :D</div>
<div>Housekeeping!<br>You can follow along here: <a href="http://sta.mn/qhg">sta.mn/qhg</a>. Links are in blue boxes, <em>green</em> is just emphasis. You can comment and edit on <a href="https://github.com/maptime/anatomy-of-a-web-map/">github!</a></div>
<div>By the folks at <a href="http://maptime.io">#maptime</a></div>
<div>Housekeeping!<br>You can follow along here: <a href="http://maptime.io/anatomy-of-a-web-map/">http://maptime.io/anatomy-of-a-web-map/</a>. Links are in blue boxes, <em>green</em> is just emphasis. You can comment and edit on <a href="https://github.com/maptime/anatomy-of-a-web-map/">github!</a></div>
<div>Now let's get started :)</div>
<div>Today we will be talking about the <em>very most basic principles</em> of web mapping.</div>
<div>We're including a little history, so you can get an idea of how web maps have come to be.</div>
Expand All @@ -105,10 +105,11 @@
<div>What is a web map?</div>
<div>To answer that question, maybe it's more helpful to ask,</div>
<div>How is a <em>web map</em> different than a <em>digital map</em>?</div>
<div><em>Digital</em>: involves a computer, but might not be accessible by the internet.</div>
<div><em>Digital map</em>: usually made on a computer; but it has > 1 zoom level*</div>
<div><img src="images/migration-economist-.jpg"></div>
<div>A <em>web map</em> is a kind of <em>digital map</em>. And both are obviously quite different from <em>analog</em> maps, such as paper maps and atlases!</div>
<div>We're talking about web maps that you view in a browser, like...</div>
<div><img src="images/osm.png"><a href="http://www.openstreetmap.org/">OpenStreetMap.org</a></div>
<div><img src="images/osm.png"><a href="https://www.openstreetmap.org/">OpenStreetMap.org</a></div>
<div><img src="images/google-map.png"><a href="https://www.google.com/maps/preview">maps.google.com</a></div>
<div><img src="images/mapsdotstamen.png"><a href="http://maps.stamen.com">maps.stamen.com</a></div>
<div><img src="images/iphone_maps.jpg">Making maps for <em>mobile devices</em> can be similar, but we're not talking about that today.</div>
Expand Down Expand Up @@ -147,42 +148,30 @@
<div>http://<em>tile.openstreetmap.org</em>/4/2/6.png -- this is the name of the tile server.</div>
<div>http://tile.openstreetmap.org/<em>4</em>/2/6.png -- this is the z value, or the zoom level.</div>
<div>http://tile.openstreetmap.org/4/<em>2/6</em>.png -- This is the x/y value, or the place in the grid where the tile lives.</div>
<div>Google maps use <em>Mercator projection</em>, which is designed for sailors BUT it works well for flat maps.</div>
<div>Most* web maps use <em>Mercator projection</em>, which is designed for sailors BUT it works well for flat maps.</div>
<div><a href="http://commons.wikimedia.org/wiki/File:1855_Colton_Map_of_the_World_on_Mercator_Projection_-_Geographicus_-_WorldMercator-colton-1855.jpg"><img src="images/mercator.jpg"></a></div>
<div>We'll see more map projections later...!</div>
<div>Anyway, so all other slippy maps and slippy map software followed Google's lead, with tiles at the base.</div>
<div>Anyway, so all other slippy maps and slippy map software followed Google's lead, with raster tiles at the base.</div>
<div><em> Raster </em> is an image, comprised of many pixels </div>
<div>Not surprisingly, a collection of <em>raster</em> tiles makes up what we call the map's <em>base layer.</em></div>
<div>When we layer things like markers on top of them, we call those <em>data layers</em> or <em>content layers</em> or <em>feature layers</em>.</div>
<div>When we layer things like markers on top of them, we call those <em>data layers</em> or <em>feature layers</em>.</div>
<div>*(Not every web map contains a feature layer, but they are fairly typical.)</div>
<div>They are often <em>vector</em> layers (point, line, polygon). Sometimes you can interact with them (clicking to produce a popup, for example).</div>
<div>Filetypes: GIS uses <em>shapefiles</em>, but web maps prefer <em>KML</em>, or more recently, <a href="http://github.com/lyzidiamond/learn-geojson">GeoJSON</a></div>
<div>These are usually <em>vector</em> layers (points, lines, polygons). Sometimes you can interact with them (clicking to produce a popup, for example).</div>
<div><em>Vector</em>: geometry-based </div>
<div>Filetypes: GIS uses <em>shapefiles</em>, but web maps prefer <a href="http://github.com/lyzidiamond/learn-geojson">GeoJSON</a>* </div>
<div>Here's the breakdown of how these pieces fit together:</div>
<div><img src="images/basemap-datalayers-01.png"></div>
<div><img src="images/basemap-datalayers-02.png"></div>
<div><img src="images/basemap-datalayers-03.png"></div>
<div><img src="images/basemap-datalayers-04.png"></div>
<div><img src="images/basemap-datalayers-05.png"></div>
<div><img src="images/basemap-datalayers-06.png"></div>
<div>Make sense?</div>
<div>Great!</div>
<div>What does the javascript library do? Grabs the tiles, adds content layer, handles interaction.</div>
<div>The javascript: we recommend <a href="http://leafletjs.com">Leaflet</a>, although there are others: <a href="http://openlayers.org">OpenLayers</a>, and <a href="https://www.mapbox.com/mapbox.js/api/">mapbox.js</a> </div>
<div>Now we're ready to dive a little deeper into the whole <em>web map anatomy!</em></div>
<div><img src="images/leaflet-toner-snapshot-giant.png"><em>The simplest possible web map:</em> <a href="http://sta.mn/v5h">sta.mn/v5h</a></div>
<div><a href="leaflet.html">leaflet</a></div>
<div><a href="leaflet-simple.html">leaflet</a></div>
<div>Make sense? Great! </div>
<div>Let's make a map but with a little less work! with umap!</div>
<div>umap.openstreetmap.fr </div>
<div><img src="images/leaflet_code.png"></div>
<div><img src="images/anatomy-of-a-web-map.png"></div>
<div>What does the javascript library do? Grabs the tiles, adds content layer, handles interaction.</div>
<div>The javascript: we recommend <a href="http://leafletjs.com">Leaflet</a>, although there are others: <a href="http://openlayers.org">OpenLayers</a> (which is making a comeback) / <a href="http://modestmaps.com">Modest Maps</a> / <a href="http://polymaps.org">Polymaps</a></div>
<div>And don't forget: <a href="https://developers.google.com/maps/documentation/javascript/">Google Maps API</a> / <a href="http://www.microsoft.com/maps/choose-your-bing-maps-API.aspx">Bing Maps API</a> / <a href="http://developer.here.com/web/guest/javascript-apis">Nokia HERE Maps API</a> / <a href="https://developers.arcgis.com/en/javascript/">ESRI ArcGIS API</a></div>
<div>3 exceptions to the simplified story!</div>
<div>Exception #1: Tiles are always rasters <em>EXCEPT</em> when they're not!</div>
<div><img src="images/vector_tiles.png"><em>vector tiles!</em> What are they? <a href="http://bl.ocks.org/wboykinm/7393674">(unrelated demo)</a></div>
<div><a href="https://www.mapbox.com/blog/vector-tiles/">vector tiles</a>: they are an alternative to a database that makes raster tiles. They still render to rasters for display</div>
<div><em>Raster:</em> ask for data to fit into tile</div>
<div><em>Vector:</em> already have vector data sliced up in the way that I will make raster tiles</div>
<div>So someone has to go through and chop up that data, like <a href="https://www.mapbox.com/blog/vector-tiles/">MapBox</a></div>
<div>Exception #2: Can’t interact with features on a raster. BUT <a href="https://www.mapbox.com/developers/utfgrid/">UTFGrid</a> (Mapbox invention) makes it possible.</div>
<div style="color: black"><img src="images/utfgrid.png">UTFGrid is an invisble tile layer made up of arbitrary letters which are indexes into the clickable data</div>
<div style="color: black"><img src="images/parks-conservancy.png">Stamen used this technique on the <a href="http://www.parksconservancy.org/map/#/?coords=15:37.8016:-122.4659&date=1394668684907">Parks Conservancy map.</a></div>
<div>Exception #3: <a href="http://d3js.org">D3</a> exists outside the world of tiles</div>
<div>But, now there's....</div>
<div><a href="https://d3js.org">D3</a> exists outside the world of tiles</div>
<div>you can’t easily make road map in D3 <em>BUT</em> can do things that are clumsy in slippy maps like...</div>
<div style="color: black"><img src="images/d3-examples/d3_choropleth.png">choropleth maps or... <a href="http://sta.mn/jyx">sta.mn/jyx</a></div>
<div style="color: black"><img src="images/d3-examples/d3_cartogram.png">cartograms or... <a href="http://sta.mn/q99">sta.mn/q99</a></div>
Expand All @@ -191,26 +180,34 @@
<div style="color: black"><img src="images/d3-examples/racial-divide.png">IS</div>
<div style="color: black"><img src="images/d3-examples/topojson.png">IN</div>
<div style="color: black"><img src="images/d3-examples/drought.png">SANE</div>
<div>Find these examples and more in Kai Chang's <a href="http://exposedata.com/talk/d3-geo/">d3.geo presentation</a></div>
<div>Very powerful, but steep learning curve</div>

<div>BUT WAIT:<a href="https://www.mapbox.com/blog/vector-tiles/">vector tiles</a> </div>
<div>and if you want to style your base map</div>
<div>3D Features</div>
<div>zoom levels, oh my!</div>
<div><img src="images/cleveland_at_bearing_pitch.png"></img></div>
<div>Large Data sets </div>
<div>change styling on the fly </div>
<div> BUT: can't use
<div>mapbox.com </div>
<div>These colors are so overwhelming! use <a href="https://www.mapbox.com/cartogram/"> mapbox cartogram </a></div>
<div>So.<br>Where do I start?</div>
<div>Do I need to make my own custom tiles?</div>
<div>No? Use these! <a href="http://wiki.openstreetmap.org/wiki/Tiles">OpenStreetMap</a>, <a href="http://cloudmade.com/products/map-tiles">CloudMade</a>, <a href="http://maps.stamen.com">Stamen</a>, <a href="https://www.mapbox.com/tour/#maps">MapBox</a>, <a href="http://developer.mapquest.com/web/products/open/map">MapQuest</a></div>
<div>Yes? Use <a href="https://www.mapbox.com/tilemill/">TileMill</a> to design your own tiles.</div>
<div><img src="images/worldwide-wood.png"> <em>Pretty!</em></div>
<div>Style your map with <a href="https://www.mapbox.com/carto">CartoCSS</a> (or just carto)</div>
<div>You can host these files on <a href="https://www.mapbox.com/plans/">MapBox</a>, or...</div>
<div>Serve the tiles by running your own tile server. For example: <a href="https://github.com/klokantech/tileserver-php/">TileServer.php</a> / <a href="http://tilestache.org">TileStache</a> / <a href="http://tilecache.org">TileCache</a> / <a href="https://github.com/mapbox/tilestream">TileStream</a> / <a href="https://github.com/chelm/mbtiles-server">mbtiles-server</a> / <a href=http://wiki.openstreetmap.org/wiki/Mod_tile">mod_tile</a></div>
<div>See Eric Theise's <a href="http://erictheise.com/maptime_platform_slides">Geo Platform tutorial</a> for all the gritty details</div>
<div>Do I need to make my own custom raster tiles?</div>

<div>No! Use these! <a href="http://wiki.openstreetmap.org/wiki/Tiles">OpenStreetMap</a>, <a href="http://maps.stamen.com">Stamen</a>, <a href="https://www.mapbox.com/tour/#maps">MapBox</a>, <a href="http://developer.mapquest.com/web/products/open/map">MapQuest</a></div>
<div>Do I need to create my own vector tiles? </div>
<div>No, you can use <a href="https://mapbox.com">MapBox</a> or <a href="https://openmaptiles.com/">openmaptiles </a> and <a href="https://maputnik.github.io/editor/"> maputnik </a> or you can create your own ($$)...</div>

<div>Serve the tiles by running your own tile server. For example: <a href="https://github.com/klokantech/tileserver-php/">TileServer.php</a> / <a href="http://tilestache.org">TileStache</a> / <a href="http://tilecache.org">TileCache</a> / <a href=http://wiki.openstreetmap.org/wiki/Mod_tile">mod_tile</a></div>
<div>See Eric Theise's <a href="https://erictheise.com/geostack-deck/#/">Geostack</a> for all the gritty details</div>
<div>Do I need a content layer?</div>
<div>No? Put all your data into the tiles, possibly using UTFGrid for interactivity</div>
<div>it depends... </div>
<div>Yes? Convert a Shapefile to GeoJSON with <a href="http://ogre.adc4gis.com/">OGRE</a> or write your own GeoJSON with <a href="http://geojson.io">geojson.io</a></div>
<div>Finally, <a href="http://cartodb.com">CartoDB</a> takes care of almost all of this for you!</div>
<div><img src="images/random/lurn_moar.jpg">Learn More:<br><a href="http://maptime.io/lessons-resources/">http://maptime.io/lessons-resources/</a></div>

<div>Thanks to:</div>
<div><a href="https://github.com/lyzidiamond">Lyzi Diamond</a></div>
<div><a href="http://stamen.com">Stamen</a></div>
<div>Everyone at <a href="http://maptime.github.io">#maptime</a></div>
<div><a href="https://github.com/lyzidiamond">Lyzi Diamond</a>, <a href="http://stamen.com/studio/alan">Alan McConchie</a>,<a href="http://stamen.com/studio/beth">Beth Schechter</a>, and Will Skora</div>
<div>Everyone else at <a href="http://maptime.github.io">#maptime</a></div>
<div>You!</div>
<div>Presentation made with <a href="http://www.macwright.org/big/">big</a></div>
48 changes: 48 additions & 0 deletions leaflet-simple.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!doctype html>
<html>
<head>
<title>My new map! </title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>

</head>
<body>

<div id="map-id" style="width: 60%; height: 600px; border: 1px solid #ccc;"></div>

<script>

var basemap = new L.TileLayer('https://api.mapbox.com/styles/v1/skorasaurus/cjm8df5wd09sc2spfluycp0oq/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1Ijoic2tvcmFzYXVydXMiLCJhIjoiaEdGTUZWTSJ9.osOC8tWU3bMaNprVNoEu7g', {maxZoom: 21});
var latlng = new L.LatLng(41.501860,-81.635799);

var myMap = new L.Map('map-id', {center: latlng, zoom: 10, layers: [basemap]});

var theMarker = L.marker([41.501860,-81.835799]).addTo(myMap);

var myStyle = {
"color": "#ff7800",
"weight": 5,
"opacity": 0.65
};

var geojsonLayer = L.geoJson.ajax("locations.geojson", {
onEachFeature: function(feature, layer) {
layer.bindPopup(feature.properties.name);
},
{
style: myStyle;
}
});

geojsonLayer.addTo(myMap);


</script>



</div>
</body>
</html>
191 changes: 145 additions & 46 deletions leaflet.html
Original file line number Diff line number Diff line change
@@ -1,48 +1,147 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"></script>
<style type="text/css">
#mapdiv { height: 100%; }
</style>
</head>
<body>
<div id="mapdiv"></div>

<script>

var geojsonFeature = {
"type": "Feature",
"properties": {
"name": "PARISOMA"
},
"geometry": {
"type": "Point",
"coordinates": [-122.41598, 37.77349]
}
};

var mapvar = L.map('mapdiv').setView([37.7706,-122.3782],12);

var tileLayer = L.tileLayer(
'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg',
{
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under CC BY 3.0. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under CC BY SA.'
}
);

mapvar.addLayer(tileLayer);

var geojsonLayer = L.geoJson(
geojsonFeature,
{
onEachFeature: function(feature, layer) { layer.bindPopup(feature.properties.name); }
}
);

mapvar.addLayer(geojsonLayer);

</script>

</body>
<head>
<title>My new map! </title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>

<style>
*, *:before, *:after {
box-sizing: border-box;
}

body {
margin: 40px;
font-family: 'Open Sans', 'sans-serif';
/* background-color: #fff;
color: #444;*/
}

h1, p {
margin: 0 0 1em 0;
}

.main-class {
/*max-width: 940px;*/
margin: 0 20px;
display: grid;
grid-gap: 10px;
}

/*@media screen and (min-width: 600px) {
*/
/* no grid support? */
.block-a, .block-b, .block-c {
float: left;
width: 79.1489%;
}

#map-id {
float: right;
width: 79.7872%;
}

.main-class {
margin: 0 auto;
grid-template-columns: 1fr 3fr;
grid-auto-rows: minmax(150px, auto);
}

.block-a {
grid-column: 1;
grid-row: 2;
}

.block-b {
grid-column: 1;
grid-row: 3;
}

.block-c {
grid-column: 1;
grid-row: 4;
}

#map-id {
grid-column: 2;
grid-row: 2 / 7;
}

/*}
*/
.main-class > * {
border-radius: 5px;
padding: 20px;
font-size: 150%;
/* needed for the floated layout*/
margin-bottom: 10px;
}

/* We need to set the widths used on floated items back to auto, and remove the bottom margin as when we have grid we have gaps. */
/*@supports (display: grid) {
.main-class > * {
width: auto;
margin: 0;
}
}*/
</style>
</head>

<body>
<div class="main-class">
<div id="map-id">
<h1>Using negative space</h1>
</div>

<div class="block-a"><h3>Base map</h3>(styling can be done in mapbox studio classic; geoserver; </div>
<div class="block-b"><h3>Data layer</h3>(styling can be done with the javascript library (leaflet, openlayers)</div>
<div class="block-c">Block C</div>
</div>


<script>

// var basemap = new L.TileLayer('http://{s}.tiles.mapbox.com/v3/skorasaurus.5eb85050/{z}/{x}/{y}.png', {maxZoom: 13});
var baseMap = new L.TileLayer('https://api.mapbox.com/styles/v1/skorasaurus/cjm8df5wd09sc2spfluycp0oq/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1Ijoic2tvcmFzYXVydXMiLCJhIjoiaEdGTUZWTSJ9.osOC8tWU3bMaNprVNoEu7g', {maxZoom: 21});

var latlng = new L.LatLng(41.501860,-81.635799);

var myMap = new L.Map("map-id", {center: latlng, zoom: 10, layers: [baseMap]});


var theMarker = L.marker([41.501860,-81.835799]).addTo(myMap);

var myStyle = {
"color": "#ff7800",
"weight": 5,
"opacity": 0.65
};

var geojsonLayer = L.geoJson.ajax("locations.geojson", {
onEachFeature: function(feature, layer) {
layer.bindPopup(feature.properties.name);
},

style: function (feature) {
return myStyle;
}
});

geojsonLayer.addTo(myMap);

// Add AJAX request for data
// var counties = $.ajax({
// url:"./locations.geojson",
// dataType: "json",
// success: console.log("County data successfully loaded."),
// error: function (xhr) {
// alert(xhr.statusText)
// }
// })

</script>
</main>
</body>
</html>