Come prima cosa vorrei ringraziare Andrea per avermi dato la possibilità di contribuire, nel mio piccolo, a TANTO, scusandomi con lui per tutto il tempo (davvero troppo) passato da quando gli ho promesso questo tutorial ad oggi!
In questo breve articolo-tutorial cercherò di fare una panoramica sulla componente client di MapFish, un framework open source basato su ExtJs e OpenLayers, grazie al quale è possibile realizzare delle applicazioni webgis in pieno stile web 2.0 con poco sforzo una volta compreso il funzionamento degli “ingranaggi”.
Innanzitutto va detto che la parte relativa al mapping vero e proprio può essere gestita esattamente come in OpenLayers che, come già ricordato, è compreso all’interno di MapFish.
Si ha quindi a disposizione tutta la flessibilità di OpenLayers (layer WMS, WFS, Google, Yahoo, ecc.) e se si sanno già realizzare mappe online con questa ottima libreria, il passaggio a MapFish consiste semplicemente nel comprendere come gestire layout ed eventi alla maniera di ExtJs (l’altra componente del framework) e nello scoprire gli utili widget che MapFish mette a disposizione dello sviluppatore.
L’utilizzo di questi widget è simile a quello dei controlli di OpenLayers, con la differenza che in questo caso viene sfruttata la potenza di ExtJs per aggiungere un’interfaccia utente avanzata al controllo. I widget che necessitano del solo codice lato client sono:
- Toolbar – una barra degli strumenti con dei tasti preimpostati (full-extent, pan, zoombox, zoom out) che è possibile espandere con nuovi bottoni sapendosi muovere un minimo con OL;
- Layer Tree – si tratta di una “toc”, simile al layer switcher di OL, ma molto più configurabile, con la possibilità di includere facilmente icone e di annidare e raggruppare i layer a proprio piacimento;
- Scorciatoie – liste a discesa con possibilità di autocompletamento del testo inserito (come avviene in Google suggest, per capirci) che centrano la mappa sulle coordinate corrispondenti al luogo/elemento scelto;
- Stampa – un semplice controllo da includere per stampare la porzione di mappa visualizzata.
Affinché gli altri widget di MapFish (stampa complessa, ricerca nel db, ecc.) funzionino, è necessario che sia installata la componente server del framework che, però, non tratteremo in questo articolo (anche perché, non avendoci mai lavorato, rischierei di scrivere una montagna di cavolate!).
ExtJs semplifica la creazione di layout, anche molto complessi, che risultano accattivanti per l’utente e cross-browser. Con poche righe di codice è possibile creare interfacce a schede (tab), menu accordion, form avanzati, ecc… avendo la sicurezza che l’applicazione verrà correttamente visualizzata su tutti i browser più diffusi in circolazione. Con ExtJs possiamo ottenere rapidamente delle belle GUI in cui “infilare” le nostre applicazioni webgis. Insomma, sono assicurati un risultato di tutto rispetto e un bel risparmio di diottrie e bile (è risaputo che quella di rendere cross-browser delle appicazioni web “complesse” sia una delle attività che più contribuiscono alla creazione di nuovi tipi di imprecazioni… ).
Fatta questa introduzione, passiamo al tutorial vero e proprio!
Tutorial MapFish
Creeremo una semplice applicazione webgis, munita di una toolbar e di un layer tree, con cui sarà possibile visualizzare la localizzazione degli utenti GRASS su due mappe di base alternative.
Le informazioni che mostreremo provengono da diversi server WMS (Nasa, Metacarta, Grass).
Utilizzeremo la versione 1.1 del framework MapFish, scaricabile da qui come archivio compresso in formato tar.gz (se state lavorando in ambiente Windows, vi consiglio di procurarvi l’ottimo 7zip per estrarne il contenuto).
Il primo passaggio consiste ovviamente nello scompattare quanto abbiamo scaricato in modo da ottenere una cartella (MapFish-1.1) che contiene tutto il necessario per creare la nostra applicazione d’esempio.
Utilizzando la sola parte client non abbiamo bisogno di rendere visibile il tutto ad un eventuale webserver e possiamo posizionare la directory di cui sopra dove più ci aggrada nel filesystem…
Tuttavia, per mantenere un certo ordine, consiglio di creare una ulteriore cartella, che chiameremo “EsempioMF”, e di lavorare al suo interno.
Creiamo anche un file index.html, un file myMapFish.js e spostiamo anche loro nella cartella di lavoro “EsempioMF”.
A questo punto, quindi, la situazione dovrebbe essere la seguente:
EsempioMF
|
– MapFish-1.1
|
– index.html
|
– myMapfish.js
Ora che siamo organizzati in modo più o meno ordinato, è il momento di riempire il file index.html.
Ecco come:
<html> <head> <title>Esempio MapFish by TANTO</title> <!-- link ai CSS della componente ExtJS (è possibile scaricare temi dal sito di extjs e sostituire default.css con il foglio di stile del tema scaricato... ce ne sono un paio che meritano) --> <link rel="stylesheet" type="text/css" href="MapFish-1.1/client/mfbase/ext/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="MapFish-1.1/client/mfbase/ext/resources/css/default.css" /> <!-- Inserisco i riferimenti agli script Javascript necessari al funzionamento del framework MapFish --> <script type="text/javascript" src="MapFish-1.1/client/mfbase/openlayers/lib/OpenLayers.js"></script> <script type="text/javascript" src="MapFish-1.1/client/mfbase/ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="MapFish-1.1/client/mfbase/ext/ext-all.js"></script> <script type="text/javascript" src="MapFish-1.1/client/mfbase/mapfish/MapFish.js"></script> <!-- Inserisco il riferimento allo script Javascript myMapFish.js --> <script type="text/javascript" src="myMapFish.js"></script> </head> <body> <!-- Nel body creo i div che faranno da contenitori per la mappa vera e propria, per la toolbar e per il layer tree --> <div id="map"></div> <div id="buttonbar"></div> <div id="tree"></div> </body> </html>
I commenti indicano cosa è stato inserito nell’header.Quindi possiamo chiudere index.html e iniziare a lavorare sullo script myMapFish.js.
Questo script conterrà due porzioni ben distinte:
- la prima servirà a definire il layout dell’applicazione (codice ExtJs);
- la seconda definirà la mappa vera e propria (codice OpenLayers) ed i widget MapFish che utilizzeremo.
Cominciamo, quindi, dalla prima parte dello script ed inseriamo quanto segue:
//Layout dell'applicazione //************************ Ext.onReady(function() { new Ext.Viewport({ layout:'border', items:[{ region:'north', margins:'4 4 4 4', height: 63, html: '<img src="http://blog.spaziogis.it/wp-content/themes/blacknwhite/blacknwhite/images/TANTO_logo.png"/>', bodyStyle:'padding:2px;' },{ region:'center', layout:'border', margins:'0 4 4 4', items:[{ region:'north', border:false, contentEl:'buttonbar', height:26 },{ region:'center', contentEl:'map', border:false }] },{ title:'Layer tree', region:'east', margins:'0 4 4 0', width:350, contentEl:'tree', collapsible:true },{ region:'south', margins:'0 4 4 4', height:20, html:'Esempio realizzato per TANTO', bodyStyle:'padding:2px;font-size:12px;font-family:tahoma,arial,helvetica' }] }); });
questa porzione di codice definisce completamente la webgui, non c’è bisogno di altro.
In sintesi, dopo aver inizializzato ExtJs con il metodo Ext.onReady, abbiamo creato un oggetto Viewport per dire ad ExtJs di utilizzare tutta la finestra del browser (dimenticavo… vogliamo che la nostra applicazione sia a tutto schermo ) e poi abbiamo inserito un layout di tipo ‘border’ all’interndo del quale (nel pannello ‘center’) abbiamo annidato un secondo layout dello stesso tipo.
Ogni layout di tipo border può contenere 5 panneli (‘region’), detti north, center, east, west, south. Di questi solo ‘center’ è obbligatorio.
Ad ogni modo vi rimando all’esplorazione del sito di ExtJs per scoprire come complicare a piacimento i vostri layout. Il sito è molto ben fatto, pieno di tutorial ed esempi.
Passiamo ora alla mappa e ai mapfish widget.
Sempre all’interno del file myMapFish.js inseriamo questo pezzo di codice sotto al precedente:
//Mappa e Widget //************************ function initMap(){ //Creo la mappa e definisco alcuni controlli di base var map = new OpenLayers.Map('map',{controls:[ new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanZoomBar() ]}); //Definisco l'extent che utilizzerò come vista iniziale var bounds = new OpenLayers.Bounds(5,36,21,50); //Definisco i layer WMS, due di base (alternativi) e uno di overlay var jpl_wms = new OpenLayers.Layer.WMS("NASA_Global_Mosaic", "http://t1.hypercube.telascience.org/cgi-bin/landsat7",{layers: "landsat7"}); var ol_wms = new OpenLayers.Layer.WMS("OpenLayers_WMS", "http://labs.metacarta.com/wms/vmap0",{layers: 'basic'}); var grass_users = new OpenLayers.Layer.WMS.Untiled("Utenti_grass", "http://mapserver.gdf-hannover.de/cgi-bin/grassuserwms?", {layers: 'GRASS-Users',transparent:true, format:'image/png'}, {isBaseLayer:false}); //Aggiungo i layer alla mappa map.addLayers([jpl_wms,ol_wms,grass_users]); //Aggiungo il toolbar widget di MapFish: //************************************** //Creo la toolbar var toolbar = new mapfish.widgets.toolbar.Toolbar({map: map, configurable:true}); //Scelgo di renderizzare la toolbar in un div con id = buttonbar toolbar.render('buttonbar'); //Aggiungo i bottoni/controlli toolbar.addControl(new OpenLayers.Control.ZoomBox(), {iconCls: 'zoomin',toggleGroup: 'map'}); toolbar.addControl(new OpenLayers.Control.ZoomOut(), {iconCls: 'zoomout',toggleGroup: 'map'}); toolbar.addControl(new OpenLayers.Control.DragPan({isDefault: true}),{iconCls: 'pan', toggleGroup: 'map'}); //Attivo la toolbar toolbar.activate(); //Layer tree //*************************************** //Creo un modello per il layer tree, distribuendo i layer in due nodi espandibili distinti (Mappe di base e Overlay) var model = [{ text: "Mappe di base", expanded: true, children: [{ checked:true, text:"Nasa Global Mosaic", layerName:"NASA_Global_Mosaic" },{ checked:false, text:"OpenLayers WMS", layerName:"OpenLayers_WMS" }]},{ text: "Overlay", expanded: true, children: [{ checked:false, text:"Utenti GRASS", layerName:"Utenti_grass" }] }]; //Inserisco il widget vero e proprio indicando var tree = new mapfish.widgets.LayerTree({ map: map, el: 'tree', model: model, border:false, autoHeight:true }); tree.render(); //Centro la mappa sull'extent definito in precedenza map.zoomToExtent(bounds); } //fine della funzione init()
Anche qui i commenti dovrebbero essere abbastanza chiari.
Abbiamo creato una mappa esattamente come se stessimo lavorando con buon vecchio OpenLayers e, in più, abbiamo inserito nel codice due MapFish widget.
Prima di vedere il risultato del nostro lavoro dobbiamo fare due piccole modifica al file index.html:
- inserire un evento onload a livello del tag per fare in modo che la mappa venga caricata all’apertura della pagina (esattamente come in OL);
- inseire alcune regole CSS necessarie per la corretta visualizzazione dei MapFish widget
Ecco come deve apparire index.html modificato a dovere:
<html> <head> <title>Esempio MapFish by TANTO</title> <!-- link ai CSS della componente ExtJS (è possibile scaricare temi dal sito di extjs e sostituire default.css con il foglio di stile del tema scaricato... ce ne sono un paio che meritano) --> <link rel="stylesheet" type="text/css" href="MapFish-1.1/client/mfbase/ext/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="MapFish-1.1/client/mfbase/ext/resources/css/default.css" /> <!-- Inserisco i riferimenti agli script Javascript necessari al funzionamento del framework MapFish --> <script type="text/javascript" src="MapFish-1.1/client/mfbase/openlayers/lib/OpenLayers.js"></script> <script type="text/javascript" src="MapFish-1.1/client/mfbase/ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="MapFish-1.1/client/mfbase/ext/ext-all.js"></script> <script type="text/javascript" src="MapFish-1.1/client/mfbase/mapfish/MapFish.js"></script> <!-- Inserisco il riferimento allo script Javascript myMapFish.js --> <script type="text/javascript" src="myMapFish.js"></script> </head> <body onload="initMap()"> <!-- Nel body creo i div che faranno da contenitori per la mappa vera e propria, per la toolbar e per il layer tree --> <div id="map"></div> <div id="buttonbar"></div> <div id="tree"></div> </body> </html> <style type="text/css"> /* Icone dei bottoni della toolbar */ .zoomin { background-image:url(MapFish-1.1/client/mfbase/mapfish/img/icon_zoomin.png) !important; height:20px !important; width:20px !important; } .zoomout { background-image:url(MapFish-1.1/client/mfbase/mapfish/img/icon_zoomout.png) !important; height:20px !important; width:20px !important; } .pan { background-image:url(MapFish-1.1/client/mfbase/mapfish/img/icon_pan.png) !important; height:20px !important; width:20px !important; } /* Dimensioni del Layer tree */ #tree { height: 100%; width: 100%; } </style>
Adesso apriamo index.html col borwser e il risultato dovrebbe essere questo.
I contenuti potrebbero non essere più adeguati ai tempi!
By Giovanni on apr 27, 2009
Un ringraziamento di cuore agli amici e colleghi Andrea e Alessio. Un ottimo articolo e, cosa rara, in italiano!
Spero sia uno spunto per ridare slancio alla condivisione di pratiche, competenze ed idee tra la rete di professionisti del settore GIS in Italia…
By Andrea Borruso on apr 27, 2009
Caro Giovanni,
noi di TANTO, non scherzo, ci ripetiamo spesso questa frase:
http://bit.ly/13z7vR
Grazie a te per essere passato, e per avermi messo in una categoria speciale. Il tuo grazie lo passo però tutto ad Alessio.
Credo altresì che in questo spazio, siano stati già fatti altri sforzi nella direzione da te auspicata. Non lo dico polemicamente, ma per “giustezza”.
E’ bello che tu abbia lasciato una traccia; ci fa sentire più comunità. Questo blog ha avuto le sue 7000 pagine visualizzate negli ultimi 30 giorni, ma pochissimi feedback diretti. E’ solo demerito nostro, o è anche questo un sintomo della poca voglia di “condividere pratiche, competenze ed idee” nella rete di professionisti del settore GIS in Italia?
un abbraccio,
a
By Giovanni on apr 27, 2009
Chiedo scusa per essermi dimenticato di ringraziare tutto TANTO. E’ la mia prima “traccia”, ma lo seguo ormai da tempo, e devo dire che questo articolo non fa altro che confermarne la qualità… Quindi colgo la scusa di questo articolo per augurare a TANTO e alla sua comunità di continuare, e crescere, in questa direzione.
By Alessio on apr 27, 2009
Colleghi???!!! Ma la smettete di darmi del geologo!!?
(più che altro è un’offesa per i geologi… )
Scherzi a parte il commento di Giovanni mi fa grande piacere! E il ringraziamento lo condivido volentieri con Andrea
Ne parlavamo qualche giorno fa in chat del fatto che i contatti sono abbastanza numerosi ma i commenti al momento sono pochini. Io spero che crescano perché da un commento può nascere l’occasione per ragionare su un’idea o magari, grazie ad una critica, ci si accorge di aver scritto qualche cavolata… e ci si precipita a correggere per evitare magre figure…
By Andrea Borruso on apr 27, 2009
Ma vi ha fatto così schifo il riferimento cinefilo?
By Antonio Falciano on apr 28, 2009
Ragazzi,
volevo complimentarvi con tutti voi per l’ennesimo contenuto interessante di questo blog. Anche la citazione da Pulp Fiction non è da meno! ROTFL
Scherzi a parte, a mio avviso, TANTO è il miglior blog che si occupa di informazione geografica in Italia.
Ancora una volta complimenti! Continuate così!!!
ciao
Antonio
By Andrea Borruso on apr 28, 2009
Antonio,
grazie mille. Citerei ancora una volta Mr. Wolf, ma non vorrei che tu “Rolling On the Floor” (maledetti acronimi)
Grazie per avere lasciato un segno, è un vero piacere sapere che apprezzi il lavoro che facciamo.
ciao,
a
By Pietro Blu Giandonato on apr 28, 2009
E scomodiamo ancora Mr. Wolf, tanto ormai io e Andrea abbiamo fondato la sezione italiana dell’associazione FIPAV, che ovviamente non è la ben più nobile Federazione Italiana di Pallavolo, ma un esclusivo club (non più di 2/3 soci sennò non avrebbe più senso) di “autoestimatori”. Presidente onorario è, naturalmente, l’esimio Mr. Wolf…
Comunque, sono aperte le iscrizioni.
Ad maiora ragazzi!
By Forghetti Claudio on ago 11, 2009
Complimenti a parte…ho seguito alla lettera le istruzioni del tutorial ma quando provo ad aprire la “index.html” ci sono evidenti problemi.Pagina bianca.Il codice dell’esempio non funziona…
By Forghetti Claudio on ago 11, 2009
cioè…mi spiego meglio:
1- creazione directory “esempioMF”
2- scompattamento e copia della cartella “MapFish-1.1″ all’interno della directory “esempioMF”
3- creazione del file “index.html” e conseguente scrittura del file copiando ed incollando quanto riportato da Alessio
4- creazione del file “myMapfish.js” e conseguente scrittura del file copiando ed incollando quanto riportato da Alessio.
Ho verificato che tutti i path all’interno del codice puntino alle cartelle giuste ma
quando provo ad aprire la pagina index.html nel browser mi appare una bella pagina bianca.
non sono un esperto di programmazione, ma nemmeno un nubbo completo…potrebbe qualcuno verificare la bontà del codice pubblicato?grazie
By Alessio on ago 11, 2009
Mi sembra strano.
A me l’esempio si vede perfettamente su FF, IE, Chrome, ecc.
Se usi IE probabilmente è il browser che ti blocca il “contenuto attivo” della pagina. Clicca sulla banda gialla in alto e consentine l’esecuzione.
In caso non si tratti di questo, verifica di aver copiato bene tutto il codice.
Un tag non chiuso nell’html o una virgola di troppo nel js possono causare problemi.
By Alessio on ago 11, 2009
Ho appena verificato ricostruendo l’applicazione funzionante seguendo passo passo il tutoria e facendo copia e incolla del codice dall’articolo.
Confermo che funziona.
C’è solo il solito IE che tenta di bloccare l’esecuzione del javascript, ma è normalissimo. Consenti e sei a posto (ancora meglio, evita IE )
Ciao
By enrico on ott 30, 2009
Ho trovato molto interessanti gli articoli inerenti ad Openstreetmap, e openlayer, sto cercando di capire anche Mapfish.
Vorrei farti una domanda se possibile,
Io utilizzo Arcmap 9.2 della Esri, e vorrei imparare a pubblicare una mappa con il sistema di openlayer, o di mapfish, vorrei sapere :
1. se posso utilizzare così come sono o devo convertire i dati puntuali o lineari che ho già in formato shapefile
2. eventualemente se c’è un modo (solo php?) per rendere protetti i dati puntuali o lineari inseriti.
Grazie
Enrico
By Alessio on ott 30, 2009
Ciao Enrico,
Openlayers è “solo” un client e per utilizzarlo per pubblicare i tuoi shape hai bisogno di un mapserver (umn-mapserver o geoserver per esempio) che ti generi un servizio WMS o WFS.
Volendo hai anche una strada più rapida: convertire i tuoi shape in kml ed utilizzarli direttamente indicando ad openlayers la loro posizione sul disco.
Qui c’è un esempio molto semplice.
Per la sicurezza dei dati questo sicuramente non è l’approccio migliore. Sarebbe meglio importare i tuoi shape in un db postgis, passare da un mapserver e generare un servizio wms che richieda l’autenticazione e che venga mostrato da openlayers su una pagina web.
Scusami la risposta un po’ generica, ma l’argomento è piuttosto ampio.
By enrico on ott 30, 2009
Si scusate, la domanda era posta male(per non dire stupida!!!), ho già creato mappe con googlemaps collegate a file kmz posizionati sul server del nostro sito web… so dell’esistenza di mapserver, devo solo approfondire la sua conoscenza e metterlo nel frullatore con openlayers, mapfish e dargli una spruzzata di jquery per rendere il tutto accattivante!!!
By Attilio on feb 8, 2012
Salve,
ho trovato molto interessante questo articolo. Ho realizzato il mio web gis adattandolo alle mie esigenze. Ora vorrei aggiungere alcune funzionalità, come ad esempio quella per interrogare i layer cliccando su un punto della mappa.
Ho visto alcuni esempi su internet ma non riesco a ottenere ciò che voglio. Sto utilizzando degli shape su postgis e geoserver.
Sapete aiutarmi?
Grazie.
By Alessio on feb 9, 2012
Salve Attilio,
grazie per l’apprezzamento sull’articolo.
L’interrogazione di un layer può essere ottenuta in moltissimi modi che dipendono dalla “forma” in cui quel layer arriva sulla tua applicazione client. E’ un vettoriale? Un wms? Altro…?
Ci sono anche casi in cui è conveniente prelevare i parametri dalla mappa (extent d un box, coordinate, ecc.) e interrogare il layer direttamente sul db, senza passare da geoserver, via ajax (usando php/java/asp/python/altro come backend).
Quindi, vista la quantità di variabili in gioco, è difficile rispondere alla tua domanda con gli elementi che hai fornito.
In ogni caso, come abbiamo spesso ricordato noi di TANTO, preferiamo non usare i commenti come supporto tecnico.
Se hai bisogno di questo tipo di aiuto la via migliore è servirti delle mailing list dei software che stai utilizzando.
http://osgeo-org.1560.n6.nabble.com/OpenLayers-Users-f3910695.html
http://osgeo-org.1560.n6.nabble.com/GeoServer-User-f3786390.html
http://postgis.refractions.net/support/
Saluti
By PASQUALINO on mag 24, 2014
Ciao,
intanto grazie; tutto è chiaro, ma purtroppo rimane sempre un grande dilemma installare il framework: sono mille cartelle, mille files, non riesco a sistemare nulla, e sono sempre schiavo dei colleghi informatici anche per queste fesserie (installazione). Di nuovo grazie