Tempo fa scrissi un articolo su ArcGIS Server 9.3 soffermandomi sui servizi REST e le API Javascript ed accennando al fatto che ESRI mette a disposizione delle estensioni per le API di Google Maps e per quelle di Bing Maps.
Ultimamente ho lavorato un po’ con le prime e ne ho avuto complessivamente una buona impressione. Tuttavia, durante lo sviluppo, ho riscontrato un problema nella misurazione delle distanze e delle aree che merita di essere messo in evidenza, soprattutto perché gli esempi della documentazione ESRI non lo fanno a dovere ed anzi, secondo me, risultano leggermente fuorvianti.
Terminata la premessa, prima di andare avanti con l’articolo, voglio ringraziare Domenico Ciavarella, che mi ha dato un supporto fondamentale per arrivare ad una soluzione che altrimenti starei ancora cercando.
La proiezione di Google Maps
Google Maps, Bing Maps ed altri provider (come OpenStreetMap, Yahoo e, di recente, la stessa ESRI) utilizzano una proiezione nota come Spherical Mercator, derivata dalla proiezione di Mercatore. Il codice EPSG ufficiale è 3785, anche se prima della sua definizione molti software hanno utilizzato l’ufficioso 900913. L’identificativo per i software ESRI, tra cui ovviamente ArcGIS Server, è invece 102113.
Questa proiezione considera la Terra come una sfera e consente di includerne completamente la superficie all’interno di un quadrato.
Quando però si rappresenta una superficie curva su di un piano, come un foglio di carta o il monitor di un computer, si introducono delle deformazioni. In questo caso, man mano che ci si allontana dall’equatore le aree cartografate subiscono un pesante stiramento sia in senso verticale che orizzontale e diventano, quindi, via via più esagerate verso i poli (la Groenlandia, per esempio, sembra più grande dell’Africa). Questa proiezione evidentemente non è fatta per minimizzare la deformazione delle aree (la proiezione di Mercatore è conforme infatti), ma risulta vantaggiosa per l’uso attraverso il web perché consente di applicare un modello efficiente di tassellamento e caching.
Il problema…
Ammettiamo di voler creare un’applicazione di webmapping con le sopracitate estensioni delle API Javascript di ArcGIS Server per Google Maps.
La prima cosa da fare è creare un mapservice in grado di esporre i nostri dati spaziali con la medesima proiezione delle basi cartografiche di Google. Come spiegato nel post dedicato ad ArcGIS Server (linkato all’inizio di questo articolo) un mapservice “aggancia” e pubblica un progetto redatto in ArcMap (il classico .mxd), quindi basta assegnare al dataframe del progetto il sistema di riferimento appropriato (che si trova nella lista dei sistemi proiettati, alla voce WGS 84 Web Mercator, con identificativo 102113), salvare il tutto e pubblicarlo con ArcGIS Server. Niente di difficile insomma.
Focalizziamoci ora sullo sviluppo del client: tra i tanti strumenti che oggi ci si aspetta di trovare in una applicazione WebGIS ci sono i “righelli” che consentono di disegnare spezzate e poligoni e di misurarne poi lunghezza ed area. ESRI lo sa, ed ha giustamente incluso un esempio per mostrare come creare questi tool nella documentazione delle sue API.
Abbiamo detto però che l’uso della proiezione Spherical Mercator provoca una deformazione crescente man mano che ci si spinge verso i poli e, tracciando una spezzata per misurare un oggetto al suolo di dimensioni note, come uno stadio di calcio, ci si accorge dell’inghippo: è più lungo di quanto dovrebbe essere (circa 146 metri invece di 105-110).
L’esempio fornito da ESRI non considera la deformazione e può indurre gli sviluppatori all’errore. E’ vero che una persona con le adeguate conoscenze di geomatica può arrivare ad intuire il rischio insito nell’uso della proiezione di Google, ma è anche vero che il webmapping è terra di confine tra “gissologi” e sviluppatori informatici “puri”, senza particolari cognizioni tipiche del mondo gis. Non è per nulla detto, quindi, che chi sviluppa abbia i mezzi per immaginare il problema prima di averci sbattuto il muso e personalmente credo che aver pubblicato un esempio del genere nella documentazione ufficiale, senza neanche accennare alla questione della deformazione, sia stata una leggerezza.
…e la soluzione
Non molto tempo fa sul blog di ArcGIS Server è comparso un interessante post che mette in evidenza il problema della misurazione delle distanze e spiega come comportarsi per risolverlo.
Il servizio che in ArcGIS Server è incaricato di calcolare lunghezze ed aree, il Geometry Service, è in grado di svolgere diverse altre operazioni, tra cui la proiezione al volo delle geometrie.
Il “trucco” consiste nel riproiettare la geometria tracciata dall’utente nel sistema di riferimento più adatto alla zona mappata prima di effettuarne la misurazione e stampare a schermo il risultato.
Purtroppo lo snippet di codice fornito da ESRI è pronto all’uso solo per le API Javascript, mentre per le estensioni di Google Maps bisogna fare da soli e il discorso è un po’ meno semplice.
Al posto di questa funzione:
var sr = new esri.SpatialReference({wkid:32610}); geometryService.project([graphic], sr, function(projectedGraphic) { geometryService.areasAndLengths(projectedGraphic, function(result) { var perimeter = result.lengths[0]; var area = result.areas[0]; }); });
abbiamo bisogno di questa:
var geometryService = new esri.arcgis.gmaps.Geometry("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); function calculateLengths() { //Parametri per la riproiezione var params = new esri.arcgis.gmaps.ProjectParameters(); params.geometries = [polyline]; params.inSpatialReference = 4326; params.outSpatialReference = 3004; //Gauss-Boaga fuso Est //Riproiezione e funzione di callback geometryService.project(params, getLengths); } function getLengths(projectResults){ var url = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer/lengths"; var parameters = { polylines: projectResults.geometries, sr: 3004 }; esri.arcgis.gmaps.JSONRequest(url, test, parameters); } function test(result) { alert(result.lengths[0]+" m"); }
Ho realizzato un veloce esempio che mostra i risultati ottenuti dal codice proposto da ESRI nella propria documentazione a confronto con quelli ottenuti dalla riproiezione con il Geometry Service e dalle semplici API di Google Maps, che hanno dei metodi propri per la misura di linee e poligoni.
I contenuti potrebbero non essere più adeguati ai tempi!
By Andrea Borruso on mag 1, 2010
Ale,
un altro post che parla di questo tema:
http://geographika.co.uk/watch-out-for-openlayer-distances
Sbaglio a preferire il termine web-mapping a web-gis?
Questo tuo contributo è di grande utilità.
Ciao,
a
By Alessio on mag 1, 2010
Non sbagli.
Sbaglio io quando certe volte utilizzo i due termini come se fossero dei sinonimi.
Penso che la scelta dell’uno o dell’altro dovrebbe essere basata sulle funzionalità offerte all’utente.
Un applicativo in grado di eseguire operazioni di analisi spaziale (es:buffer) o query con operatori spaziali è un WebGIS, mentre uno che mostra di una serie di eventi o tematismi, senza grandi possibilità di interagire con quanto mostrato, rientra nella definizione di webmapping.
Questa è la mia opinione ovviamente… ed ammetto di non essermi documentato chissà quanto sulla specifica questione
PS
grazie per la segnalazione dell’articolo che parla di OL
By Domenico Ciavarella on mag 2, 2010
Volevo fare una precisazione riprendendo un commento di Melita Kennedy (ESRI).
La tempistica ha caratterizzato la definizione di ‘Web Mercator’. L’EPSG aveva aggiunto, nel marzo 2008, il ‘Popular Visualisation CRS / Mercator’ con il codice 3785. Questo è stato deprecato e sostituito con il codice 3857 (WGS 84 / Pseudo-Mercator). Nel frattempo, ESRI aggiunse il 102113, ‘WGS 1984 Web Mercator’, la cui definizione è molto simile al 3785. In seguito venne aggiunto anche il 102100, (WGS 1984 Web Mercator Auxiliary Sphere) la cui definizione è simile al 3857. Ai tempi della 9.3, non era corretto cambiare l’originale 102113 in 3785, e la sostituzione, 3857, non era ancora stata rilasciata.
Per ArcGIS 10, il 102100 cambierà in 3857, dal momento che si equivalgono.
Il vantaggio nell’usare la 102100 (3857) sta nel fatto che il datum è un WGS84 e quindi, se utilizziamo una proiezione ad esempio UTMWGS84, non abbiamo trasformazioni di datum rispetto alla 102113.
By Alessio Di Lorenzo on mag 2, 2010
Ciao Domenico,
avevo letto anche io di questa novità in ArcGIS 10 ma l’avevo esclusa dal post per “facilità di lettura”. Grazie per l’utile precisazione