Post on 15-May-2015
description
Beyond GoogleMapsAndrew Turner, Mapufacture & FortiusOne
or...
Evolved Maps, desconstructed
or...
A Brief History of Mapping
*IANAH
*
StoryMapping
Meaning
Meaning
Navigation
Compass
1492 - Columbus sails the ocean blue
Cartographic Renaissance
So geographers, in Afric maps,With savage pictures fill their gaps,And o’er unhabitable downsPlace elephants for want of towns.
- Jonathan Swift
Ortelius Atlas
Exploration
Travel Guides
Driving Guides
GIS
Internet Maps
2005 - Google slips the map
2005 - Google slips the map
GPS becomes ubiquitous
mobile computing
urban renewalparticipatory web
Slippy Maps &
Spinny Globes
Design
Usability
http://maps.google.com/maps?f=q&hl=en&geocode=&q=Cape+Town&ie=UTF8&ll=-33.938803,18.486214&spn=0.182293,0.331306&z=12
Data Coverage and Quality
http://maps.google.com/maps?f=q&hl=en&geocode=&q=Cape+Town&ie=UTF8&ll=-33.938803,18.486214&spn=0.182293,0.331306&z=12
http://openstreetmap.org/?lat=-33.9377&lon=18.4745&zoom=12&layers=B000FTF
Data Coverage and Quality
Brighton, UK
Brighton, UK
Data Ownership and Access
Data Ownership and Access
Technology Limitations
Technology Limitations
Where Next?
http://flickr.com/photos/loupiote/25426957
Storage
id name rating lat lon
10045 Vibe Bar 4.3 52.81 0.295
10046 Half Moon Pub
3.8 53.432 0.312
10047 Windmill 2.6 50.982 0.256
10048 Marquess oAnglesey
1.7 51.023 1.24
10049 Grange Pub
4.5 52.110 0.4562
10050 Coopers Arms
3.5 50.862 0.821
10051 Old Queens Head
3.2 52.591 0.312
10052 Oxo Tower
1.3 51.93 -0.351
10053 Riverside 3.9 52.18 0.62
id name rating lat lon
10045 Vibe Bar 4.3 52.81 0.295
10046 Half Moon Pub
3.8 53.432 0.312
10047 Windmill 2.6 50.982 0.256
10048 Marquess oAnglesey
1.7 51.023 1.24
10049 Grange Pub
4.5 52.110 0.4562
10050 Coopers Arms
3.5 50.862 0.821
10051 Old Queens Head
3.2 52.591 0.312
10052 Oxo Tower
1.3 51.93 -0.351
10053 Riverside 3.9 52.18 0.62
SELECT name,latitude,longitude, acos(SIN( PI()* 40.7383040 /180 )*SIN( PI()*latitude/180 ))+(cos(PI()* 40.7383040 /180)*COS( PI()*latitude/180) *COS(PI()*longitude/180-PI()* -73.99319 /180))* 3963.191 AS distance
FROM allcountries
WHERE 3963.191 * ACOS( (SIN(PI()* 40.7383040 /180)*SIN(PI() * latitude/180)) +(COS(PI()* 40.7383040 /180)*cos(PI()*latitude/180)*COS(PI() * longitude/180-PI()* -73.99319 /180))) < = 1.5
ORDER BY 3963.191 * ACOS((SIN(PI()* 40.7383040 /180)*SIN(PI()*latitude/180)) +(COS(PI()* 40.7383040 /180)*cos(PI()*latitude/180)*COS(PI() * longitude/180-PI()* -73.99319 /180)))
SELECT the_geom FROM geom_table WHERE ST_Distance(the_geom, GeomFromText('POINT(0.02839 51.50807)', -1)) < 100
SELECT the_geom FROM geom_table WHERE the_geom && 'BOX3D(0.02 51,0.03 52)'::box3d ANDST_Distance(the_geom, GeomFromText('POINT(0.02839 51.50807)', -1)) < 100
SpatiaLite
http://www.gaia-gis.it/spatialite/
SQLite + Spatial Types
GeoHash
http://geohash.org/
SELECT nameFROM pubsWHERE geohash LIKE "GCPUV%"
GeoHash
http://geohash.org/
SELECT nameFROM pubsWHERE geohash LIKE "GCPUVR%" OR geohash LIKE "GCPVJ2%"
Data
Wiki for the World
Flickr OSM http://www.flickr.com/map?&fLat=39.9227&fLon=116.4694&zl=6
Sharing
GeoRSS
GeoRSS
GeoRSS
+
GeoRSS
<georss:point>45.256 -71.92
</georss:point>+
GeoRSS
<georss:point>45.256 -71.92
</georss:point>+
GeoRSS
<georss:point>45.256 -71.92
</georss:point>+
RSS / Atom<?xml version="1.0" encoding="UTF-8"?><feed xml:lang="en-US" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="http://grwifi.net/feed" xmlns="http://www.w3.org/2005/Atom"> <title>Grand Rapids WiFi: News, Updated Hotspot Locations, and Comments</title> <id>http://grwifi.net/atom/locations</id> <link href="http://grwifi.net/feed" rel="self" type="application/atom+xml"/> <rights>Creative Commons Attribution-NonCommercial-ShareAlike 2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/ </rights> <updated>2007-03-28T17:31:33+00:00</updated> <entry> <id>http://grwifi.net/location/view/skelletones#comment3862</id> <title>Grand Rapids WiFi: Comment on The Euclid</title> <link href="http://grwifi.net/location/view/skelletones#comment3862" rel="alternate" type="text/html"/> <category term="The Euclid"/> <author><name>mari</name></author> <content type="xhtml"><p>i know a local band in kalamazoo called rising vacancy. i was wondering how …/p></content> <published>2007-03-28T17:31:33+00:00</published> </entry> <entry> <id>http://grwifi.net/location/view/bk-east-paris#comment3855</id> <title>Grand Rapids WiFi: Comment on Burger King - East Paris</title> <link href="http://grwifi.net/location/view/bk-east-paris#comment3855" rel="alternate" type="text/html"/> <category term="Burger King - East Paris"/> <author><name>Brandino</name></author> <content type="xhtml"><p>I love burger king </p></content> <published>2007-03-21T16:38:19+00:00</published> </entry> <entry> <id>http://grwifi.net/location/view/common-ground#comment3843</id> <title>Grand Rapids WiFi: Comment on Common Ground Coffee Shop</title> <link href="http://grwifi.net/location/view/common-ground#comment3843" rel="alternate" type="text/html"/> <category term="Common Ground Coffee Shop"/> <author> <name>Rex Cowan</name> </author> <content type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml"><p>Common Ground is a welcoming place with a warm atmosphere, the clerk I talked to had …</p></content> <published>2007-03-17T01:45:59+00:00</published> </entry></feed>
GeoRSS<?xml version="1.0" encoding="UTF-8"?><feed xml:lang="en-US" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="http://grwifi.net/feed" xmlns:georss="http://www.georss.org/georss" xmlns="http://www.w3.org/2005/Atom"> <title>Grand Rapids WiFi: News, Updated Hotspot Locations, and Comments</title> <id>http://grwifi.net/atom/locations</id> <link href="http://grwifi.net/feed" rel="self" type="application/atom+xml"/> <rights>Creative Commons Attribution-NonCommercial-ShareAlike 2.0 http://creativecommons.org/licenses/by-nc-sa/2.0/ </rights> <updated>2007-03-28T17:31:33+00:00</updated> <entry> <id>http://grwifi.net/location/view/skelletones#comment3862</id> <title>Grand Rapids WiFi: Comment on The Euclid</title> <link href="http://grwifi.net/location/view/skelletones#comment3862" rel="alternate" type="text/html"/> <category term="The Euclid"/> <author><name>mari</name></author> <georss:point>42.960126 -85.667997</georss:point> <content type="xhtml"><p>i know a local band in kalamazoo called rising vacancy. i was wondering how …/p></content> <published>2007-03-28T17:31:33+00:00</published> </entry> <entry> <id>http://grwifi.net/location/view/bk-east-paris#comment3855</id> <title>Grand Rapids WiFi: Comment on Burger King - East Paris</title> <link href="http://grwifi.net/location/view/bk-east-paris#comment3855" rel="alternate" type="text/html"/> <category term="Burger King - East Paris"/> <author><name>Brandino</name></author> <georss:point>42.911495 -85.568665</georss:point> <content type="xhtml"><p>I love burger king </p></content> <published>2007-03-21T16:38:19+00:00</published> </entry> <entry> <id>http://grwifi.net/location/view/common-ground#comment3843</id> <title>Grand Rapids WiFi: Comment on Common Ground Coffee Shop</title> <link href="http://grwifi.net/location/view/common-ground#comment3843" rel="alternate" type="text/html"/> <category term="Common Ground Coffee Shop"/> <author> <name>Rex Cowan</name> </author> <georss:point>42.962927 -85.637179</georss:point> <content type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml"><p>Common Ground is a welcoming place with a warm atmosphere, the clerk I talked to had …</p></content> <published>2007-03-17T01:45:59+00:00</published> </entry></feed>
GeoNames GeoRSS http://www.geonames.org/rss-to-georss-converter.html
KML<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.2"> <Placemark> <name>Simple placemark</name> <description>Attached to the ground. Intelligently places itself at the height of the underlying terrain.</description> <Point> <coordinates>-122.0822035425683,37.42228990140251,0</coordinates> </Point> </Placemark></kml>
KML Extended Data
<ExtendedData id="rooms"> <name>Rooms</name> <value>3</value></ExtendedData>
KML Network Links
</NetworkLink> <NetworkLink> <name><![CDATA[Pubs in London]]></name> <Link> <href>http://maker.geocommons.com/maps/839/overlays/1</href> </Link></NetworkLink>
{ "type": "Point", "coordinates": [100.0, 0.0] }
GeoJSON
GeoJSON { "blog": { "posts": [ { "type": "atom:item", "atom:summary": "post 1", "atom:description": "i love blogging" }, { "type": "atom:item", "atom:summary": "post 2 from CA", "atom:description": "geoblogging in California" "geometry": { "type", "Point", "coordinates": [-120, 40] } }, ], "geometry": { "type": "Polygon", "coordinates": [[[-121, 39], [-119, 39], [-119, 41], [-121, 41], [-121, 39]]] } } }
GeoWeb
Resources
• /places
• /places/89
• /places/89.atom
• /places/89.kml
Web Aligned http://highearthorbit.com/a-proposal-georss-kml
Formats
HTML : RSS
Formats
HTML : RSS ::
Formats
HTML : RSS KML : GeoRSS::
Formats
Visualization : Syndication
HTML : RSS KML : GeoRSS::
Visualization
Mapstraction
Mapstraction API<script src="http://maps.google.com/maps?file=api&v=2&key=YOUR_KEY" type="text/javascript"></script><script type="text/javascript" src="mapstraction.js"></script>
<div id="mapstraction" style="width: 400px; height: 400px;"></div>
<script type="text/javascript">var mapstraction = new Mapstraction('mapstraction','google');
var myPoint = new LatLonPoint(37.4041, -122.0081);mapstraction.setCenterAndZoom(myPoint, 10);
mapstraction.addControls({ pan: true, zoom: 'small', map_type: true });
</script>
Power of the Swap
var mapstraction = new Mapstraction(‘map’, ‘google’);
Power of the Swap
mapstraction.swap(‘mapstraction’, ‘yahoo’);
Power of the Swap
mapstraction.swap(‘mapstraction’, ‘microsoft’);
Power of the Swap
mapstraction.swap(‘mapstraction’, ‘openstreetmap’);
Overlays
mapstraction.addImageOverlay("over","images/santodomingo.png",50,-70.01544, 18.39777, -69.80567, 18.563517);
mapstraction.addImageOverlay("over",file,opacity,west,south,east,north);
Filters
mapstraction.removeAllFilters();mapstraction.addFilter('category', 'eq', 10 );mapstraction.doFilter();
Filters
mapstraction.removeAllFilters();mapstraction.addFilter('category', 'eq', 10 );mapstraction.doFilter();
mapstraction.toggleFilter('category', 'eq', 10 );
Sliders
map = new OpenLayers.Map("map", { maxResolution: 360/512, projection: "EPSG:4326" , numZoomLevels: 20, minZoomLevel: 0, maxZoomLevel: 19, controls: [ new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanPanel(), new OpenLayers.Control.ZoomPanel() ]});var wms = new OpenLayers.Layer.WMS( "world", "/cgi-bin/tilecache/tilecache.cgi?", {layers: 'world'});map.addLayers([wms]);map.setCenter(new OpenLayers.LonLat(0, 32), 7);
map = new OpenLayers.Map("map", { maxResolution: 360/512, projection: "EPSG:4326" , numZoomLevels: 20, minZoomLevel: 0, maxZoomLevel: 19, controls: [ new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanPanel(), new OpenLayers.Control.ZoomPanel() ]});var wms = new OpenLayers.Layer.WMS( "world", "/cgi-bin/tilecache/tilecache.cgi?", {layers: 'world'});map.addLayers([wms]);map.setCenter(new OpenLayers.LonLat(0, 32), 7);
<link rel="stylesheet" href="../themes/gray.css" type="text/css" media="screen" />
<div id="map" class="gray smallmap"></div>
div.gray .olControlZoomPanel { top: 14px; left: 14px;}
div.gray .olControlZoomPanel div { background-image: url(img/gray/gray_zoom_horiz.png); height: 18px; width: 18px;}
div.gray .olControlZoomPanel .olControlZoomInItemInactive { top: 0px; left: 25px; background-position: 18px 0px;}
div.gray .olControlZoomPanel .olControlZoomToMaxExtentItemInactive { top: 0px; left: 0px; background-position: 0px -18px;}
div.gray .olControlZoomPanel .olControlZoomOutItemInactive { top: 0px; left: 0px; background-position: 0px 0px;}
<link rel="stylesheet" href="../themes/gray.css" type="text/css" media="screen" />
<div id="map" class="gray smallmap"></div>
div.gray .olControlZoomPanel { top: 14px; left: 14px;}
div.gray .olControlZoomPanel div { background-image: url(img/gray/gray_zoom_horiz.png); height: 18px; width: 18px;}
div.gray .olControlZoomPanel .olControlZoomInItemInactive { top: 0px; left: 25px; background-position: 18px 0px;}
div.gray .olControlZoomPanel .olControlZoomToMaxExtentItemInactive { top: 0px; left: 0px; background-position: 0px -18px;}
div.gray .olControlZoomPanel .olControlZoomOutItemInactive { top: 0px; left: 0px; background-position: 0px 0px;}
<link rel="stylesheet" href="../themes/gray.css" type="text/css" media="screen" />
<div id="map" class="gray smallmap"></div>
<link rel="stylesheet" href="../themes/hearts.css" type="text/css" media="screen" /><div id="map" class="hearts smallmap"></div>
.hearts .olControlZoomPanel div { background-image: url(img/hearts/hearts-zoom.png);}.hearts .olControlPanPanel div { background-image: url(img/hearts/hearts-panel.png);}
<link rel="stylesheet" href="../themes/hearts.css" type="text/css" media="screen" /><div id="map" class="hearts smallmap"></div>
.hearts .olControlZoomPanel div { background-image: url(img/hearts/hearts-zoom.png);}.hearts .olControlPanPanel div { background-image: url(img/hearts/hearts-panel.png);}
<link rel="stylesheet" href="../themes/hearts.css" type="text/css" media="screen" /><div id="map" class="hearts smallmap"></div>
Accessibility
ModestMaps
package { public class ModestMapsSample extends Sprite { private var map:Map; public function ModestMapsSample() { map = new TweenMap(stage.stageWidth - 2 * PADDING, stage.stageHeight - 2 * PADDING, true, new MicrosoftRoadMapProvider(), new MapExtent(37.829853, 37.700121, -122.212601, -122.514725)); map.addChild(new MapControls(map)); map.addChild(new ZoomSlider(map)); addChild(map); } }}
Analysis
MySociety House Price vs. Travel Time
http://www.mysociety.org/2007/more-travel-maps/
Fuel Efficiency Routing
Bakery Routing
Cartography
NeoCartography
wrp.geothings.net
Mapnik
Mapnik http://mapnik.com
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE Map><Map bgcolor="#b5d0d0" srs="+proj=latlong +datum=WGS84"> <Style name="world"> <Rule> <MaxScaleDenominator>250000000000</MaxScaleDenominator> <MinScaleDenominator>6000000</MinScaleDenominator> <PolygonSymbolizer> <CssParameter name="fill">#f2efe9</CssParameter> </PolygonSymbolizer> <LineSymbolizer> <CssParameter name="stroke">#b5d0d0</CssParameter> <CssParameter name="stroke-width">0.5</CssParameter> </LineSymbolizer> </Rule> </Style> <Layer name="world" status="on" srs="+proj=latlong +datum=WGS84"> <StyleName>world</StyleName> <Datasource> <Parameter name="type">shape</Parameter> <Parameter name="file">/Users/ajturner/Projects/mapnik/world_borders</Parameter> </Datasource> </Layer></Map>
Shenzen Maps
Cascadenick http://code.google.com/p/mapnik-utils/
* { line-width: 1; line-color: #999; polygon-fill: #fff; }
*[zoom>=6][zoom<12] { line-color: #f90;}#world-borders[zoom<10] NAME{ text-fill: #333;}
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE Map><Map bgcolor="#b5d0d0" srs="..."> <Stylesheet> Map { map-bgcolor: #ccc; } </Stylesheet> <Stylesheet src="example.mss"/> <Layer name="world" status="on" srs="..."> <StyleName>world</StyleName> <Datasource> <Parameter name="type">shape</Parameter> <Parameter name="file">...</Parameter> </Datasource> </Layer></Map>
example.mml example.mss
Tiles
Tiles
Tiles
TileCache http://tilecache.org
Image
WMS
Mapnik
Image
CRS
TileCache
TileCache http://tilecache.org
Image
WMS
Mapnik
Image
CRS
TileCacheTMS
900913(google)
Mapstraction Tilesmapstraction.addTileLayer("http://oakland-1950s.s3.amazonaws.com/{Z}-r{Y}-c{X}.jpg", 80);
New Orleans http://maps.thinknola.com
Mobile
Mobline Placemarking
uLocate WHERE
uLocate WHERE
Android Innovations
cab4me
Ambient Location
OmniFocus
UrbanSpoon
PocketMaps
PocketMaps
ruby: http://github.com/ajturner/pocketmapspython: http://aaronland.info/python/pocketMMap
height = 11width = 8.5margin = .25dpi = 144
bbox = (45.482882,-73.619899,45.532687,-73.547801)zoom = 16
out = "montreal_pocketmmap.pdf"
pm = pocketMMap(height, width, margin, dpi)pm.load_provider('OPEN_STREET_MAP')pm.draw(bbox, zoom)pm.save(out)
Geolocation
W3C Geolocation http://dev.w3.org/geo/api/spec-source.html
navigator.geolocation.getCurrentPosition(function(pos) { alert( pos.latitude + ", " + pos.longitude );})
interface Geolocation { readonly attribute Position lastPosition;
void getCurrentPosition(in PositionCallback successCallback);
int watchPosition(in PositionCallback successCallback);
void clearWatch(in int watchId); };
PlundrDS
Crowd Sourced Crisis Information
geotagging pacersM T W Th
geotagging pacersM T W Th1 23 4
geotagging pacersM T W Th1 23 4
geotagging pacersM T W Th1 23 4
geotagging pacersM T W Th1 23 4
BBC Bangladesh Boat Journey
Nonline
AtomPub
Workspace<service xmlns:atom="http://www.w3.org/2005/atom" xmlns="http://www.w3.org/2007/app"> <workspace> <atom:title>Main Site</atom:title> <collection href="http://example.com/maps.atom"> <atom:title>Example Maps</atom:title> <accept>application/vnd.google-earth.kml+xml</accept> <accept>application/atom+xml</accept> </collection> <collection href="http://example.com/places.atom"> <atom:title>Example Places</atom:title> <accept>application/atom+xml</accept> </collection> <collection href="http://example.com/users.atom"> <atom:title>Example Users</atom:title> <accept>application/atom+xml</accept> </collection> </workspace></service>
places.atom
<feed xmlns:georss="http://www.georss.org/georss" xmlns="http://www.w3.org/2005/Atom"> <title>Places</title> <id>http://example.com/places</id> <link type="application/atom+xml" rel="self" href="http://example.com/places.atom"/> <link type="application/vnd.google-earth.kml+xml" rel="alternate" href="http://example.com/places.kml"/> <link type="text/html" rel="alternate" href="http://example.com/places"/> <updated>2008-03-13T21:30:10Z</updated> ...</feed>
Creating a Resourceuser@host:/tmp$ curl -i -X POST \ -H "Authorization: Basic YWRtaW46OGZjOGFkZmM=" \ -H "Content-Type: application/atom+xml;type=entry" \ -H "Slug: 600 N Sherwood" \ -d@test.atom \ http://example.com/places
Creating a Resourceuser@host:/tmp$ curl -i -X POST \ -H "Authorization: Basic YWRtaW46OGZjOGFkZmM=" \ -H "Content-Type: application/atom+xml;type=entry" \ -H "Slug: 600 N Sherwood" \ -d@test.atom \ http://example.com/places
HTTP/1.1 201 CreatedDate: Fri, 14 Mar 2008 04:32:33 GMTServer: Twisted/2.5.0 TwistedWeb/[twisted.web2, version 0.2.0]Content-Length: 744Accept-Ranges: bytesLocation: http://example.com/places/600-n-sherwoodContent-Type: application/atom+xml;type=entry
New Resource<?xml version="1.0" encoding="utf-8"?><entry xmlns="http://www.w3.org/2005/Atom" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<title>Test</title> <link href="http://example.com/places/600-n-sherwood.atom" type="application/atom+xml;type=entry" rel="edit"/> <link href="http://example.com/places/600-n-sherwood" type="text/html" rel="alternate"/> <id>urn:uuid:dfa47428-e9ce-41b4-9f42-c2a3cad9037a</id> <updated>2008-03-14T04:32:33Z</updated> <summary>Testing placemark</summary> <georss:where> <gml:Point> <gml:pos>-105.084251 40.594463</gml:pos> </gml:Point> </georss:where></entry>
Updating a Resourcesean@lenny:/tmp$ curl -i -X PUT \ -H "Authorization: Basic YWRtaW46OGZjOGFkZmM=" \ -H "Content-Type: application/atom+xml;type=entry" \ -d@test-edit.atom \ http://example.com/places/600-n-sherwood.atom
Updating a Resourcesean@lenny:/tmp$ curl -i -X PUT \ -H "Authorization: Basic YWRtaW46OGZjOGFkZmM=" \ -H "Content-Type: application/atom+xml;type=entry" \ -d@test-edit.atom \ http://example.com/places/600-n-sherwood.atom
HTTP/1.1 200 OK
atom
kml
AtomPub
atom
json
client
atom
kml
AtomPub
atom
json
client
resource
atom
kml
AtomPub
atom
json
client
resource
edit
atom
kml
AtomPub
atom
json
client
resource
edit
atom
kml
AtomPub
atom
json
client
resource
edit
atom
kml
AtomPub
atom
json
client
resource
edit
atom
kml
AtomPub
atom
json
clientaggregator
p1
p{1,2,3,4}
p2
p3
p4
atom
kml
AtomPub
atom
json
clientaggregator
p1
p{1,2,3,4}
edit p1
p2
p3
p4
atom
kml
AtomPub
atom
json
clientaggregator
p1
p{1,2,3,4}
edit p1
p2
p3
p4
Public Geodata Repository
Metadata, Statistics, Open Data
GeoData Visualization
Thematic Styling
Classification
Styling
Base Data
Comparative Analysis http://maker.geocommons.com/maps/839
Inspect the Data
Styled KML
We’re Hiring Help build the GeoWeb
GeoWeb
Asante sana!
andrew@highearthorbit.comhighearthorbit.comtwitter.com/ajturner