1. google maps Il nostro obiettivo: “ Poter posizionare e visualizzare nostre informazioni su una mappa geo-referenziandole” Questa tecnica è anche conosciuta come “Mash-up” Per farlo utilizzeremo il servizio messo a disposizione da Google: google maps E lo programmeremo utilizzando le sue API ed i linguaggi : XHTML Javascript PHP
2. mash-up da wikipedia: “ Mash-up (letteralmente: "poltiglia"), in termini informatici, indica un'applicazione che usa contenuto da più sorgenti per creare un servizio completamente nuovo. Il contenuto dei mash-up è normalmente preso da terzi via API , tramite feed (es. RSS e Atom) o Javascript. I mash-up stanno rivoluzionando lo sviluppo del web permettendo a chiunque di combinare dati da siti come Amazon.com, eBay, Google, Windows Live e Yahoo! in modi innovativi.” per approfondire: http://www.ictv.it/file/vedi/168/mashup/ http://www.slideshare.net/valicac/mashups-87355 esempio: http://www.housingmaps.com/
3. google maps da wikipedia (http://it.wikipedia.org/wiki/Google_Maps): “ Google Maps è un servizio accessibile dal relativo sito web e che consente la ricerca e la visualizzazione di mappe geografiche della Terra. Oltre a questo è possibile ricercare servizi in particolari luoghi, tra cui ristoranti, monumenti, negozi, trovare un possibile percorso stradale tra due punti e visualizzare foto satellitari di molte zone con diversi gradi di dettaglio. Le foto sono statiche (non in tempo reale). Oltre a queste funzioni, offre anche una ricerca di attività commerciali sulle stesse mappe” per approfondire: http://www.youtube.com/watch?v=Yu9fV_YyIRI url: http://maps.google.it/
4. API API (Application Programming Interface): Definizione di metodi, oggetti e proprietà per accedere ai dati wikipedia: http://it.wikipedia.org/wiki/Application_programming_interface In particolare nel nostro caso utilizzeremo le google maps API . Che sono costituite da un framework javascript google maps API: http://code.google.com/intl/it-IT/apis/maps/documentation/index.html
5. mappe automatiche con il google wizard Google offre un sistema automatico (wizard) che permette di generare la porzione di codice da aggiungere alle proprie pagine web per aggiungere una semlice mappa al prioprio sito. Le mappe generate dal wizard possono contenere un solo indicatore, non è possibile personalizzarle. url del wizard: http://www.google.com/uds/solutions/wizards/mapsearch.html esempio: http://econym.org.uk/gmap/example_wizard.htm
7. utilizzare le API per poter avere il controllo completo della mappa dobbiamo utilizzare le API messe a disposizione da google e programmare via javascript il nostro mash-up L'utilizzo delle API è gratuito a patto che si rispettino i seguenti punti: - devono essere utilizzate solo in pagine pubbliche e ad accesso gratuito - è necessario registrare un API KEY valida per un solo dominio - non ci sono limiti al numero pagine visualizzate per giorno (ma se supera le 500.000 è bene informare google) - il numero delle richieste di geocode per giorno è limitato - non è consentito oscurare il logo do google url per generare l'API KEY: http://code.google.com/intl/it-IT/apis/maps/signup.html esempio di API KEY: ABQIAAAAglQh2814cniz0fajFXDDlhTbP7gUAaSGLwuL0wgux7a6hFzScxQr0rn6I2U7q0joG3bQXRqHI_uopQ
8. creare una mappa Ottenuta l'API KEY possiamo realizzare la nostra prima pagina con una mappa di google: per prima cosa va creata la pagina XHTML: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> < html xmlns = "http://www.w3.org/1999/xhtml"> < head > < meta http-equiv = "content-type" content = "text/html; charset=utf-8"/> < title > Google Maps JavaScript API Example </ title > </ head > < body > < div id = "map" style =" width : 500px ; height : 300px " ></ div > </ body > </ html >
9. creare una mappa dobbiamo poi includere il framework javascript: … < head > < meta http-equiv = "content-type" content = "text/html; charset=utf-8"/> < title > Google Maps JavaScript API Example </ title > < script src = " http://maps.google.com/maps?file=api&v=2&key=APIKEY " type = "text/javascript"></ script > </ head > …
10. creare una mappa creiamo ora una funzione javascript che verrà eseguita all'onload del body, cioè appena tutta la pagina è stata caricata nel browser. La funzione utilizzerà le API di google per caricare la mappa all'interno del DIV che abbiamo chiamato “map” < head > … < script type = "text/javascript"> //<![CDATA[ function load () { if ( GBrowserIsCompatible ()) { var map = new GMap2 ( document . getElementById ( "map" )); map . setCenter ( new GLatLng ( 37.4419 , -122.1419 ), 13 ); } } //]]> </ script > </ head > < body onload ="load () " onunload ="GUnload () " > < div id = "map" style =" width : 500px ; height : 300px " ></ div > </ body >
11. creare una mappa aggiungiamo i controlli per lo zoom e la visualizzazione < head > … < script type = "text/javascript"> //<![CDATA[ function load () { if ( GBrowserIsCompatible ()) { var map = new GMap2 ( document . getElementById ( "map" )); map . addControl ( new GLargeMapControl ()); map . addControl ( new GMapTypeControl ()); map . setCenter ( new GLatLng ( 43.907787 , -79.359741 ), 8 ); } } //]]> </ script > </ head > < body onload ="load () " onunload ="GUnload () " > < div id = "map" style =" width : 500px ; height : 300px " ></ div > </ body >
12. aggiungere marker ad una mappa per aggiungere dei segnaposto (marker) ad una mappa è utile crearsi una funzione, che ci permetterà di creare l'oggetto segnaposto in un determinato punto e con un particolare codice html da mostrare all'interno del fumetto < head > … < script type = "text/javascript"> //<![CDATA[ … function createMarker ( point , html ) { var marker = new GMarker ( point ); GEvent . addListener ( marker , "click" , function () { marker . openInfoWindowHtml ( html ); }); return marker ; } … //]]> </ script > </ head >
13. aggiungere marker ad una mappa a questo punto possiamo utilizzare la funzione “createMarker” per creare i nostri segna posto all'interno della funzione di inizializzazione “load” … function load () { if ( GBrowserIsCompatible ()) { var map = new GMap2 ( document . getElementById ( "map" )); map . addControl ( new GLargeMapControl ()); map . addControl ( new GMapTypeControl ()); map . setCenter ( new GLatLng ( 43.907787 , -79.359741 ), 8 ); var point = new GLatLng ( 43.65654 , -79.90138 ); var marker = createMarker ( point , '<div style="width:240px">testo del fumetto e un <a href="http://www.e-xtrategy.net">Link<a><div>' ) map . addOverlay ( marker ); } } …
14. aggiungere marker ad una mappa è possibile attivare il fumetto di un marker anche da un link esterno alla mappa. Per farlo è necessario dichiarare un array globale var gmarkers = []; da riempire poi ogni volta che si crea un marker function createMarker ( point , html ) { var marker = new Gmarker ( point ); GEvent . addListener ( marker , "click" , function () { marker . openInfoWindowHtml ( html ); }); gmarkers . push ( marker ); return marker ; } dichiariamo poi una nuova funzione: function myclick ( i ) { GEvent . trigger ( gmarkers [ i ], "click" ); } che richiameremo tramite link dall'html < div >< a href = "#" onclick ="myclick ( 0 ) " > primo </ a > - < a href = "#" onclick ="myclick ( 1 ) " > secondo </ a ></ div >
15. caricare da un file XML se vogliamo gestire molti marker la cosa migliore è caricarli utilizzando un file esterno XML. per prima cosa dobbiamo crere il file example.xml: < markers > < marker lat =" 43.65654 " lng =" -79.90138 " html =" Some stuff to display in the<br>First Info Window " label =" Marker One " /> < marker lat =" 43.91892 " lng =" -78.89231 " html =" Some stuff to display in the<br>Second Info Window " label =" Marker Two " /> < marker lat =" 43.82589 " lng =" -79.10040 " html =" Some stuff to display in the<br>Third Info Window " label =" Marker Three " /> </ markers > Ora modifichiamo il codice javascript per leggere le info dei marker dal file XML
16. caricare da un file XML all'interno della funzione “load” aggiungiamo: function load () { if ( GBrowserIsCompatible ()) { var map = new GMap2 ( document . getElementById ( "map" )); map . addControl ( new GLargeMapControl ()); map . addControl ( new GMapTypeControl ()); map . setCenter ( new GLatLng ( 43.907787 , -79.359741 ), 8 ); GDownloadUrl ( "example.xml" , function ( doc ) { var xmlDoc = GXml . parse ( doc ); Var markers = xmlDoc . documentElement . getElementsByTagName ( "marker" ); for ( var i = 0 ; i < markers . length ; i ++) { var lat = parseFloat ( markers [ i ]. getAttribute ( "lat" )); var lng = parseFloat ( markers [ i ]. getAttribute ( "lng" )); var point = new GLatLng ( lat , lng ); var html = markers [ i ]. getAttribute ( "html" ); var label = markers [ i ]. getAttribute ( "label" ); var marker = createMarker ( point , label , html ); map . addOverlay ( marker ); } }); } }
17. pilotare la mappa dall'HTML per farlo occorre che l'oggetto “map” sia dichiarato esternamente alla funzione “load” in modo che risulti globale var map function load () { if ( GBrowserIsCompatible ()) { map = new GMap2 ( document . getElementById ( "map" )); … } ora possiamo accedere ai metodi dell'oggetto “map” anche da altre funzioni: function myzoom ( a ) { map . setZoom ( map . getZoom () + a ); } e richiamare la funzione dall'html < a href = "javascript:myzoom(5)"> Zoom +5 </ a >< br /> < a href = "javascript:myzoom(-5)"> Zoom -5 </ a >< br />
18. disegnare linee e poligoni oltre i segna posti e possibile disegnare linee per indicare percorsi. per farlo inannzitutto modifichiamo il file XML aggiungendo le informazioni delle linee da disegnare < markers > < marker lat =" 43.65654 " lng =" -79.90138 " html =" finetra 1 " label =" Marker One " /> < marker lat =" 43.91892 " lng =" -78.89231 " html =" finestra 2 " label =" Marker Two " /> < marker lat =" 43.82589 " lng =" -79.10040 " html =" finestra 3 " label =" Marker Three " /> < line colour =" #FF0000 " width =" 4 " > < point lat =" 43.65654 " lng =" -79.90138 " /> < point lat =" 43.91892 " lng =" -78.89231 " /> < point lat =" 43.82589 " lng =" -79.10040 " /> </ line > < line colour =" #008800 " width =" 8 " > < point lat =" 43.9078 " lng =" -79.0264 " /> < point lat =" 44.1037 " lng =" -79.6294 " /> < point lat =" 43.5908 " lng =" -79.2567 " /> < point lat =" 44.2248 " lng =" -79.2567 " /> < point lat =" 43.7119 " lng =" -79.6294 " /> < point lat =" 43.9078 " lng =" -79.0264 " /> </ line > </ markers >
19. disegnare linee e poligoni ed aggiungiamo il codice per estrarre le informazioni relative alle linee all'interno della funzione di callback richiamata da “ GDownloadUrl” GDownloadUrl ( "example1.xml" , function ( doc ) { var xmlDoc = GXml . parse ( doc ); var markers = xmlDoc . documentElement . getElementsByTagName ( "marker" ); for ( var i = 0 ; i < markers . length ; i ++) { ... } var lines = xmlDoc . documentElement . getElementsByTagName ( "line" ); for ( var a = 0 ; a < lines . length ; a ++) { var colour = lines [ a ]. getAttribute ( "colour" ); var width = parseFloat ( lines [ a ]. getAttribute ( "width" )); var points = lines [ a ]. getElementsByTagName ( "point" ); var pts = []; for ( var i = 0 ; i < points . length ; i ++) { pts [ i ] = new GLatLng ( parseFloat ( points [ i ]. getAttribute ( "lat" )), parseFloat ( points [ i ]. getAttribute ( "lng" ))); } map . addOverlay ( new GPolyline ( pts , colour , width )); } });
20. adattare lo zoom in base ai marker se i marker da visualizzare sono molti e magari generati in modo dinamico (vedremo poi come) è possibile che i livello di zoom scelto per la mappa non sia sempre corretto per mostrare subito nella videata tutti marker se, ad esempio, modifichiamo il nostro file XML inserendo altri 3 marker con coordinate piuttosto lontane dai tre iniziali vedremo che si trovano al di fuori della parte visibile della mappa: <markers> <marker lat="43.65654" lng="-79.90138" html="Some stuff to display in the<br>First Info Window" label="Marker One"/> <marker lat="43.91892" lng="-78.89231" html="Some stuff to display in the<br>Second Info Window" label="Marker Two"/> <marker lat="43.82589" lng="-79.10040" html="Some stuff to display in the<br>Third Info Window" label="Marker Three"/> <marker lat="44.65654" lng="-78.90138" html="Some stuff to display in the<br>A Info Window" label="Marker A"/> <marker lat="44.91892" lng="-77.89231" html="Some stuff to display in the<br>B Info Window" label="Marker B"/> <marker lat="44.82589" lng="-78.10040" html="Some stuff to display in the<br>C Info Window" label="Marker C"/> </markers>
21. adattare lo zoom in base ai marker modificando il codice javascript, possiamo fare in modo che il livello si zoom sia calcolato in modo da mostrare tutti marker: //dichiariamo una nuova variabile globale var bounds; … //all'interno della funzione load annulliamo il setCenter map.setCenter(new GlatLng(0,0),0); //e creiamo l'oggetto Bounds bounds = new GlatLngBounds(); … //all'intenro del ciclo for che aggiunge i marker inseriamo bounds.extend(point); … //sempre dentro il metodo di callback ma fuori dal ciclo for inseriamo map.setZoom(map.getBoundsZoomLevel(bounds)); map.setCenter(bounds.getCenter());
22. visualizzazione a tab nel fumetto è possibile visualizzare una serie di TAB (linguette) all'interno del fumetto. Per farlo sostituiamo la funzione per la creazione del marker: function createTabbedMarker ( point , html1 , html2 , label1 , label2 ) { var marker = new GMarker ( point ); GEvent . addListener ( marker , "click" , function () { marker . openInfoWindowTabsHtml ( [ new GInfoWindowTab ( label1 , html1 ), new GinfoWindowTab ( label2 , html2 )] ); }); gmarkers . push ( marker ); } Ed andiamo a modificare la chiamata alla funzione che crea il marker all'interno del ciclo for dopo la lettura del file XML var marker = createTabbedMarker ( point , "primo contenuto" , "secondo contenuto" , "primo tab" , "secondo tab" );
23. personalizzare l'immagine del marker Google mette a disposizione anche un oggetto javascript che offre la possibilità di personalizzare l'immagine utilizzata per la creazione del marker. //per prima cosa va creato e configurato l'oggetto (dentor l'IF della funzione load) var martini = new GIcon(); martini.iconSize=new GSize(32,32); martini.shadowSize=new GSize(56,32); martini.iconAnchor=new GPoint(16,32); martini.infoWindowAnchor=new GPoint(16,0); martini.image = "http://maps.google.com/mapfiles/kml/pal2/icon27.png"; martini.shadow = "http://maps.google.com/mapfiles/kml/pal2/icon27s.png"; //mmodifichiamo la funzione createMarker in modo da prevedere l'icona function createMarker(point,html, icon ) { var marker = new GMarker(point, icon ); GEvent.addListener(marker, "click", function() { marker.openInfoWindowHtml(html); }); gmarkers.push(marker); return marker; } //ed al momento di aggiugere il marker specifichiamo l'icona var marker = createMarker(point,html, martini );
24. caricare i marker da un file KML Al posto di sviluppare codice in javascript utilizzando le Google Maps API è possibile personalizzare una mappa di google anche preparando un file KML e inviando a google stesso che provvedere a renderlo visibile sulla mappa Il KML (Keyhole Markup Language) è un linguaggio basato su XML creato per gestire dati geospaziali in tre dimensioni nei programmi Google Earth, Google Maps e Google Mobile. Un semplice file KML contiene sempre oltre all'intestazione XML anche una intestazione psecifica KML ed un tag radice: <Document> ... </Document> . All'interno del tag Document possono esserci una serie di <Placemark> ognuno descriverà un elemento da mettere sopra la mappa <?xml version="1.0" encoding="UTF-8"?> <kml xmlns=" http://earth.google.com/kml/2.0 "> <Document> <name>KML Example file</name> <description>Simple markers</description> <Placemark> <name>Marker 1</name> <description>testo di esempio</description> <Point> <coordinates>-122.1,37.4,0</coordinates> </Point> </Placemark> </Document> </kml>
25. caricare i marker da un file KML <?xml version="1.0" encoding="UTF-8"?> <kml xmlns=" http://earth.google.com/kml/2.0 "> <Document> <name>KML Example file</name> <description>Simple markers</description> <Placemark> <name>Marker 1</name> <description>testo di esempio</description> <Point> <coordinates>-122.1,37.4,0</coordinates> </Point> </Placemark> </Document> </kml> ANALIZZIAMO IL DOCUMENTO Il file deve essere un XML sintatticamente valido, e i nomi dei tag sono case sensitive Il valore no del tag name verrà mostrato nella barra del titolo e nella side bar Il valore del tag description verrà mostrato nella sidebar Il valore del name all'interno del Placemark verrà mostrato nella the sidebar e nel fumetto Il valore della description all'interno del Placemark verrà mostrato nel fumetto Le coordinates si riferiscono rispettivamente alla longitudine e alla latitudine e all'altitudine (google map non è in grado di gestire l'altitudine). La mappa verrà automaticamente centrata e zoommata per mostrare tutti i placemarks. Per inviarla a Google basta passarla come parametro in questo modo: http://maps.google.com/maps?q=http://hosting3.e-xtrategy.net/corsoitis/lorenzo/kml1.xml
26. caricare i marker da un file KML Ovviamente le stesse funzionalità le possiamo ottenere in modo piuttosto semplice utilizzando le Google Map API function load() { if (GBrowserIsCompatible()) { var map = new Gmap2(document.getElementById("map")); map.addControl(new GlargeMapControl()); map.addControl(new GmapTypeControl()); map.setCenter(new GLatLng(53.763325,-2.579041), 9); var kml = new GGeoXml(" http://hosting3.e-xtrategy.net/corsoitis/lorenzo/kml2.xml "); map.addOverlay(kml); } } ATTENZIONE: il file XML deve essere navigabile da Google
27. limitare la possibilità di zoom/movimento Per limitare la possibilità di Zoom dobbiamo sovrascrivere i metodi .getMinimumResolution() e .getMaximumResolution() del nostro oggetto map Per prima cosa bisogna dire che questa operazione va fatta per ogni tipo di mappa presente nella nostra pagina (satellitare, ibrida, normale) infatti all'interno dell'oggetto principale map sono presenti ulteriori oggetti uno per ogni tipo di mappa. Ed i metodi da sovrascrivere si trovano all'interno di questi oggetti. Per estrarre l'array con i vari tipi di mappa possiamo usare il metodo getMapTypes var mt = map.getMapTypes(); Ora non resta che scorrere l'array mt e per ogni elemento sovrascrivere i metodi for (var i=0; i<mt.length; i++) { mt[i].getMinimumResolution = function() {return 7;} mt[i].getMaximumResolution = function() {return 11;} } Questo codice va inserito dopo la creazione della mappa e all'interno della funzione load
28. limitare la possibilità di zoom/movimento Per limitare la possibilità di Movimento dobbiamo invece catturare l'evento move, che si scatena quando l'utente sposta la mappa, e permettere il movimento solo se si rimane all'interno dello spazio consentito Per prima cosa bisogna creiamo (a livello globale) un oggetto bounds per definire l'area consentita var allowedBounds = new GLatLngBounds(new GLatLng(49.5,-10), new GLatLng(59,2.6)); Poi prepariamo una funzione che verifichi se la mappa è all'interno dell'area scelta function checkBounds() { if (allowedBounds.contains(map.getCenter())) { return; } var C = map.getCenter(); var X = C.lng(); var Y = C.lat(); var AmaxX = allowedBounds.getNorthEast().lng(); var AmaxY = allowedBounds.getNorthEast().lat(); var AminX = allowedBounds.getSouthWest().lng(); var AminY = allowedBounds.getSouthWest().lat(); if (X < AminX) {X = AminX;} if (X > AmaxX) {X = AmaxX;} if (Y < AminY) {Y = AminY;} if (Y > AmaxY) {Y = AmaxY;} map.setCenter(new GLatLng(Y,X)); }
29. limitare la possibilità di zoom/movimento Infine possiamo cattuare l'evento move e richiamare la nostra funzione GEvent.addListener(map, "move", function() { checkBounds(); });
30. calcolare la distanza tra due punti Per calcolare la distanza (inmetri) tra due punti esiste un metodo dedicato distanceFrom che fa parte della classe GPoint All'interno del ciclo che disegna i marker possiamo utilizzare il metodo distanceFrom per calcolare la distanza dei punti con il centro della mappa var point = new GLatLng(lat,lng); d=point.distanceFrom(new GLatLng(43.907787,-79.359741))/1000; var strDistanza = "Distanza dal centro: "+d.toFixed(3)+" Km."; var marker = createMarker(point,strDistanza,martini);
31. scrivere un etichetta sopra al marker JSON JSON, acronimo per: JavaScript Object Notation, è un modo semplice e veloce per descrivere dati verso un computer ma in modo Human-Readable. Consiste in una stringa di testo ed è in grado di descrivere semplici strutture di dati (oggetti, array). var OggettoJSON = {"firstName": "John", "lastName": "Smith", "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": 10021} } Var Oggetto = eval(“(“+OggettoJSON+”)”); alert(Oggetto.firstName); alert(Oggetto.address.streetAddress);
32. scrivere un etichetta sopra al marker Quando creiamo un Icona da utilizzare come marker (tramite l'oggetto Gicon) possiamo definire un livello “label” da mettere in overlay (sopra) l'icona di base che utilizziamo come segnaposto. In questo modo possiamo creare diverse combinazioni di immagini di sfondo e label in overlay:
33. scrivere un etichetta sopra al marker Iniziamo preparando 2 array con l'elenco delle immagini di sfondo e di quelle di overlay: var background = []; background["pink"] = "http://econym.org.uk/gmap/colour108.png"; background["gold"] = "http://econym.org.uk/gmap/colour086.png"; background["white"] = "http://econym.org.uk/gmap/colour125.png"; var overlay = []; overlay["A"] = "http://econym.org.uk/gmap/overlay2.png"; overlay["B"] = "http://econym.org.uk/gmap/overlay3.png"; overlay["C"] = " http://econym.org.uk/gmap/overlay4.png "; Poi modifichiamo la funzione createMarker in questo modo: function createMarker(point,html, ba,ov ) { var mylabel = {"url":overlay[ov], "anchor":new GLatLng(4,4), "size":new GSize(12,12) }; var MyIcon = new GIcon(G_DEFAULT_ICON, background[ba], mylabel); var marker = new GMarker(point, MyIcon ); GEvent.addListener(marker, "click", function() { marker.openInfoWindowHtml(html); }); gmarkers.push(marker); return marker; }
34. scrivere un etichetta sopra al marker Infine dobbiamo creare i marker scegliendo quale background e quale overlay vogliamo visualizzare: function load() { if (GBrowserIsCompatible()) { map = new GMap2(document.getElementById("map")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(43.907787,-79.359741),8); var point = new GLatLng(43.65654,-79.90138); var marker = createMarker(point,'Fumetto del punto A', 'white','A' ); map.addOverlay(marker); var point = new GLatLng(43.91892,-78.89231); var marker = createMarker(point,'Fumetto del punto B', 'pink','B' ); map.addOverlay(marker); var point = new GLatLng(43.82589,-79.10040); var marker = createMarker(point,'Fumetto del punto C', 'gold','C' ) map.addOverlay(marker); } }
35. posizionare un oggetto HTML sulla mappa E' possibile prendere un qualsiasi oggetto della nostra pagina HTML e posizionarlo sopra la mappa. Ad Esempio se abbiamo questo codice HTML: <div id="htmlOverlay" style="background-color:#ffffff;font-weight:bold;border:2px #006699 solid;width:350px;"> Questo contenuto HTML viene posizionato sopra la mappa </div> Per posizionarlo nella mappa dobbiamo aggiungere nella funziona load: var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(100,10)); pos.apply(document.getElementById("htmlOverlay")); map.getContainer().appendChild(document.getElementById("htmlOverlay")); Per i posizionamenti Google mette a disposizione le seguenti costanti: G_ANCHOR_BOTTOM_LEFT, G_ANCHOR_BOTTOM_RIGHT, G_ANCHOR_TOP_LEFT, G_ANCHOR_TOP_RIGHT
36. gestire enormi quantità di marker I marker che noi creiamo sono sempre presenti sulla mappa, anche quanto il livello di zoom o il posizionamento non li mostra. Se abbiamo un numero molto elevato di marker da visualizzare, il carico di lavoro del browser sarà molto alto e la pagina molto lenta sia nella creazione iniziale sia nei movimenti. Per evitare questo Google mette a disposizione un oggetto GmarkerManager in grado di gestire enormi quantità di marker Vogliamo ad esempio mostrare sulla mappa un file XML così strutturato: <markers> <marker town="Agatwi" lat="-1.88590506132813" lng="30.0548049476562" pop="108798"/> <marker town="Astrida" lat="-2.58252615507813" lng="29.7232724449219" pop="65300"/> <marker town="Banda" lat="-2.4248616203125" lng="29.1638960441406" pop="20376"/> <marker town="Bandazi" lat="-1.91353471601562" lng="30.2231807121094" pop="33155"/> <marker town="Basa" lat="-1.669729784375" lng="29.3591235351563" pop="60226"/> <marker town="Bganga" lat="-1.45328979492188" lng="30.4413044914063" pop="6329"/> … </markers> Che contiente 1576 marker http://hosting3.e-xtrategy.net/corsoitis/lorenzo/rwanda.xml
37. gestire enormi quantità di marker Anche solo la lettura di questo file impiegherà molto tempo. Aggiungiamo quindi un messaggio di “loading” da visualizzare fino a che no abbiamo completato tutte le nostre operazioni: ... if (GBrowserIsCompatible()) { var om = new OverlayMessage(document.getElementById('map')); om.Set('<b>Loading...<b>'); … … … GDownloadUrl("http://hosting3.e-xtrategy.net/corsoitis/lorenzo/rwanda.xml", function (doc) { … … om.Clear(); }); } Per poter funzionare dobbiamo aggiungere la libreria OverlayMessagge che possiamo caricare come javascript esterno all'interno dell'HEAD in questo modo: <script src="http://www.acme.com/javascript/OverlayMessage.js" type="text/javascript"></script>
38. gestire enormi quantità di marker Dopo l'apertura del loading andiamo a definire le icone che utilizzeremo per le diverse tipologie di marker: … … var icon = new GIcon(); icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png"; icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png"; icon.iconSize = new GSize(12, 20); icon.shadowSize = new GSize(22, 20); icon.iconAnchor = new GPoint(6, 20); icon.infoWindowAnchor = new GPoint(5, 1); iconblue = new GIcon(icon,"http://labs.google.com/ridefinder/images/mm_20_blue.png"); icongreen = new GIcon(icon,"http://labs.google.com/ridefinder/images/mm_20_green.png"); iconyellow = new GIcon(icon," http://labs.google.com/ridefinder/images/mm_20_yellow.png "); function createMarker(point,html,icon) { var marker = new GMarker(point, icon); GEvent.addListener(marker, "click", function() { marker.openInfoWindowHtml(html); }); return marker; }
39. gestire enormi quantità di marker All'interno della funzione GDownloadUrl andiamo a leggere i contenuti del file XML GDownloadUrl("http://hosting3.e-xtrategy.net/corsoitis/lorenzo/rwanda.xml", function (doc) { var gmarkersA = []; var gmarkersB = []; var gmarkersC = []; var gmarkersD = []; var xmlDoc = GXml.parse(doc); var markers = xmlDoc.documentElement.getElementsByTagName("marker"); for (var i = 0; i < markers.length; i++) { var lat = parseFloat(markers[i].getAttribute("lat")); var lng = parseFloat(markers[i].getAttribute("lng")); var point = new GLatLng(lat,lng); var town = markers[i].getAttribute("town"); var pop = markers[i].getAttribute("pop"); … } … … Prepariamo 4 array che conterranno i marker dei quattro tipi di punti in modo da poter assegnare ad ogni tipo un icona diversa
40. gestire enormi quantità di marker Nel momento della creazione dei marker li dividiamo per tipo in base al valore della popolazione GDownloadUrl("http://hosting3.e-xtrategy.net/corsoitis/lorenzo/rwanda.xml", function (doc) { … for (var i = 0; i < markers.length; i++) { … … if (parseInt(pop) > 70000) { var marker = createMarker(point,town+"<br>Population: "+pop,icon); gmarkersA.push(marker); } else if (parseInt(pop) > 50000) { var marker = createMarker(point,town+"<br>Population: "+pop,iconyellow); gmarkersB.push(marker); } else if (parseInt(pop) > 40000) { var marker = createMarker(point,town+"<br>Population: "+pop,icongreen); gmarkersC.push(marker); } else { var marker = createMarker(point,town+"<br>Population: "+pop,iconblue); gmarkersD.push(marker); } }
41. gestire enormi quantità di marker A questo punto creiamo la mappa e chiediamo a GMarkerManager di visualizzare i punti sulla mappa GDownloadUrl("http://hosting3.e-xtrategy.net/corsoitis/lorenzo/rwanda.xml", function (doc) { … for (var i = 0; i < markers.length; i++) { … … } var map = new GMap2(document.getElementById("map")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(-1.6347,29.388), 11, G_SATELLITE_MAP); var mm = new GMarkerManager (map, {borderPadding:1}); mm.addMarkers(gmarkersA,0,17); mm.addMarkers(gmarkersB,11,17); mm.addMarkers(gmarkersC,12,17); mm.addMarkers(gmarkersD,13,17); mm.refresh(); om.Clear(); // Clear the loading message });
42. geocoding Modifichiamo il codice HTML in modo da prevedere una FORM che utilizzeremo per chiedere all'utente di fornire un indirizzo che poi andremo a mostrare sulla mappa utilizzando le funzioni di Geocoding <div id="map" style="width: 800px; height: 600px"></div> <form onsubmit="showAddress(); return false" action="#"> <input id="search" size="60" type="text" value="" /> <input type="submit" value="Go!" /> <input type="button" onclick="javascript:map.clearOverlays();return false" value="Clear markers" /> </form> <div id="message"></div>
43. geocoding La funzione Load in questo caso sarà molto semplice e dovrà creare solamente una mappa al minimo livello di zoom Var map; function load() { if (GBrowserIsCompatible()) { map = new GMap(document.getElementById("map")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(20,0),2); } } A livello globale andiamo invece a creare l'oggetto GClientGeocoder var geo = new GClientGeocoder(); var reasons=[]; reasons[G_GEO_SUCCESS] = "OK"; reasons[G_GEO_MISSING_ADDRESS] = "Non è stato inserito l'indirizzo"; reasons[G_GEO_UNKNOWN_ADDRESS] = "Indirizzo sconosciuto"; reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Indirizzo non visualizzabile"; reasons[G_GEO_BAD_KEY] = "Errore API KEY"; reasons[G_GEO_TOO_MANY_QUERIES] = "Troppe interrogazioni"; reasons[G_GEO_SERVER_ERROR] = "Errore sul server";
44. geocoding Infine creiamo la funzione da richiamare al SUBMIT della FORM function showAddress() { var search = document.getElementById("search").value; geo.getLocations(search, function (result) { if (result.Status.code == G_GEO_SUCCESS) { document.getElementById("message").innerHTML = "trovati " +result.Placemark.length +" risultati"; for (var i=0; i<result.Placemark.length; i++) { var p = result.Placemark[i].Point.coordinates; var marker = new GMarker(new GlatLng(p[1],p[0])); document.getElementById("message").innerHTML+="<br>"+(i+1)+": "+result.Placemark[i].address+marker.getPoint(); map.addOverlay(marker); } var p = result.Placemark[0].Point.coordinates; map.setCenter(new GLatLng(p[1],p[0]),14); } else { var reason="Codice "+result.Status.code; if (reasons[result.Status.code]) { reason = reasons[result.Status.code] } alert('Impossibile trovare "'+search+ '": ' + reason); } }); }