SlideShare uma empresa Scribd logo
1 de 89
#GEOSHIZZLE
Fronteers 25/04/13 @ KaHo Sint-Lieven
Braintwists of a mapping aficionado
Geoshizzle, braintwists of a mapping aficionado
a·fi·ci·o·na·do
/əˌfiSH(ē)əˈnädō/
Noun
A person who is very
knowledgeable and enthusiastic
about an activity, subject, or pastime.
Aficionado? Iemand die heel wat kennis en heel enthousiast is over een bepaald onderwerp
a·fi·ci·o·na·do
/əˌfiSH(ē)əˈnädō/
Noun
A person who is very
knowledgeable and enthusiastic
about an activity, subject, or pastime.
In mijn geval eerder iemand die zeer enthousiast er over is. Ik heb wel wat kennis over
mapping, maar ken zeker niet alles er over: de scope ervan is echt wel ruim om alles er over
te kunnen weten.
#bootini
Dat ik er heel enthousiast over ben kan je wel merken als je met me samenwerkt. Onlangs
gingen we op bootini met onze studenten 1ICT richting “bachten de kuppe”. Op de planning
stond o.a. een wandeltocht en al snel had ik m’n eigen kaart samengesteld en stond ik met
m’n kompas temidden te velde ...
#scouts
M’n voorliefde is hoogstwschl te wijten aan het feit dat ik in de scouts gezeten heb (en nog
steeds zit) waar we vaak op stap gaan, al dan niet off-road.
GOOGLE MAPS
Mapping has become a commodity
DISCLAIMER: ik ben fan van Google Maps. Dat ding is echt super me dunkt. Velen vloeken er
op, maar ik ben laaiend enthousiast. De voorbeelden/implementaties die ik aanhaal zullen
dan ook op Google Maps gericht zijn.
Google Maps JS API
Waarom ik zo enthousiast er over ben?
1) Het is JavaScript. Sterker nog: het is goede JavaScript: bijna alles wat er op weer te geven
valt heeft event handlers, callback hooks, etc. — Mijn ogen beginnen al te fonkelen als ik zie
waar overal ik wat kan prutsen/tweaken.
2) Je kan er zeer veel mee doen/op weergeven. De meesten kennen het standaard weergeven
van een kaar en het plotten van markers plotten, maar er is meer: lijnen (polyline) tekenen,
shapes (polygons) weergeven, custom overlays op een map plaatsen, custom tiles gebruiken,
etc.
3) Dat ding wordt constant geupdatet, met toffe features. In de eerste versie mocht je er niet
aan denken om te gaan routeren over het wegennet, nu gaat dat automatisch. Sinds kort
zitten bvb. draggable shapes er in, mét
Google Maps APIs
De meesten denken aan de JavaScript Google Maps API wanneer we’t woord in de mond
nemen. Echter bestaat er veel meer dan enkel die JS API. Zo is er bvb. ook een API waarmee je
statische afbeeldingen kan genereren (Static Maps API) en biedt Google enkele diensten aan
waar je berekeningen mee kan laten uitvoeren (Distances API, Geocoding API, etc.) —
Opnieuw: laaiend enthousiast :-)
Google Maps Basics
var map = new google.maps.Map(document.getElementById('map_canvas'), {
	 zoom: 5,
	 center: new google.maps.LatLng(51.061142, 3.708851),
	 mapTypeId: google.maps.MapTypeId.TERRAIN
});
Ik ga er van uit dat iedereen hier wel weet hoe je Google Maps implementeert en hoe je
basiszaken kan doen zoals markers op het ding zetten
Google Maps Basics
var marker = new google.maps.Marker({
	 map: map,
	 position: new google.maps.LatLng(51.061142, 3.708851)
});
google.maps.event.addListener(marker, 'click', toggleBounce);
Ik ga er van uit dat iedereen hier wel weet hoe je Google Maps implementeert en hoe je
basiszaken kan doen zoals markers op het ding zetten
MAP PROJECTIONS
Mercator rickrolled us all!
Een eerste iets wat ik jullie moet vertellen - en iets waar ik echt dolenthousiast over ben -
zijn kaartprojecties. Blijkt ook dat de wereldkaart zoals we ze kennen totaal fout is qua
proporties en zo, allemaal te danken een aan Vlaming Mercator genaamd ...
Map Projection
“A map projection is a way to
represent the curved surface of the
Earth on the flat surface of a map.”
Een kaartprojectie is een manier om onze 3D wereldbol weer te geven op een 2D vlak.
Map Projections
Als je kijkt naar het maken van een wereldbol dan zie je dat die repen om een bol op te
bouwen totaal geen rechthoekige vorm hebben.
Map Projections
Als je al die stukken naast elkaar zou leggen zou je op iets à la het bovenstaande uitkomen.
Om de kaart te verkrijgen zoals we ze nu kennen is er blijkbaar hier en daar aan gesleuteld,
gezien we op rechthoekige stroken uitkomen.
Stom vergelijkbaar voorbeeld: de pel van een appelsien/mandarijn.
Projection Surfaces
“One way of describing a projection is first to
project from the Earth's surface to a developable
surface, and then to unroll the surface into a plane.”
Als je wat onderzoek doet naar kaartprojecties zal je al gauw leren dat er drie courante
projectievlakken zijn die gebruikt worden
Projection Surfaces
Cylinder
Cone
Plane
Een eerste is de cylinder: rol een blad papier rondom de bol, laat de lamp binnenin branden,
teken alles over, knip de cylinder open, en rol ‘m uit — Klaar!
De tweede is een cone/kegel er over zetten: opnieuw opensnijden en je bent er.
Tenslotte is er nog het gewone vlak
Projection Distortions
“Distortion (or warping) is the alteration of the
original shape (or other characteristic) of something.
Distortion is usually unwanted, and often efforts are
to lessen it. In some fields, however, distortion may
be desirable or acceptable.”
In a mapping context:
something = angles | size of an area | distance
Elke projectie op één van de projection surfaces heeft last van vervormingen – Herinner u
daarstraks met die repen die horizontaal uitgestrekt worden: hier en daar zal er wat
uitgerokken moeten worden.
Elk verschillende vervorming duiken op bij kaartprojecties. Afhankelijk van het gebruik van de
kaart kan deze vervorming eventueel getolereerd worden (merk op: je zal eerder en kaart
kiezen op basis van wat het net niet-vervormt).
Binnen de mapping context zijn er drie types van niet-vervormingen die van belang zijn: het
behoud van hoeken, het behoud van verhoudingen tussen objecten, het behoud van
afstanden.
Projection Distortions
Wat we concreet eens gaan doen is bollekes op de aarde zetten en kijken in hoeverre deze
vervormen bij het omzetten naar een 2D beeld. Er zijn 3+1 belangrijke projectietypes dat we
hier bij onderscheiden:
ProjectionTypes (1/2)
Equivalent Projection
preserves proportions in the sizes of areas
Conformal Projection
preserves angle measurements
Een eerste type van projectie is de “conformal projection”. Deze bewaart het meten van
hoeken. Als je in het middelste cirkeltje een hoek van 45° afmeet, dan is dat in die andere
cirkeltjes ook zo. Wat deze projectie echter niet bewaart zijn de proporties/afstanden: je zou
het niet zeggen maar op deze kaart beslaat elke cirkel een even groot aardoppervlak!
Een projectie die wel de proporties/oppervlaktes bewaart is de “equivalent projection”. Hier
zie je wel meteen dat de cirkels geen cirkels blijven: het afmeten van hoeken wordt vervormd:
45° in de top van afrika is al eerder 60° in het midden en 30° in het noorden. Echter klopt de
verhouding tussen de continenten onderling wel. Zie Groenland bvb: in de bovenste projectie
is die bijna even groot zoals Afrika, hier niet.
ProjectionTypes (2/2)
Equidistance Projection
preserves distances
Compromise Projection
preserves none
Een projectie die het meten van afstanden behoudt is een “equidistance projection”: waar je
ook je lat legt, de afstand zal het zelfde zijn. Je ziet wel ook dat de hoeken hier niet meer
dezelfde zijn (cirkels worden ovalen) en dat de verhodoudingen niet bewaard worden (zie
Groenland).
Compromise tenslotte behoudt geen enkele metric, maar probeert ze te minimaliseren om
een vrij realistisch beeld te krijgen.
Projection Implementations
http://xkcd.com/977/
Qua kaartprojecties weten we dus ondertussen dat er verschillende “projectievlakken” zijn, en
een projectie bepaalde eigenschapen (niet-)behoudt.
Er bestaan heel veel kaartprojecties, en elk heeft zijn voor & nadelen. Welke je moet kiezen
hangt af van het gebruik. Waar we echter allemaal blind in volgen is dat Mercator blijkbaar de
standaard geworden is, terwijl de achterliggende reden volledig achterhaald is
Mercator World Map (1569)
Mercator Projection
Een zeer bekende en nog steeds vaak gebruikte kaartprojectie is de Mercator projectie,
gemaakt door Gerardus Mercator (Vlaming) in 1569. Dit is ze hier, z’n eerste wereldkaart.
Mercator was ahead of his time
Mercator Projection = Conformal = Handy if you’re a sailor (which you are, anno 1569)
De map van Mercator werd zeer populair omdat deze “conformal” is. Komt heel goed van pas
wanneer je met een zeilschip op pad gaat (wat men vaak deed toen, naar het schijnt) omdat
je dan gewoonweg één rechte lijn kan trekken om die koers aanhouden om er te geraken.
Andere kaarten van die periode vereisten van een kapitein dat ie steeds z’n koers corrigeerde
en routes moest uitrekenen. Niet echt handig.
Mercator is still popular
http://docs.openlayers.org/library/spherical_mercator.html
SphericalMercator Projection (EPSG:900913)
Google maps, Yahoo Maps, Microsoft Virtual Earth, etc. gebruiken de SphericalMercator
projectie
Mercator is long overdue
Proportions are not preserved
Greenland is not as big as South-America!
Distances are not preserved
Straight line != the shortest route
Het gebruik van Mercator is echter totaal achterhaald. We zitten opgezadeld met een
verouderd systeem dat we niet meer gebruiken: de koers mag dan wel rechtlijnig zijn, de
afstanden en proporties zijn vervormd.
- Ons beeld van Groenland is totaal verkeerd
- Vliegtuigen vliegen hebben meer aan de kortste afstand ipv een rechtlijnige afstand (want:
minder bezine = minder kilos = minder benzine)
Mercator Puzzle
http://gmaps-samples.googlecode.com/svn/trunk/poly/puzzledrag.html
Het laat ons wel toe om een quizje ineen te schieten: hier zie je enkele landen die verschoven
zijn tov hun originele positie. Door de projectie worden ze allen vervormd. Dat grote ding in
het midden van de pagina bvb is Australië.
GEODETIC DATUMS
The earth ain’t flat. But it ain’t round either.
Naast kaartprojecties is het werken met coördinaten/geodetische datums (jawel, datums –
niet data!) een zeer belangrijk aspect binnen de geodesie (=de wetenschap die zich met de
vorm en afmetingen van de aarde bezig houdt).
Spherical Coordinates
φ = latitude (-90° – 90°) | λ = longitude (-180° – 180°)
Om de positie van een punt op een perfecte bol weer te geven heb je twee dingen nodig:
- de hoeken tov twee ortogonaalvlakken, hier aangeduid met X en Phi
- de afstand tov het middelpunt, hier aangduid met R
Probleem is echter dat je dit niet meteen kan toepassen op de aarde.
World Coordinates?
φ = latitude (-90° – 90°) | λ = longitude (-180° – 180°)
Je zou nu kunnen denken: “Aha! Heel simpel, we passen dit gewoon toe op de aarde en
klaar!” – We kennen immers de termen waarschijnlijk al:
- latitude (phi) ofte de hoek tov het equitoriale vlak (-90° tot 90°)
- longitude (lambda) ofte de hoek tov de nulmeridiaan (-180° tot 180°)
Helaas, het blijkt niet zo makkelijk te zijn ...
Enter Stage Left:The Geoid
“The “mathematical figure of the Earth”, a smooth but
highly irregular surface that corresponds not to the actual
surface of the Earth's crust, but to a surface which can
only be known through extensive gravitational
measurements and calculations.”
Er bestaat blijkbaar iets dat de “geoide” genaamd is. Heel speciaal ding maar het heeft te
maken met zwaartekracht, equipotentiaal, getijden, zeeniveau, etc. — Komt er op neer dat
het “het mathematische model van de aarde” is, zoals Gauss (een wiskundige) het ooit
beschreven heeft.
Blijkt het nog eens een ferm lelijk ding te zijn ook, dat zelfs van ver niet eens op een bol
trekt.
Enter Stage Right:
The Reference Ellipsoid
“A mathematically-defined surface that approximates the
geoid, usually a flattened spheroid with two different axes:
An equatorial radius (the semi-major axis a), and a polar
radius (the semi-minor axis b)”
Nu, wiskundigen blijven wiskundigen en hebben er iets op gevonden: Om berekeningen op
de speciale vorm te kunnen toepassen wordt een referentie ellipsoide rondom de geoide
gevormd. Met deze ellipsoide bij de hand kunnen we dan coördinaten gaan uitdrukken.
De ellipsoide heeft twee parameters:
- a = the semi-major axis = equitorial radius
- b = the semi-minor axis = polar raidus
Met deze twee parameters wordt ook nog f (flattening) berekend als zijnde (a-b)/a
World Coordinates
φ = latitude (-90° – 90°) | λ = longitude (-180° – 180°)
Om coordinaten te bereken is deze afgeplatte bol dus de correcte figuur. Bemerk dat de rode
lijn niet meer door het middelpunt gaat ... zie https://twitter.com/breynHouteborg/status/
327520319457853440 & https://twitter.com/breynHouteborg/status/
327526360794947587 (Thanks!)
Mensen binnen de geodesie spreken hier over de geodetische latitude ipv de geocentrische
(die vanuit het midden) latitude.
Global Ellipsoids
WGS84
a = 6378137.0m
b = 6 356 752.314245m
f = 298.257223563
GRS80
a = 6378137.0m
b = 6356752.314140m
f = 298.257222101
http://spatialreference.org/ref/epsg/4326/http://spatialreference.org/ref/sr-org/7311/html/
GRS80 & WGS84 zijn twee internationaal vaak gebruikte ellipsoïden om coordinaten weer te
geven. Ze zijn nagenoeg dezelfde doch wordt WGS84 als dé standaard aanzien: GPS bvb.
gebruikt deze coördinaten
Zeer leuk om weten is dat Google Maps bvb. werkt hier mee: je geeft WGS84 coördinaten mee
aan het systeem en die zal ze zelf omzetten naar SpericalMercator coördinaten (X/Y set
uitgedrukt in meter)
WGS84
Frontdoor KaHo Sint-Lieven
51° 3’ 40.1106” N , 3° 42’ 31.8636”E
Een voorbeeld is de voordeur van de KaHo: φ 51° 3’ 40.1106”, λ 3° 42’ 31.8636”
WGS84 Alternate Notation
Frontdoor KaHo Sint-Lieven
51.061142 N, 3.708851 E
Een voorbeeld is de voordeur van de KaHo: φ 51.061142, λ 3.708851
WGS84 Notation Conversion
// From degrees° minutes’ seconds” to decimal degrees
var degreesToDecimaldegrees = function(degrees, minutes, seconds) {
	 return Math.round((degrees + (minutes/60) + (seconds/3600)) * 1000000) / 1000000;
}
// From decimal degrees to degrees° minutes’ seconds”
var decimalDegreesToDegrees = function(decimaldegrees) {
	 var degrees = Math.floor(decimaldegrees),
	 minutes = Math.floor(((decimaldegrees) - Math.floor(decimaldegrees)) * 60),
	 seconds = (Math.floor(((((decimaldegrees) - Math.floor(decimaldegrees)) * 60)
	 - Math.floor(((decimaldegrees) - Math.floor(decimaldegrees)) * 60))
	 * 100000) * 60 / 100000);
	 return degrees + '° ' + minutes + '' ' + seconds + '"';
}
console.log(degreesToDecimaldegrees(51, 22, 2.100)); // 51.36725
console.log(decimalDegreesToDegrees(51.36725)); // 51° 22' 2.0994"
Hier de JavaScript functies die de twee formaten kan omvormen naar elkaar.
Local Ellipsoids
Voor er satellieten uitgevonden waren was het werken met globale ellipsoïden niet echt
handig. Vele landen hebben daarom een eigen lokale ellipsoïde, en dus een eigen
coordinatensysteem
Belgium: Lambert1972
Lambert1972: http://spatialreference.org/ref/epsg/31370/html/
Lambert2008: http://spatialreference.org/ref/epsg/3812/html/
In België is Lambert1972 onze standaard, gebaseerd op de Hayford1924 ellipsoïde. In 2005
en 2008 volgende er updates om over te stappen op de GRS80 ellipsoïde.
De bijhorende projectie is een conische conformal projectie die beperkt wordt door een
bounding box (twee breedtegraden (“two standard parallel”) + de hoek waaronder op een
bepaalde afstand naar belgie gekeken wordt).
Lambert coordinaten worden uitegedrukt in een X-Y paar.
De waardes van die bounding box verschillen per revisie, let dus op als je een set lambert
coordinaten krijgen: kijk goed of het de versie van 1972, 2005 of 2008 is! Versie 2005 wordt
trouwens niet vaak gebruikt: je zal meestal of de oude (1972) of de nieuwste (2008)
tegenkomen.
Lambert1972
Frontdoor KaHo Sint-Lieven
x: 103848.409429, y: 194699.552339
Converting LB1972 to WGS84
var lambert72toWGS84 = function(x, y) {
	 var newLongitude, newLatitude,
	 	 n = 0.77164219, F = 1.81329763, thetaFudge = 0.00014204, e = 0.08199189,
	 	 a = 6378388, xDiff = 149910, yDiff = 5400150, theta0 = 0.07604294,
	 	 xReal = xDiff - x,
	 	 yReal = yDiff - y,
	 	 rho = Math.sqrt(xReal * xReal + yReal * yReal),
	 	 theta = Math.atan(xReal / -yReal);
	 newLongitude = (theta0 + (theta + thetaFudge) / n) * 180 / Math.PI;
	 newLatitude = 0;
	 for (var i = 0; i < 5 ; ++i) {
	 	 newLatitude = (2 * Math.atan(Math.pow(F * a / rho, 1 / n) * Math.pow((1 + e *
Math.sin(newLatitude)) / (1 - e * Math.sin(newLatitude)), e / 2))) - Math.PI / 2;
	 }
	 newLatitude *= 180 / Math.PI;
	 return [newLatitude, newLongitude];
}
http://jpenet.blogspot.be/2012/08/transformation-between-datums-in.html
http://jpenet.blogspot.be/2012/08/transformation-between-datums-in_14.html
Converting LB1972 to WGS84
If you can’t get enough:
GOOGLE MAPS COORDS &TILES
From Coordinates to Pixels, and vice versa
GoogleTile System
zoom: 2
tiles: 4 x 4
size: 1024px x 1024px
zoom: 1
tiles: 2 x 2
size: 512px x 512px
zoom: 0
tiles: 1 x 1
size: 256px x 256px
De kaart die je op Google maps te zien krijgt is niet één grote afbeelding die je doorgestuurd
wordt. Als je even gaat sniffen via de Network Tab van de Developer Tools dan zal je zien dat
de afbeelding steeds versneden is in tegels van 256 x 256 pixels.
Per zoom level zijn er tegels opgemaakt. Je zal steeds met 2^(n*2) tegels zitten (n =
zoomniveau).
GoogleTile System
0,0
0,0 1,0
0,1 1,1
0,0 1,0
0,1 1,1
2,0 3,0
2,1 3,1
0,2 1,2 2,2 3,2
0,3 1,3 2,3 3,3
De tegels zijn benoemd tov een X-Y as vanuit de top left corner.
Google Maps tenslotte is dusdanig slim om jou enkel maar de tegels die je nodig hebt door te
sturen.
3D → 2D → Pixels
lat : 51.061142
lng : 3.708851
x: 412867.4046906519m
y: 6632116.16820788m
Just feed Google Maps WGS84 (decimal degrees) and it’ll transform them automagically
x: 130.63740515555554
y: 85.63391060773934
z: 1
Qua coördinaten Google Maps gebruikt WGS84 coördinaten. Intern zet ie dat dan om naar de
correcte XY coordinaat om zaken op de map weer te geven.
WGS84 → Pixels
zoom: 2
tiles: 4 x 4
size: 1024px x 1024px
zoom: 1
tiles: 2 x 2
size: 512px x 512px
zoom: 0
tiles: 1 x 1
size: 256px x 256px
Soms zal je effectief zelf willen weten op welke pixel een bepaalde coordinaat staat, dus zal
je moeten gaan rekenen.
Bemerk dat de XY waarde zal afhangen van het zoomlevel:
Op zoomlevel 1 bestaat Google Maps uit 1 tegel, dus zal de X/Y waarde van 1 tot 265px gaan
Op zoomlevel 2 bestaat Google Maps uit 2x2 tegels, dus zal de X/Y waarde van 1 tot 512
gaan
Op zoomlevel 3 ...
WGS84 → Pixels
lat : 51.061142
lng : 3.708851
Just feed Google Maps WGS84 (decimal degrees) and it’ll transform them automagically
x: 130.63740515555554
y: 85.63391060773934
z: 1
Om het effectief om te zetten hoef je niet eerst de WGS84 coord om te zetten naar de
projectie (wat je iets in meters zal opleveren!) en dan naar pixels op het scherm. Je kan dat
meteen doen.
WGS84 → Pixels
The formula will need to take the projection distortions into account
Let op! Je kan dit niet zomaar afmeten! Herinner u dat de Mercator projectie enkel hoeken
respecteert, afstanden tussen punten gemeten met de meetlat zijn niet dezelfde! Ziehier de
cirkels: deze beslaan allen een even groot oppervlak maar zien er niet gelijk uit qua grootte!
WGS84 → Pixels (Standalone)
// Converts a lat/lng coordinate to an XY Point for the given zoom level
function fromLatLngToPixel(lat, lng, zoom) {
	 var deg2rad = Math.PI / 180;
	 var x = Math.floor((lng + 180) / 360 * (1 << zoom) * 256);
	 var y = Math.floor((1 - Math.log(Math.tan(lat * deg2rad) + 1 / Math.cos(lat *
deg2rad)) / Math.PI) / 2 * (1 << zoom) * 256);
	 return [x, y];
}
// Converts an XY Point at the given zoom level to a lat/lng coordinate
var fromPixelToLatLng = function(x, y, zoom) {
// ...
};
console.log(fromLatLngToPixel(51.061142, 3.708851, 0));
// zoom 0: [ x: 130, y: 85 ]
// zoom 1: [ x: 261, y: 171 ]
// zoom 2: [ x: 522, y: 342 ]
Je kan het manueel berekenen, zie hier. Handig voor standalone/serverside implementaties
WGS84 → Pixels
// Converts a lat/lng coordinate to an XY Point for the given zoom level
var latlngToPoint = function(map, latlng){
	 var normalizedPoint = map.getProjection().fromLatLngToPoint(latlng);
	 var scale = Math.pow(2, map.getZoom());
	 var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale,
normalizedPoint.y * scale);
	 return pixelCoordinate;
};
// Converts an XY Point at the given zoom level to a lat/lng coordinate
var pointToLatlng = function(map, point){
	 var scale = Math.pow(2, map.getZoom());
	 var normalizedPoint = new google.maps.Point(point.x / scale, point.y / scale);
	 var latlng = map.getProjection().fromPointToLatLng(normalizedPoint);
	 return latlng;
};
console.log(latlngToPoint(map, new google.maps.LatLng(51.061142, 3.708851)));
// zoom 0: [ x: 130.63740515555554, y: 85.63391060773934 ]
// zoom 1: [ x: 261.2748103111111, y: 171.26782121547868 ]
// zoom 2: [ x: 522.5496206222222, y: 342.53564243095735 ]
Ondertussen voorziet Google ons met versie 3 ons ondertussen van een hulpmiddel
`map.getProjection().fromLatLngToPixel() ` dat het rekenen voor zich neem. Best dit te
gebruiken gezien dit mee met de projectie gaat (op Google Maps kan je van projectie
wisselen – zie https://developers.google.com/maps/documentation/javascript/
maptypes#Projections)
We bereken de positie op zoomlevel 0, en scalen dan mee up met het zoomlevel.
WGS84 → EPSG:900913
// Converts WGS84 coordinates (lat,lng) to EPSG:900913 coordinates (x,y)
var WGS84toSphericalMercator = function(lat, lng) {
var x = lng * 20037508.34 / 180;
var y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
y = y * 20037508.34 / 180;
return [x, y];
}
// Converts EPSG:900913 coordinates (x,y) to WGS84 coordinates (lat,lng)
var SphericalMercatorToWGS84 = function(x, y) {
var lat = (y / 20037508.34) * 180;
var lng = (x / 20037508.34) * 180;
lat = 180/Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI /
2);
return [lat, lng];
}
console.log(WGS84toSphericalMercator(51.061142, 3.708851));
// -> [ x: 412867.4046906519, y: 6632116.16820788 ]
console.log(SphericalMercatorToWGS84(412867.4046906519, 6632116.16820788));
// -> [ lat: 51.06114199999999, lng: 3.708851 ]
Voor zij die toch de SphericalMercator omvormstap ooit zouden nodig hebben, hier is’m.
3D → Pixels →Tile
// Converts an XY Point to a tile index
var pointToTile = function(x, y) {
	 var TILE_SIZE = 256;
	 return [Math.floor(x / TILE_SIZE), Math.floor(y / TILE_SIZE)];
}
console.log(pointToTile(260, 125)); // [ 1, 0 ]
Wat je vervolgens ook nog heel simpel kan doen is te weten komen op welk tegel een
bepaalde XY coordinaat staat. Niet meer dan een simpele math.floor een deling.
Pixeloffset inViewport
Soms zal je willen weten wat de positie van een coordinaat tov de NW corner is.
Pixeloffset inViewport
// Calculates the XY pixel offset of a Coordinate relative to the NW (top left)
corner of the map
var getCanvasPointOffset(latLng) {
	 var scale = Math.pow(2, map.getZoom());
	 var nw = new google.maps.LatLng(
	 map.getBounds().getNorthEast().lat(),
	 map.getBounds().getSouthWest().lng()
	 );
	 var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
	 var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng);
	 var pixelOffset = new google.maps.Point(
	 Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
	 Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
	 );
}
console.log(getCanvasPointOffset(marker.getPosition()));
Daar bestaat uiteraard een formule voor: bereken twee XY paren en retourneer het verschil.
Pixeloffset inViewport
http://bruxellesmdr.be/home
Praktisch voorbeeld: deze overlays bij de markers. Ja, je kan het doen via de muispositie,
maar via de map is net iets geekier.
Let trouwens ook op het gebruik van de minimap op deze site, en het rode kader dat mee
gaat: concreet gezien neem je steeds de bounds (NW en SE corner) van de grote map en stel
je deze in als NW en SE corner van de rechthoek. Bijkomend trigger je dan nog een click event
op de minimap om het kader (en de grote map ook) te herpositioneren.
CUSTOMTILES
It’s JavaScript, so it’s hackable/extendable!
CustomTiles
http://www.use-it.travel/cities/map/ghent/?zoom
Custom Tiles is iets wat je kan gebruiken om eigen maps (of heel grote pano’s) te gaan
serven. De mensen van USE-IT bvb maken tourist guides die ze ook digitaal verspreiden.
On Disk
Format: z_x_y.jpg
Op disk ziet dat er zo uit: per zoom level zijn alle tiles gegenereerd.
Serving CustomTiles
Full code at http://bramus.github.io/photoshop-google-maps-tile-cutter/example/
var customMapType = new google.maps.ImageMapType({
	 getTileUrl: function(coord, zoom) {
	 	 var nCoord = getNormalizedCoord(coord, zoom);
	 	 return 'tiles/' + zoom + '_' + nCoord.x + '_' + nCoord.y + '.jpg';
	 },
	 tileSize: new google.maps.Size(256, 256),
	 maxZoom: maxZoom,
	 name: '...'
});
var map = new google.maps.Map(document.getElementById('map'), {
	 center: new google.maps.LatLng(0, 0), zoom: 2,
	 streetViewControl: false, mapTypeControl: false,
	 mapTypeControlOptions: { mapTypeIds: ["custom"] }
});
map.mapTypes.set('custom', customMapType);
map.setMapTypeId('custom');
Deze kan je dan instellen om getoond te worden ter vervanging van de Google Maps Tiles. De
getTileUrl functie is de cruciale in het verhaal.
CutTiles using aTileCutter
Automatically with https://github.com/bramus/photoshop-google-maps-tile-cutter
Het aanmaken van de tiles gebeurt met een TileCutter. Er bestaan er heel wat, maar ik heb
m’n eigen TileCutter geschreven: een Photoshop Script dat een geopende (grote) afbeelding
zal aflopen en alle mogelijke tiles er van zal trekken.
Dat script is trouwens geschreven in JavaScript: je kan Photoshop aansturen via JS ...
#zottesfeer!
HEATMAPS
Visualizing Data
GowallaHEAT (RIP)
http://gowallaheat.bram.us/
Heatmaps vind ik zelf supercool! Het laat je toe om zeer knappe visualisaties te maken. Hier
ene dat ik ooit gemaakt heb: GowallaHEAT die je Gowalla (RIP) checkins visualiseert.
GowallaHEAT Core (PHP)
Heatmap
Rendering of pixel based canvases
Canvas dimensions passed into constructor
Points are added as X/Y coordinates
MercatorHeatmapTile
Rendering of Mercator based tiles
Canvas is created as a specific tile of a certain zoom level (256px)
Points are added as WGS84 and are converted to X/Y
Only specific tile is rendered
MercatorHeatmap
Rendering of Mercator based canvases
Canvas is created for a given zoom level (256px, 512px, 1024px, ...)
Points are added as WGS84 and are converted to X/Y
Het ding is indertijd gemaakt in PHP en bestaat uit drie basisklasses die van elkaar overerven.
Generating Heatmaps
Heatmaps renderen is echt niet moeilijk eens je’t weet:
- plot per punt een dot die transparant wordt naar de buitenkant toe
- overlap zorgt er voor dat de gebieden donkerder of lichter worden.
- map dan de donkerheidsgraad aan een bepaalde gradient: transparent (of wit) wordt blauw,
lichtgrijs groen, zwart wordt rood (of wit)
Overlaying Heatmaps
// Gowallaheat was implemented with Google Maps v2, so alas no code to show ...
// System is comparable to working with custom tiles though:
// Store the tiles as `z_x_y.png` on the server and load ‘m in
Om de transparante overlays nu te renderen op een Google Maps heb je heel wat JS nodig.
Helaas dateert de implementatie van in de tijd van GMaps2 en is de code niet meer up-to-
date.
Principe is wel het zelfde als bij het werken met custom tiles: tiles worden genummerd &
ingeladen via een custom functie.
Heatmaps in Google Maps v3
var pointArray = new google.maps.MVCArray([
	 new google.maps.LatLng(37.782551, -122.445368),
	 ...
	 new google.maps.LatLng(37.783206, -122.440829)
]);
var heatmap = new google.maps.visualization.HeatmapLayer({
	 data: pointArray
});
heatmap.setMap(map);
https://developers.google.com/maps/documentation/javascript/examples/layer-heatmap
Nu, de code van toen heb je niet nodig, gezien het nu vanzelf in Google Maps v3 zit – hoera!
SHAPEFILES & GEOJSON
The vectors of the mapping business
Shapefile
“A shapefile is a digital vector storage format
for storing geometric location and associated
attribute information.”
Shapefiles zijn de svg’s van de mapping business. Je kan deze bekijken met een shapefile
viewer.
Rendering Shapefiles
https://github.com/kig/shp.js/
Shapefiles kan je niet renderen op Google Maps helaas, maar wel bvb. met D3.js en een
shp.js plugin.
Met KartoGraph kan je ook aan de slag.
Shapefiles Oost-Vlaanderen
http://www.gisoost.be/home/atlasbw.php?kies=alle_gemeenten
Vele van de gis diensten in België bieden shapefiles aan, maar je moet ze wel weten te
vinden ;-)
Let op, je zal ook moeten filteren — er zit heel veel cruft tussen
GeoJSON
“GeoJSON allows geographic data to be
stored in a human-readable way”
{
"type": "Feature",
"id": "OpenLayers.Feature.Vector_314",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
97.03125,
39.7265625
]
}
}
Naast shapefiles heb je ook GeoJSON. Voor ons iets handiger om mee te werken want da’s
tekst die we kunnen lezen.
In die GeoJSON kan je alles opslaan: Markers (punten), PolyLines (lijnen), PolyGons (vormen),
etc. — echt wel vet!
GeoJSON
https://github.com/JasonSanford/GeoJSON-to-Google-Maps
Het gebruik van GeoJSON binnen Google Maps is simpel, mits een hulpmiddel.
Mercator Puzzle Redux
http://bramus.github.io/mercator-puzzle-redux/
Herinner u de Mercator puzzel? Heb die wat aangepast zodat je niet steeds dezelfde 15
landen krijgt.
De landen dat is uit een GeoJSON file gehaald.
Bijkomend is er nog wat geprutst om de shapes programmatorisch te verplaatsen: van elk
land wordt het middelpunt van de shape genomen en per punt van de shape wordt vanuit het
middelpunt de richting en de afstand genoteerd. Vervolgens wordt de shape op een andere
plaats (waar de afstanden anders zijn, maar de hoeken de zelfde) hertekend als zijnde: teken
mij nu eens alle punten op een bepaalde afstand en richting vanaf het nieuwe middelpunt.
http://www.bram.us/2013/02/16/google-maps-v3-move-polygon/
Mercator Puzzle Redux Sidenote
Herinner u de Mercator puzzel? Heb die wat aangepast zodat je niet steeds dezelfde 15
landen krijgt.
De landen dat is uit een GeoJSON file gehaald.
Bijkomend is er nog wat geprutst om de shapes programmatorisch te verplaatsen: van elk
land wordt het middelpunt van de shape genomen en per punt van de shape wordt vanuit het
middelpunt de richting en de afstand genoteerd. Vervolgens wordt de shape op een andere
plaats (waar de afstanden anders zijn, maar de hoeken de zelfde) hertekend als zijnde: teken
mij nu eens alle punten op een bepaalde afstand en richting vanaf het nieuwe middelpunt.
Shapefile → GeoJSON
http://www.bram.us/2012/03/14/convert-esri-shapefile-shp-to-geojson-json/
$ /Library/Frameworks/GDAL.framework/Programs/ogr2ogr -f "GeoJSON"
output.json input.shp
$ /Library/Frameworks/GDAL.framework/Programs/ogr2ogr -f "GeoJSON"
-s_srs "EPSG:31370" -t_srs "WGS84" output.json input.shp
Shapefile to GeoJSON
Shapefile to GeoJSON with coordinates conversion
http://spatialreference.org/
Shapefiles kan je naar GeoJSON omzetten.
Let op met de shapefiles van GisOOST: deze zijn in Lambert1972 en zal je dus naar WGS84
moeten omzetten. Gelukkig kan die ogr2ogr daar mee overweg. Wat je wel zal moeten te
weten komen is de EPSG code. Die kan je vinden op http://spatialreference.org/
Shapefile Deelgemeenten Deinze
Hier een voorbeeld van de deelgemeenten van Deinze: Shapefile van Gisoost, omgezet met
ogr2ogr naar WGS84 coordinaten, ingeladen in Google Maps met behulp van de GeoJSON
plugin.
En het blijkt nog te kloppen ook. Indien het niet klopt: coordinatenconversie nakijken!
Shapefile → SVG → Browser
http://kartograph.org/
Met Kartograph kan je een shapefile omzetten naar een SVG (met een bepaalde projectie) en
deze dan via javascript embedden, stylen, en zelfs interactief maken.
Bestaat uit een python script om een SVG te creëren, en een JS lib om de SVG vervolgens te
embedden.
A FEW MORETHINGS
Various stuff
Ferraris Maps (1777)
http://www.kbr.be/collections/cart_plan/ferraris/ferraris_nl.html
De Ferraris kaarten zijn echt prachtig en hi-res. Hier Gent bvb. Enige jammere is dat die site
niet echt wow is, en de viewer in Flash is.
Styled Maps
https://developers.google.com/maps/documentation/javascript/styling
http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html
Google Maps kan je perfect stylen naar hetgeen je wil. Per entitiet (straten, labels, landmassa,
water, etc) kan je instellen of het zichtbaar moet zijn of niet, wat het kleur is, etc.
Resultaat uit deze hulptool is JSON die je dan mee aan de config van je map instance geeft.
Distance Between Points
// Manual: Haversine Formula: shortest route over a sphere
function distance(latlng1, latlng2) {
var R = 6371, // Radius of the earth, in km. Need miles? change to 3961
dLat = (latlng2.lat - latlng1.lat) * (Math.PI / 180),
dLon = (latlng2.lng - latlng1.lng) * (Math.PI / 180),
a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(latlng1.lat * (Math.PI / 180)) *
Math.cos(latlng2.lat * (Math.PI / 180)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2),
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)),
d = R * c;
	 return d;
}
// Google Maps v3 with Geometry Library
// @see https://developers.google.com/maps/documentation/javascript/geometry
google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
De kortste afstand op een mercator projectie is geen rechte lijn. Gebruik hiervoor de
haversine formule, die rekening houdt met de straal van de aarde.
Bearing/Heading
// Manual calculation of the bearing
var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) -
Math.sin(lat1)*Math.cos(lat2) * Math.cos(dLon);
var brng = Math.atan2(y, x).toDeg(
// Google Maps v3 with Geometry Library
// @see https://developers.google.com/maps/documentation/javascript/geometry
google.maps.geometry.spherical.computeHeading (latLngA, latLngB);
Je kan ook de richting naar een bepaald punt (vanuit een ander punt) gaan bepalen.
Is dus iets wat gebruikt werd bij die Mercator Puzzle Redux van daarstraks
Areal Photos of Belgium
http://ogc.beta.agiv.be/gdiviewer/
Luchtfoto’s van België (veel beter dan die van Google of Bing) vind je op Agiv. Dataset werd
onlangs vernieuwd.
Topograhpic Maps of Belgium
http://www.ngi.be/topomapviewer/public?lang=nl&
Stafkaarten en zo staat dan weer op ngi.be.
Marker Clustering
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/examples.html
Voor het weergeven van heel wat markers is een markerclusterer handig. Voor gebruik in
Google Maps bestaat er een inplooibare plugin.
Marker Clustering (PHP)
http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google-maps
Voor zij die in PHP markers willen clusteren ... je zal wel enkele formules herkennen :-)
Want Moar?
GIS
D3
LeafLet
TileServer
OpenStreetMap
OpenLayers
MapBox
TileMill
MrSID
Geospatial SQL
#GEOSHIZZLE
Fronteers 25/04/13 @ KaHo Sint-Lieven
Braintwists of a mapping aficionado
SOURCES
• http://www.nationalgeographic.com/features/2000/exploration/projections/
• http://kartoweb.itc.nl/geometrics/map%20projections/mappro.html
• http://www.1worldglobes.com/images/columbus_globes/globe_gores_assembly_lg.jpg
• http://www.genekeyes.com/CAHILL-1909/fig.1-2-55.jpg
• http://www-personal.umich.edu/~sarhaus/UnivChicago/tigdd27proj.html
• http://earth.rice.edu/mtpe/geo/geosphere/topics/mapprojections.html
• https://en.wikipedia.org/wiki/Map_projection
• http://en.wikipedia.org/wiki/Distortion
• https://www.e-education.psu.edu/natureofgeoinfo/c2_p29.html
• http://upload.wikimedia.org/wikipedia/commons/8/88/Gerardus_Mercator.jpg
• https://en.wikipedia.org/wiki/Tissot%27s_indicatrix
• http://en.wikipedia.org/wiki/Mercator_1569_world_map
• http://en.wikipedia.org/wiki/Mercator_projection
• http://www.free-online-private-pilot-ground-school.com/navigation-basics.html
• http://en.wikipedia.org/wiki/Datum_(geodesy)
• http://en.wikipedia.org/wiki/World_Geodetic_System
• http://en.wikipedia.org/wiki/Latitude
• http://spatialreference.org/ref/epsg/4326/
• http://spatialreference.org/ref/epsg/31300/
• http://spatialreference.org/ref/epsg/31370/
• http://nl.scoutwiki.org/Lambert_(Belgi%C3%AB)
• http://www.ngi.be/NL/NL2-1-7.shtm
• http://www.mathworks.com/help/symbolic/mupad_ug/spherical-coordinates.png
• http://www.colorado.edu/geography/gcraft/notes/datum/datum.html
• http://kartoweb.itc.nl/geometrics/Coordinate%20transformations/coordtrans.html
• http://www.ngi.be/Common/Lambert2008/Schema_Lambert_1972_2008_nl.pdf
• https://google-developers.appspot.com/maps/documentation/javascript/examples/map-
coordinates
• http://qfox.nl/notes/116
• http://stackoverflow.com/questions/2674392/how-to-access-google-maps-api-v3-markers-
div-and-its-pixel-position
• http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
• http://transition.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html
• http://www.movable-type.co.uk/scripts/latlong.html
• https://developers.google.com/maps/documentation/javascript/examples/layer-heatmap
• http://en.wikipedia.org/wiki/GeoJSON
•

Mais conteúdo relacionado

Destaque

AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 

Destaque (20)

AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 

#geoshizzle (with notes)

  • 1. #GEOSHIZZLE Fronteers 25/04/13 @ KaHo Sint-Lieven Braintwists of a mapping aficionado Geoshizzle, braintwists of a mapping aficionado
  • 2. a·fi·ci·o·na·do /əˌfiSH(ē)əˈnädō/ Noun A person who is very knowledgeable and enthusiastic about an activity, subject, or pastime. Aficionado? Iemand die heel wat kennis en heel enthousiast is over een bepaald onderwerp
  • 3. a·fi·ci·o·na·do /əˌfiSH(ē)əˈnädō/ Noun A person who is very knowledgeable and enthusiastic about an activity, subject, or pastime. In mijn geval eerder iemand die zeer enthousiast er over is. Ik heb wel wat kennis over mapping, maar ken zeker niet alles er over: de scope ervan is echt wel ruim om alles er over te kunnen weten.
  • 4. #bootini Dat ik er heel enthousiast over ben kan je wel merken als je met me samenwerkt. Onlangs gingen we op bootini met onze studenten 1ICT richting “bachten de kuppe”. Op de planning stond o.a. een wandeltocht en al snel had ik m’n eigen kaart samengesteld en stond ik met m’n kompas temidden te velde ...
  • 5. #scouts M’n voorliefde is hoogstwschl te wijten aan het feit dat ik in de scouts gezeten heb (en nog steeds zit) waar we vaak op stap gaan, al dan niet off-road.
  • 6. GOOGLE MAPS Mapping has become a commodity DISCLAIMER: ik ben fan van Google Maps. Dat ding is echt super me dunkt. Velen vloeken er op, maar ik ben laaiend enthousiast. De voorbeelden/implementaties die ik aanhaal zullen dan ook op Google Maps gericht zijn.
  • 7. Google Maps JS API Waarom ik zo enthousiast er over ben? 1) Het is JavaScript. Sterker nog: het is goede JavaScript: bijna alles wat er op weer te geven valt heeft event handlers, callback hooks, etc. — Mijn ogen beginnen al te fonkelen als ik zie waar overal ik wat kan prutsen/tweaken. 2) Je kan er zeer veel mee doen/op weergeven. De meesten kennen het standaard weergeven van een kaar en het plotten van markers plotten, maar er is meer: lijnen (polyline) tekenen, shapes (polygons) weergeven, custom overlays op een map plaatsen, custom tiles gebruiken, etc. 3) Dat ding wordt constant geupdatet, met toffe features. In de eerste versie mocht je er niet aan denken om te gaan routeren over het wegennet, nu gaat dat automatisch. Sinds kort zitten bvb. draggable shapes er in, mét
  • 8. Google Maps APIs De meesten denken aan de JavaScript Google Maps API wanneer we’t woord in de mond nemen. Echter bestaat er veel meer dan enkel die JS API. Zo is er bvb. ook een API waarmee je statische afbeeldingen kan genereren (Static Maps API) en biedt Google enkele diensten aan waar je berekeningen mee kan laten uitvoeren (Distances API, Geocoding API, etc.) — Opnieuw: laaiend enthousiast :-)
  • 9. Google Maps Basics var map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: 5, center: new google.maps.LatLng(51.061142, 3.708851), mapTypeId: google.maps.MapTypeId.TERRAIN }); Ik ga er van uit dat iedereen hier wel weet hoe je Google Maps implementeert en hoe je basiszaken kan doen zoals markers op het ding zetten
  • 10. Google Maps Basics var marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(51.061142, 3.708851) }); google.maps.event.addListener(marker, 'click', toggleBounce); Ik ga er van uit dat iedereen hier wel weet hoe je Google Maps implementeert en hoe je basiszaken kan doen zoals markers op het ding zetten
  • 11. MAP PROJECTIONS Mercator rickrolled us all! Een eerste iets wat ik jullie moet vertellen - en iets waar ik echt dolenthousiast over ben - zijn kaartprojecties. Blijkt ook dat de wereldkaart zoals we ze kennen totaal fout is qua proporties en zo, allemaal te danken een aan Vlaming Mercator genaamd ...
  • 12. Map Projection “A map projection is a way to represent the curved surface of the Earth on the flat surface of a map.” Een kaartprojectie is een manier om onze 3D wereldbol weer te geven op een 2D vlak.
  • 13. Map Projections Als je kijkt naar het maken van een wereldbol dan zie je dat die repen om een bol op te bouwen totaal geen rechthoekige vorm hebben.
  • 14. Map Projections Als je al die stukken naast elkaar zou leggen zou je op iets à la het bovenstaande uitkomen. Om de kaart te verkrijgen zoals we ze nu kennen is er blijkbaar hier en daar aan gesleuteld, gezien we op rechthoekige stroken uitkomen. Stom vergelijkbaar voorbeeld: de pel van een appelsien/mandarijn.
  • 15. Projection Surfaces “One way of describing a projection is first to project from the Earth's surface to a developable surface, and then to unroll the surface into a plane.” Als je wat onderzoek doet naar kaartprojecties zal je al gauw leren dat er drie courante projectievlakken zijn die gebruikt worden
  • 16. Projection Surfaces Cylinder Cone Plane Een eerste is de cylinder: rol een blad papier rondom de bol, laat de lamp binnenin branden, teken alles over, knip de cylinder open, en rol ‘m uit — Klaar! De tweede is een cone/kegel er over zetten: opnieuw opensnijden en je bent er. Tenslotte is er nog het gewone vlak
  • 17. Projection Distortions “Distortion (or warping) is the alteration of the original shape (or other characteristic) of something. Distortion is usually unwanted, and often efforts are to lessen it. In some fields, however, distortion may be desirable or acceptable.” In a mapping context: something = angles | size of an area | distance Elke projectie op één van de projection surfaces heeft last van vervormingen – Herinner u daarstraks met die repen die horizontaal uitgestrekt worden: hier en daar zal er wat uitgerokken moeten worden. Elk verschillende vervorming duiken op bij kaartprojecties. Afhankelijk van het gebruik van de kaart kan deze vervorming eventueel getolereerd worden (merk op: je zal eerder en kaart kiezen op basis van wat het net niet-vervormt). Binnen de mapping context zijn er drie types van niet-vervormingen die van belang zijn: het behoud van hoeken, het behoud van verhoudingen tussen objecten, het behoud van afstanden.
  • 18. Projection Distortions Wat we concreet eens gaan doen is bollekes op de aarde zetten en kijken in hoeverre deze vervormen bij het omzetten naar een 2D beeld. Er zijn 3+1 belangrijke projectietypes dat we hier bij onderscheiden:
  • 19. ProjectionTypes (1/2) Equivalent Projection preserves proportions in the sizes of areas Conformal Projection preserves angle measurements Een eerste type van projectie is de “conformal projection”. Deze bewaart het meten van hoeken. Als je in het middelste cirkeltje een hoek van 45° afmeet, dan is dat in die andere cirkeltjes ook zo. Wat deze projectie echter niet bewaart zijn de proporties/afstanden: je zou het niet zeggen maar op deze kaart beslaat elke cirkel een even groot aardoppervlak! Een projectie die wel de proporties/oppervlaktes bewaart is de “equivalent projection”. Hier zie je wel meteen dat de cirkels geen cirkels blijven: het afmeten van hoeken wordt vervormd: 45° in de top van afrika is al eerder 60° in het midden en 30° in het noorden. Echter klopt de verhouding tussen de continenten onderling wel. Zie Groenland bvb: in de bovenste projectie is die bijna even groot zoals Afrika, hier niet.
  • 20. ProjectionTypes (2/2) Equidistance Projection preserves distances Compromise Projection preserves none Een projectie die het meten van afstanden behoudt is een “equidistance projection”: waar je ook je lat legt, de afstand zal het zelfde zijn. Je ziet wel ook dat de hoeken hier niet meer dezelfde zijn (cirkels worden ovalen) en dat de verhodoudingen niet bewaard worden (zie Groenland). Compromise tenslotte behoudt geen enkele metric, maar probeert ze te minimaliseren om een vrij realistisch beeld te krijgen.
  • 21. Projection Implementations http://xkcd.com/977/ Qua kaartprojecties weten we dus ondertussen dat er verschillende “projectievlakken” zijn, en een projectie bepaalde eigenschapen (niet-)behoudt. Er bestaan heel veel kaartprojecties, en elk heeft zijn voor & nadelen. Welke je moet kiezen hangt af van het gebruik. Waar we echter allemaal blind in volgen is dat Mercator blijkbaar de standaard geworden is, terwijl de achterliggende reden volledig achterhaald is
  • 22. Mercator World Map (1569) Mercator Projection Een zeer bekende en nog steeds vaak gebruikte kaartprojectie is de Mercator projectie, gemaakt door Gerardus Mercator (Vlaming) in 1569. Dit is ze hier, z’n eerste wereldkaart.
  • 23. Mercator was ahead of his time Mercator Projection = Conformal = Handy if you’re a sailor (which you are, anno 1569) De map van Mercator werd zeer populair omdat deze “conformal” is. Komt heel goed van pas wanneer je met een zeilschip op pad gaat (wat men vaak deed toen, naar het schijnt) omdat je dan gewoonweg één rechte lijn kan trekken om die koers aanhouden om er te geraken. Andere kaarten van die periode vereisten van een kapitein dat ie steeds z’n koers corrigeerde en routes moest uitrekenen. Niet echt handig.
  • 24. Mercator is still popular http://docs.openlayers.org/library/spherical_mercator.html SphericalMercator Projection (EPSG:900913) Google maps, Yahoo Maps, Microsoft Virtual Earth, etc. gebruiken de SphericalMercator projectie
  • 25. Mercator is long overdue Proportions are not preserved Greenland is not as big as South-America! Distances are not preserved Straight line != the shortest route Het gebruik van Mercator is echter totaal achterhaald. We zitten opgezadeld met een verouderd systeem dat we niet meer gebruiken: de koers mag dan wel rechtlijnig zijn, de afstanden en proporties zijn vervormd. - Ons beeld van Groenland is totaal verkeerd - Vliegtuigen vliegen hebben meer aan de kortste afstand ipv een rechtlijnige afstand (want: minder bezine = minder kilos = minder benzine)
  • 26. Mercator Puzzle http://gmaps-samples.googlecode.com/svn/trunk/poly/puzzledrag.html Het laat ons wel toe om een quizje ineen te schieten: hier zie je enkele landen die verschoven zijn tov hun originele positie. Door de projectie worden ze allen vervormd. Dat grote ding in het midden van de pagina bvb is Australië.
  • 27. GEODETIC DATUMS The earth ain’t flat. But it ain’t round either. Naast kaartprojecties is het werken met coördinaten/geodetische datums (jawel, datums – niet data!) een zeer belangrijk aspect binnen de geodesie (=de wetenschap die zich met de vorm en afmetingen van de aarde bezig houdt).
  • 28. Spherical Coordinates φ = latitude (-90° – 90°) | λ = longitude (-180° – 180°) Om de positie van een punt op een perfecte bol weer te geven heb je twee dingen nodig: - de hoeken tov twee ortogonaalvlakken, hier aangeduid met X en Phi - de afstand tov het middelpunt, hier aangduid met R Probleem is echter dat je dit niet meteen kan toepassen op de aarde.
  • 29. World Coordinates? φ = latitude (-90° – 90°) | λ = longitude (-180° – 180°) Je zou nu kunnen denken: “Aha! Heel simpel, we passen dit gewoon toe op de aarde en klaar!” – We kennen immers de termen waarschijnlijk al: - latitude (phi) ofte de hoek tov het equitoriale vlak (-90° tot 90°) - longitude (lambda) ofte de hoek tov de nulmeridiaan (-180° tot 180°) Helaas, het blijkt niet zo makkelijk te zijn ...
  • 30. Enter Stage Left:The Geoid “The “mathematical figure of the Earth”, a smooth but highly irregular surface that corresponds not to the actual surface of the Earth's crust, but to a surface which can only be known through extensive gravitational measurements and calculations.” Er bestaat blijkbaar iets dat de “geoide” genaamd is. Heel speciaal ding maar het heeft te maken met zwaartekracht, equipotentiaal, getijden, zeeniveau, etc. — Komt er op neer dat het “het mathematische model van de aarde” is, zoals Gauss (een wiskundige) het ooit beschreven heeft. Blijkt het nog eens een ferm lelijk ding te zijn ook, dat zelfs van ver niet eens op een bol trekt.
  • 31. Enter Stage Right: The Reference Ellipsoid “A mathematically-defined surface that approximates the geoid, usually a flattened spheroid with two different axes: An equatorial radius (the semi-major axis a), and a polar radius (the semi-minor axis b)” Nu, wiskundigen blijven wiskundigen en hebben er iets op gevonden: Om berekeningen op de speciale vorm te kunnen toepassen wordt een referentie ellipsoide rondom de geoide gevormd. Met deze ellipsoide bij de hand kunnen we dan coördinaten gaan uitdrukken. De ellipsoide heeft twee parameters: - a = the semi-major axis = equitorial radius - b = the semi-minor axis = polar raidus Met deze twee parameters wordt ook nog f (flattening) berekend als zijnde (a-b)/a
  • 32. World Coordinates φ = latitude (-90° – 90°) | λ = longitude (-180° – 180°) Om coordinaten te bereken is deze afgeplatte bol dus de correcte figuur. Bemerk dat de rode lijn niet meer door het middelpunt gaat ... zie https://twitter.com/breynHouteborg/status/ 327520319457853440 & https://twitter.com/breynHouteborg/status/ 327526360794947587 (Thanks!) Mensen binnen de geodesie spreken hier over de geodetische latitude ipv de geocentrische (die vanuit het midden) latitude.
  • 33. Global Ellipsoids WGS84 a = 6378137.0m b = 6 356 752.314245m f = 298.257223563 GRS80 a = 6378137.0m b = 6356752.314140m f = 298.257222101 http://spatialreference.org/ref/epsg/4326/http://spatialreference.org/ref/sr-org/7311/html/ GRS80 & WGS84 zijn twee internationaal vaak gebruikte ellipsoïden om coordinaten weer te geven. Ze zijn nagenoeg dezelfde doch wordt WGS84 als dé standaard aanzien: GPS bvb. gebruikt deze coördinaten Zeer leuk om weten is dat Google Maps bvb. werkt hier mee: je geeft WGS84 coördinaten mee aan het systeem en die zal ze zelf omzetten naar SpericalMercator coördinaten (X/Y set uitgedrukt in meter)
  • 34. WGS84 Frontdoor KaHo Sint-Lieven 51° 3’ 40.1106” N , 3° 42’ 31.8636”E Een voorbeeld is de voordeur van de KaHo: φ 51° 3’ 40.1106”, λ 3° 42’ 31.8636”
  • 35. WGS84 Alternate Notation Frontdoor KaHo Sint-Lieven 51.061142 N, 3.708851 E Een voorbeeld is de voordeur van de KaHo: φ 51.061142, λ 3.708851
  • 36. WGS84 Notation Conversion // From degrees° minutes’ seconds” to decimal degrees var degreesToDecimaldegrees = function(degrees, minutes, seconds) { return Math.round((degrees + (minutes/60) + (seconds/3600)) * 1000000) / 1000000; } // From decimal degrees to degrees° minutes’ seconds” var decimalDegreesToDegrees = function(decimaldegrees) { var degrees = Math.floor(decimaldegrees), minutes = Math.floor(((decimaldegrees) - Math.floor(decimaldegrees)) * 60), seconds = (Math.floor(((((decimaldegrees) - Math.floor(decimaldegrees)) * 60) - Math.floor(((decimaldegrees) - Math.floor(decimaldegrees)) * 60)) * 100000) * 60 / 100000); return degrees + '° ' + minutes + '' ' + seconds + '"'; } console.log(degreesToDecimaldegrees(51, 22, 2.100)); // 51.36725 console.log(decimalDegreesToDegrees(51.36725)); // 51° 22' 2.0994" Hier de JavaScript functies die de twee formaten kan omvormen naar elkaar.
  • 37. Local Ellipsoids Voor er satellieten uitgevonden waren was het werken met globale ellipsoïden niet echt handig. Vele landen hebben daarom een eigen lokale ellipsoïde, en dus een eigen coordinatensysteem
  • 38. Belgium: Lambert1972 Lambert1972: http://spatialreference.org/ref/epsg/31370/html/ Lambert2008: http://spatialreference.org/ref/epsg/3812/html/ In België is Lambert1972 onze standaard, gebaseerd op de Hayford1924 ellipsoïde. In 2005 en 2008 volgende er updates om over te stappen op de GRS80 ellipsoïde. De bijhorende projectie is een conische conformal projectie die beperkt wordt door een bounding box (twee breedtegraden (“two standard parallel”) + de hoek waaronder op een bepaalde afstand naar belgie gekeken wordt). Lambert coordinaten worden uitegedrukt in een X-Y paar. De waardes van die bounding box verschillen per revisie, let dus op als je een set lambert coordinaten krijgen: kijk goed of het de versie van 1972, 2005 of 2008 is! Versie 2005 wordt trouwens niet vaak gebruikt: je zal meestal of de oude (1972) of de nieuwste (2008) tegenkomen.
  • 39. Lambert1972 Frontdoor KaHo Sint-Lieven x: 103848.409429, y: 194699.552339
  • 40. Converting LB1972 to WGS84 var lambert72toWGS84 = function(x, y) { var newLongitude, newLatitude, n = 0.77164219, F = 1.81329763, thetaFudge = 0.00014204, e = 0.08199189, a = 6378388, xDiff = 149910, yDiff = 5400150, theta0 = 0.07604294, xReal = xDiff - x, yReal = yDiff - y, rho = Math.sqrt(xReal * xReal + yReal * yReal), theta = Math.atan(xReal / -yReal); newLongitude = (theta0 + (theta + thetaFudge) / n) * 180 / Math.PI; newLatitude = 0; for (var i = 0; i < 5 ; ++i) { newLatitude = (2 * Math.atan(Math.pow(F * a / rho, 1 / n) * Math.pow((1 + e * Math.sin(newLatitude)) / (1 - e * Math.sin(newLatitude)), e / 2))) - Math.PI / 2; } newLatitude *= 180 / Math.PI; return [newLatitude, newLongitude]; }
  • 42. GOOGLE MAPS COORDS &TILES From Coordinates to Pixels, and vice versa
  • 43. GoogleTile System zoom: 2 tiles: 4 x 4 size: 1024px x 1024px zoom: 1 tiles: 2 x 2 size: 512px x 512px zoom: 0 tiles: 1 x 1 size: 256px x 256px De kaart die je op Google maps te zien krijgt is niet één grote afbeelding die je doorgestuurd wordt. Als je even gaat sniffen via de Network Tab van de Developer Tools dan zal je zien dat de afbeelding steeds versneden is in tegels van 256 x 256 pixels. Per zoom level zijn er tegels opgemaakt. Je zal steeds met 2^(n*2) tegels zitten (n = zoomniveau).
  • 44. GoogleTile System 0,0 0,0 1,0 0,1 1,1 0,0 1,0 0,1 1,1 2,0 3,0 2,1 3,1 0,2 1,2 2,2 3,2 0,3 1,3 2,3 3,3 De tegels zijn benoemd tov een X-Y as vanuit de top left corner. Google Maps tenslotte is dusdanig slim om jou enkel maar de tegels die je nodig hebt door te sturen.
  • 45. 3D → 2D → Pixels lat : 51.061142 lng : 3.708851 x: 412867.4046906519m y: 6632116.16820788m Just feed Google Maps WGS84 (decimal degrees) and it’ll transform them automagically x: 130.63740515555554 y: 85.63391060773934 z: 1 Qua coördinaten Google Maps gebruikt WGS84 coördinaten. Intern zet ie dat dan om naar de correcte XY coordinaat om zaken op de map weer te geven.
  • 46. WGS84 → Pixels zoom: 2 tiles: 4 x 4 size: 1024px x 1024px zoom: 1 tiles: 2 x 2 size: 512px x 512px zoom: 0 tiles: 1 x 1 size: 256px x 256px Soms zal je effectief zelf willen weten op welke pixel een bepaalde coordinaat staat, dus zal je moeten gaan rekenen. Bemerk dat de XY waarde zal afhangen van het zoomlevel: Op zoomlevel 1 bestaat Google Maps uit 1 tegel, dus zal de X/Y waarde van 1 tot 265px gaan Op zoomlevel 2 bestaat Google Maps uit 2x2 tegels, dus zal de X/Y waarde van 1 tot 512 gaan Op zoomlevel 3 ...
  • 47. WGS84 → Pixels lat : 51.061142 lng : 3.708851 Just feed Google Maps WGS84 (decimal degrees) and it’ll transform them automagically x: 130.63740515555554 y: 85.63391060773934 z: 1 Om het effectief om te zetten hoef je niet eerst de WGS84 coord om te zetten naar de projectie (wat je iets in meters zal opleveren!) en dan naar pixels op het scherm. Je kan dat meteen doen.
  • 48. WGS84 → Pixels The formula will need to take the projection distortions into account Let op! Je kan dit niet zomaar afmeten! Herinner u dat de Mercator projectie enkel hoeken respecteert, afstanden tussen punten gemeten met de meetlat zijn niet dezelfde! Ziehier de cirkels: deze beslaan allen een even groot oppervlak maar zien er niet gelijk uit qua grootte!
  • 49. WGS84 → Pixels (Standalone) // Converts a lat/lng coordinate to an XY Point for the given zoom level function fromLatLngToPixel(lat, lng, zoom) { var deg2rad = Math.PI / 180; var x = Math.floor((lng + 180) / 360 * (1 << zoom) * 256); var y = Math.floor((1 - Math.log(Math.tan(lat * deg2rad) + 1 / Math.cos(lat * deg2rad)) / Math.PI) / 2 * (1 << zoom) * 256); return [x, y]; } // Converts an XY Point at the given zoom level to a lat/lng coordinate var fromPixelToLatLng = function(x, y, zoom) { // ... }; console.log(fromLatLngToPixel(51.061142, 3.708851, 0)); // zoom 0: [ x: 130, y: 85 ] // zoom 1: [ x: 261, y: 171 ] // zoom 2: [ x: 522, y: 342 ] Je kan het manueel berekenen, zie hier. Handig voor standalone/serverside implementaties
  • 50. WGS84 → Pixels // Converts a lat/lng coordinate to an XY Point for the given zoom level var latlngToPoint = function(map, latlng){ var normalizedPoint = map.getProjection().fromLatLngToPoint(latlng); var scale = Math.pow(2, map.getZoom()); var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale); return pixelCoordinate; }; // Converts an XY Point at the given zoom level to a lat/lng coordinate var pointToLatlng = function(map, point){ var scale = Math.pow(2, map.getZoom()); var normalizedPoint = new google.maps.Point(point.x / scale, point.y / scale); var latlng = map.getProjection().fromPointToLatLng(normalizedPoint); return latlng; }; console.log(latlngToPoint(map, new google.maps.LatLng(51.061142, 3.708851))); // zoom 0: [ x: 130.63740515555554, y: 85.63391060773934 ] // zoom 1: [ x: 261.2748103111111, y: 171.26782121547868 ] // zoom 2: [ x: 522.5496206222222, y: 342.53564243095735 ] Ondertussen voorziet Google ons met versie 3 ons ondertussen van een hulpmiddel `map.getProjection().fromLatLngToPixel() ` dat het rekenen voor zich neem. Best dit te gebruiken gezien dit mee met de projectie gaat (op Google Maps kan je van projectie wisselen – zie https://developers.google.com/maps/documentation/javascript/ maptypes#Projections) We bereken de positie op zoomlevel 0, en scalen dan mee up met het zoomlevel.
  • 51. WGS84 → EPSG:900913 // Converts WGS84 coordinates (lat,lng) to EPSG:900913 coordinates (x,y) var WGS84toSphericalMercator = function(lat, lng) { var x = lng * 20037508.34 / 180; var y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); y = y * 20037508.34 / 180; return [x, y]; } // Converts EPSG:900913 coordinates (x,y) to WGS84 coordinates (lat,lng) var SphericalMercatorToWGS84 = function(x, y) { var lat = (y / 20037508.34) * 180; var lng = (x / 20037508.34) * 180; lat = 180/Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2); return [lat, lng]; } console.log(WGS84toSphericalMercator(51.061142, 3.708851)); // -> [ x: 412867.4046906519, y: 6632116.16820788 ] console.log(SphericalMercatorToWGS84(412867.4046906519, 6632116.16820788)); // -> [ lat: 51.06114199999999, lng: 3.708851 ] Voor zij die toch de SphericalMercator omvormstap ooit zouden nodig hebben, hier is’m.
  • 52. 3D → Pixels →Tile // Converts an XY Point to a tile index var pointToTile = function(x, y) { var TILE_SIZE = 256; return [Math.floor(x / TILE_SIZE), Math.floor(y / TILE_SIZE)]; } console.log(pointToTile(260, 125)); // [ 1, 0 ] Wat je vervolgens ook nog heel simpel kan doen is te weten komen op welk tegel een bepaalde XY coordinaat staat. Niet meer dan een simpele math.floor een deling.
  • 53. Pixeloffset inViewport Soms zal je willen weten wat de positie van een coordinaat tov de NW corner is.
  • 54. Pixeloffset inViewport // Calculates the XY pixel offset of a Coordinate relative to the NW (top left) corner of the map var getCanvasPointOffset(latLng) { var scale = Math.pow(2, map.getZoom()); var nw = new google.maps.LatLng( map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng() ); var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw); var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng); var pixelOffset = new google.maps.Point( Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale) ); } console.log(getCanvasPointOffset(marker.getPosition())); Daar bestaat uiteraard een formule voor: bereken twee XY paren en retourneer het verschil.
  • 55. Pixeloffset inViewport http://bruxellesmdr.be/home Praktisch voorbeeld: deze overlays bij de markers. Ja, je kan het doen via de muispositie, maar via de map is net iets geekier. Let trouwens ook op het gebruik van de minimap op deze site, en het rode kader dat mee gaat: concreet gezien neem je steeds de bounds (NW en SE corner) van de grote map en stel je deze in als NW en SE corner van de rechthoek. Bijkomend trigger je dan nog een click event op de minimap om het kader (en de grote map ook) te herpositioneren.
  • 56. CUSTOMTILES It’s JavaScript, so it’s hackable/extendable!
  • 57. CustomTiles http://www.use-it.travel/cities/map/ghent/?zoom Custom Tiles is iets wat je kan gebruiken om eigen maps (of heel grote pano’s) te gaan serven. De mensen van USE-IT bvb maken tourist guides die ze ook digitaal verspreiden.
  • 58. On Disk Format: z_x_y.jpg Op disk ziet dat er zo uit: per zoom level zijn alle tiles gegenereerd.
  • 59. Serving CustomTiles Full code at http://bramus.github.io/photoshop-google-maps-tile-cutter/example/ var customMapType = new google.maps.ImageMapType({ getTileUrl: function(coord, zoom) { var nCoord = getNormalizedCoord(coord, zoom); return 'tiles/' + zoom + '_' + nCoord.x + '_' + nCoord.y + '.jpg'; }, tileSize: new google.maps.Size(256, 256), maxZoom: maxZoom, name: '...' }); var map = new google.maps.Map(document.getElementById('map'), { center: new google.maps.LatLng(0, 0), zoom: 2, streetViewControl: false, mapTypeControl: false, mapTypeControlOptions: { mapTypeIds: ["custom"] } }); map.mapTypes.set('custom', customMapType); map.setMapTypeId('custom'); Deze kan je dan instellen om getoond te worden ter vervanging van de Google Maps Tiles. De getTileUrl functie is de cruciale in het verhaal.
  • 60. CutTiles using aTileCutter Automatically with https://github.com/bramus/photoshop-google-maps-tile-cutter Het aanmaken van de tiles gebeurt met een TileCutter. Er bestaan er heel wat, maar ik heb m’n eigen TileCutter geschreven: een Photoshop Script dat een geopende (grote) afbeelding zal aflopen en alle mogelijke tiles er van zal trekken. Dat script is trouwens geschreven in JavaScript: je kan Photoshop aansturen via JS ... #zottesfeer!
  • 62. GowallaHEAT (RIP) http://gowallaheat.bram.us/ Heatmaps vind ik zelf supercool! Het laat je toe om zeer knappe visualisaties te maken. Hier ene dat ik ooit gemaakt heb: GowallaHEAT die je Gowalla (RIP) checkins visualiseert.
  • 63. GowallaHEAT Core (PHP) Heatmap Rendering of pixel based canvases Canvas dimensions passed into constructor Points are added as X/Y coordinates MercatorHeatmapTile Rendering of Mercator based tiles Canvas is created as a specific tile of a certain zoom level (256px) Points are added as WGS84 and are converted to X/Y Only specific tile is rendered MercatorHeatmap Rendering of Mercator based canvases Canvas is created for a given zoom level (256px, 512px, 1024px, ...) Points are added as WGS84 and are converted to X/Y Het ding is indertijd gemaakt in PHP en bestaat uit drie basisklasses die van elkaar overerven.
  • 64. Generating Heatmaps Heatmaps renderen is echt niet moeilijk eens je’t weet: - plot per punt een dot die transparant wordt naar de buitenkant toe - overlap zorgt er voor dat de gebieden donkerder of lichter worden. - map dan de donkerheidsgraad aan een bepaalde gradient: transparent (of wit) wordt blauw, lichtgrijs groen, zwart wordt rood (of wit)
  • 65. Overlaying Heatmaps // Gowallaheat was implemented with Google Maps v2, so alas no code to show ... // System is comparable to working with custom tiles though: // Store the tiles as `z_x_y.png` on the server and load ‘m in Om de transparante overlays nu te renderen op een Google Maps heb je heel wat JS nodig. Helaas dateert de implementatie van in de tijd van GMaps2 en is de code niet meer up-to- date. Principe is wel het zelfde als bij het werken met custom tiles: tiles worden genummerd & ingeladen via een custom functie.
  • 66. Heatmaps in Google Maps v3 var pointArray = new google.maps.MVCArray([ new google.maps.LatLng(37.782551, -122.445368), ... new google.maps.LatLng(37.783206, -122.440829) ]); var heatmap = new google.maps.visualization.HeatmapLayer({ data: pointArray }); heatmap.setMap(map); https://developers.google.com/maps/documentation/javascript/examples/layer-heatmap Nu, de code van toen heb je niet nodig, gezien het nu vanzelf in Google Maps v3 zit – hoera!
  • 67. SHAPEFILES & GEOJSON The vectors of the mapping business
  • 68. Shapefile “A shapefile is a digital vector storage format for storing geometric location and associated attribute information.” Shapefiles zijn de svg’s van de mapping business. Je kan deze bekijken met een shapefile viewer.
  • 69. Rendering Shapefiles https://github.com/kig/shp.js/ Shapefiles kan je niet renderen op Google Maps helaas, maar wel bvb. met D3.js en een shp.js plugin. Met KartoGraph kan je ook aan de slag.
  • 70. Shapefiles Oost-Vlaanderen http://www.gisoost.be/home/atlasbw.php?kies=alle_gemeenten Vele van de gis diensten in België bieden shapefiles aan, maar je moet ze wel weten te vinden ;-) Let op, je zal ook moeten filteren — er zit heel veel cruft tussen
  • 71. GeoJSON “GeoJSON allows geographic data to be stored in a human-readable way” { "type": "Feature", "id": "OpenLayers.Feature.Vector_314", "properties": {}, "geometry": { "type": "Point", "coordinates": [ 97.03125, 39.7265625 ] } } Naast shapefiles heb je ook GeoJSON. Voor ons iets handiger om mee te werken want da’s tekst die we kunnen lezen. In die GeoJSON kan je alles opslaan: Markers (punten), PolyLines (lijnen), PolyGons (vormen), etc. — echt wel vet!
  • 72. GeoJSON https://github.com/JasonSanford/GeoJSON-to-Google-Maps Het gebruik van GeoJSON binnen Google Maps is simpel, mits een hulpmiddel.
  • 73. Mercator Puzzle Redux http://bramus.github.io/mercator-puzzle-redux/ Herinner u de Mercator puzzel? Heb die wat aangepast zodat je niet steeds dezelfde 15 landen krijgt. De landen dat is uit een GeoJSON file gehaald. Bijkomend is er nog wat geprutst om de shapes programmatorisch te verplaatsen: van elk land wordt het middelpunt van de shape genomen en per punt van de shape wordt vanuit het middelpunt de richting en de afstand genoteerd. Vervolgens wordt de shape op een andere plaats (waar de afstanden anders zijn, maar de hoeken de zelfde) hertekend als zijnde: teken mij nu eens alle punten op een bepaalde afstand en richting vanaf het nieuwe middelpunt.
  • 74. http://www.bram.us/2013/02/16/google-maps-v3-move-polygon/ Mercator Puzzle Redux Sidenote Herinner u de Mercator puzzel? Heb die wat aangepast zodat je niet steeds dezelfde 15 landen krijgt. De landen dat is uit een GeoJSON file gehaald. Bijkomend is er nog wat geprutst om de shapes programmatorisch te verplaatsen: van elk land wordt het middelpunt van de shape genomen en per punt van de shape wordt vanuit het middelpunt de richting en de afstand genoteerd. Vervolgens wordt de shape op een andere plaats (waar de afstanden anders zijn, maar de hoeken de zelfde) hertekend als zijnde: teken mij nu eens alle punten op een bepaalde afstand en richting vanaf het nieuwe middelpunt.
  • 75. Shapefile → GeoJSON http://www.bram.us/2012/03/14/convert-esri-shapefile-shp-to-geojson-json/ $ /Library/Frameworks/GDAL.framework/Programs/ogr2ogr -f "GeoJSON" output.json input.shp $ /Library/Frameworks/GDAL.framework/Programs/ogr2ogr -f "GeoJSON" -s_srs "EPSG:31370" -t_srs "WGS84" output.json input.shp Shapefile to GeoJSON Shapefile to GeoJSON with coordinates conversion http://spatialreference.org/ Shapefiles kan je naar GeoJSON omzetten. Let op met de shapefiles van GisOOST: deze zijn in Lambert1972 en zal je dus naar WGS84 moeten omzetten. Gelukkig kan die ogr2ogr daar mee overweg. Wat je wel zal moeten te weten komen is de EPSG code. Die kan je vinden op http://spatialreference.org/
  • 76. Shapefile Deelgemeenten Deinze Hier een voorbeeld van de deelgemeenten van Deinze: Shapefile van Gisoost, omgezet met ogr2ogr naar WGS84 coordinaten, ingeladen in Google Maps met behulp van de GeoJSON plugin. En het blijkt nog te kloppen ook. Indien het niet klopt: coordinatenconversie nakijken!
  • 77. Shapefile → SVG → Browser http://kartograph.org/ Met Kartograph kan je een shapefile omzetten naar een SVG (met een bepaalde projectie) en deze dan via javascript embedden, stylen, en zelfs interactief maken. Bestaat uit een python script om een SVG te creëren, en een JS lib om de SVG vervolgens te embedden.
  • 79. Ferraris Maps (1777) http://www.kbr.be/collections/cart_plan/ferraris/ferraris_nl.html De Ferraris kaarten zijn echt prachtig en hi-res. Hier Gent bvb. Enige jammere is dat die site niet echt wow is, en de viewer in Flash is.
  • 80. Styled Maps https://developers.google.com/maps/documentation/javascript/styling http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html Google Maps kan je perfect stylen naar hetgeen je wil. Per entitiet (straten, labels, landmassa, water, etc) kan je instellen of het zichtbaar moet zijn of niet, wat het kleur is, etc. Resultaat uit deze hulptool is JSON die je dan mee aan de config van je map instance geeft.
  • 81. Distance Between Points // Manual: Haversine Formula: shortest route over a sphere function distance(latlng1, latlng2) { var R = 6371, // Radius of the earth, in km. Need miles? change to 3961 dLat = (latlng2.lat - latlng1.lat) * (Math.PI / 180), dLon = (latlng2.lng - latlng1.lng) * (Math.PI / 180), a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(latlng1.lat * (Math.PI / 180)) * Math.cos(latlng2.lat * (Math.PI / 180)) * Math.sin(dLon / 2) * Math.sin(dLon / 2), c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), d = R * c; return d; } // Google Maps v3 with Geometry Library // @see https://developers.google.com/maps/documentation/javascript/geometry google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB); De kortste afstand op een mercator projectie is geen rechte lijn. Gebruik hiervoor de haversine formule, die rekening houdt met de straal van de aarde.
  • 82. Bearing/Heading // Manual calculation of the bearing var y = Math.sin(dLon) * Math.cos(lat2); var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2) * Math.cos(dLon); var brng = Math.atan2(y, x).toDeg( // Google Maps v3 with Geometry Library // @see https://developers.google.com/maps/documentation/javascript/geometry google.maps.geometry.spherical.computeHeading (latLngA, latLngB); Je kan ook de richting naar een bepaald punt (vanuit een ander punt) gaan bepalen. Is dus iets wat gebruikt werd bij die Mercator Puzzle Redux van daarstraks
  • 83. Areal Photos of Belgium http://ogc.beta.agiv.be/gdiviewer/ Luchtfoto’s van België (veel beter dan die van Google of Bing) vind je op Agiv. Dataset werd onlangs vernieuwd.
  • 84. Topograhpic Maps of Belgium http://www.ngi.be/topomapviewer/public?lang=nl& Stafkaarten en zo staat dan weer op ngi.be.
  • 85. Marker Clustering http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/examples.html Voor het weergeven van heel wat markers is een markerclusterer handig. Voor gebruik in Google Maps bestaat er een inplooibare plugin.
  • 86. Marker Clustering (PHP) http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google-maps Voor zij die in PHP markers willen clusteren ... je zal wel enkele formules herkennen :-)
  • 88. #GEOSHIZZLE Fronteers 25/04/13 @ KaHo Sint-Lieven Braintwists of a mapping aficionado
  • 89. SOURCES • http://www.nationalgeographic.com/features/2000/exploration/projections/ • http://kartoweb.itc.nl/geometrics/map%20projections/mappro.html • http://www.1worldglobes.com/images/columbus_globes/globe_gores_assembly_lg.jpg • http://www.genekeyes.com/CAHILL-1909/fig.1-2-55.jpg • http://www-personal.umich.edu/~sarhaus/UnivChicago/tigdd27proj.html • http://earth.rice.edu/mtpe/geo/geosphere/topics/mapprojections.html • https://en.wikipedia.org/wiki/Map_projection • http://en.wikipedia.org/wiki/Distortion • https://www.e-education.psu.edu/natureofgeoinfo/c2_p29.html • http://upload.wikimedia.org/wikipedia/commons/8/88/Gerardus_Mercator.jpg • https://en.wikipedia.org/wiki/Tissot%27s_indicatrix • http://en.wikipedia.org/wiki/Mercator_1569_world_map • http://en.wikipedia.org/wiki/Mercator_projection • http://www.free-online-private-pilot-ground-school.com/navigation-basics.html • http://en.wikipedia.org/wiki/Datum_(geodesy) • http://en.wikipedia.org/wiki/World_Geodetic_System • http://en.wikipedia.org/wiki/Latitude • http://spatialreference.org/ref/epsg/4326/ • http://spatialreference.org/ref/epsg/31300/ • http://spatialreference.org/ref/epsg/31370/ • http://nl.scoutwiki.org/Lambert_(Belgi%C3%AB) • http://www.ngi.be/NL/NL2-1-7.shtm • http://www.mathworks.com/help/symbolic/mupad_ug/spherical-coordinates.png • http://www.colorado.edu/geography/gcraft/notes/datum/datum.html • http://kartoweb.itc.nl/geometrics/Coordinate%20transformations/coordtrans.html • http://www.ngi.be/Common/Lambert2008/Schema_Lambert_1972_2008_nl.pdf • https://google-developers.appspot.com/maps/documentation/javascript/examples/map- coordinates • http://qfox.nl/notes/116 • http://stackoverflow.com/questions/2674392/how-to-access-google-maps-api-v3-markers- div-and-its-pixel-position • http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ • http://transition.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html • http://www.movable-type.co.uk/scripts/latlong.html • https://developers.google.com/maps/documentation/javascript/examples/layer-heatmap • http://en.wikipedia.org/wiki/GeoJSON •