Map as tool to represent the real world
All information is more or less geographic
+
a powerful tool to visualize information
Present the data with more dimentions
Put the field data back to the field
Interact like it's at the real-world
What does geographic data look like in web development?
Raster Data
Vector Data
Raster Data -> Tiled Images
256 x 256
the whole world is cut using a quadtree
Zoom Level
Scale
1
19
Globe
Street
Basemap Service
https://www.map-provider/{z}/{x}/{y}.png
Vector Data
Geographic JSON - GeoJSON
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {...}
"properties": {
"name": "BuffaloJS",
"event": "Introduction to Leaflet",
"date": "12/12/2016"
}
}
]
}
Point Geometry
(x, y) = (longitude, latitude)
in GeoJSON
{
"type": "Point",
"coordinates": [-79, 36]
}
Line Geometry
(x1, y1), (x2, y2), ..., , (xn, yn)
in GeoJSON
{
"type": "LineString",
"coordinates": [
[-69, 35],
[-68, 45]
]
}
Polygon Geometry
(x1, y1), (x2, y2), ..., , (xn, yn)
in GeoJSON
{
"type": "Polygon",
"coordinates": [
[[-69, 35], [-68, 45], [-65, 40]]
]
}
 (a1, b1), (a2, b2), ..., , (an, bn)
outer ring
inner ring
What if I want to
geojson.io is a simple but powful tool at your hand.
an open-source JavaScript library
for mobile-friendly interactive maps
as a project for simpler web mapping by
Vladimir Agafonkin at 2008
within a greate open-source community
Leaflet's data model
Let's create a map with Leaflet.
Define the map frame
<!DOCTYPE html>
<html>
<head>
<!-- load leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.2/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.0.2/dist/leaflet.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map', {
center: [42.875551, -78.869219],
zoom: 5
});
</script>
</body>
</html>
Add basemap
var basemap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
map.addLayer(basemap);
Add locations as map markers
// UB
var start = L.marker([43.000852, -78.789389]);
map.addLayer(start);
// Downtown
var end = L.marker([42.886135, -78.873784]);
map.addLayer(end);
Create path from GeoJSON
// just a geojson example
var path = {
type: 'Feature',
geometry: { type: 'LineString', coordinates: [[0, 0], [1, 1]] }
properties: {}
};
var pathLayer = L.geoJSON(path);
map.addLayer(pathLayer);
Create a map is simple like this!
Task I
Task II
Click on the start/end point to show the location information
Hover on the path to see the address of that location
But I said interactive...
Task I
Bind a popup to the marker.
var startLocation = '<h3>University of New York at Buffalo</h3>' +
'<p>Capen Hall, Buffalo, NY 14260</p>';
start.bindPopup(startLocation);
var endLocation = '<h3>Rand Building</h3>' +
'<p>14 Lafayette Square, Buffalo, NY 14203</p>';
end.bindPopup(endLocation);
Task II
var checkPoint;
pathLayer.on('mouseover', function(e) {
// current mouse coordinate
var latlng = e.latlng;
// OpenStreetMap geocoding API
var url = 'http://nominatim.openstreetmap.org/reverse?' +
'lat=' + latlng.lat +
'&lon=' + latlng.lng +
'&format=json';
// a function to send the request and return the result in a Promise
get(url)
.then(function(result) {
// create a popup and set its location and content
checkPoint = L.popup()
.setLatLng(latlng)
.setContent('<p>' + result.display_name + '</p>')
.openOn(map);
});
});
pathLayer.on('mouseout', function() {
if (checkPoint) {
// remove the popup from the map
checkPoint.remove();
checkPoint = null;
}
});
Styling
Marker Icon with Image
var startMarkerIcon = L.icon({
iconUrl: 'http://maps.google.com/mapfiles/kml/shapes/schools.png',
iconSize: [30, 30]
});
start.setIcon(startMarkerIcon);
Marker Icon with... whatever
var html = '<span class="fa-stack fa-lg">' +
'<i class="fa fa-circle fa-stack-2x" style="color: #286090"></i>' +
'<i class="fa fa-building fa-stack-1x fa-inverse"></i>' +
'</span>'
var endMarkerIcon = L.divIcon({
html: html,
className: ''
});
end.setIcon(endMarkerIcon);
Styling
Set path style with svg properties
var pathStyle = {
color: '#fff',
weight: 4,
dashArray: '10, 8'
};
pathLayer.setStyle(pathStyle);
Even cooler!
A rich collection of plugins
Animated Map using L.Polyline.SnakeAnim
Editable Map using leaflet.draw
Yes, this is also Leaflet, by Pedro Sousa
More resources
Join MaptimeBUF for more mapping events and talks!
Thank You!
Haoliang
haoliang.yu@outlook.com