Home > GIS, Open Data, Open Source, Web Mapping > OpenGeoData: come utilizzarli su una mappa? Ad esempio sfruttando il cross layer filtering di Geoserver

OpenGeoData: come utilizzarli su una mappa? Ad esempio sfruttando il cross layer filtering di Geoserver


Sempre più spesso si parla di open data e tra questi di quelli che maggiormente sono ricercati dagli utenti, vale a dire quelli georiferiti.

La disponibilità di open dati open georiferiti sta infatti pian piano aumentando come testimoniato nella recente conferenza sugli OpenGeoData tenutasi a Roma il 28 Febbraio. Gli ultimi esempi degni di nota in tale direzione sono stati la pubblicazione in modalità open data di informazioni georiferite messe a disposizione del Comune di Venezia, e da quello di Trento, mentre, ancora più recente, è la notizia relativa alla volontà di prossima pubblicazione in modalità open dei dati georiferiti della Provincia Autonoma di Bolzano.

L’aumentare della disponibilità va sicuramente a “saziare”, in parte, l’appetito di quel mondo di tecnici e appassionati che per skill personali, sanno cosa farci e come usare questi dati ma resta tutto un mondo di potenziali utenti (privati ma anche del mondo business), che, non provenendo dal mondo GIS classico o della neo-geography,  non hanno quindi dimestichezza con questa tipologia di dati e che quindi non sa bene come usarli o nemmeno, cosa peggiore, cosa si potrebbe fare per costruirci del valore aggiunto.

Resta quindi un gap da riempire, anche di conoscenza, per valorizzare questo patrimonio informativo messo liberamente a disposizione che, se non colmato, rischia di vanificare in parte il grosso sforzo che si sta facendo negli ultimi anni per rendere open data più informazioni possibili, le quali rischiano sì di uscire dal cassetto di un qualche funzionario della P.A, ma per finire, dimenticati, su un qualche portale open data che con il passare del tempo perderà di interesse.

Esempio

Lo scopo di questo post è quello di illustrare un possibile utilizzo di tali dati sfruttando le funzionalità di cross-layer filtering offerte da GeoServer.

I dati

Come dati di esempio ho utilizzato due shapefile messi a disposizione dal Comune di Torino e precisamente:

I dati sono praticamente direttamente utilizzabili: per mia comodità ho aggiunto ad entrambi i dati, visto che ne erano privi, un campo chiave univoco (KEY), numerico che ho valorizzato con un progressivo e poi ho trasformato l’SRS di riferimento adottando l’EPSG:900913. Per fare queste operazioni ho utilizzato QGIS Desktop ma sono operazioni che si possono fare con qualunque strumento GIS Desktop.

Per chi volesse replicare gli esmepi riportati in questo post i dati sono liberamente scaricabili.

Cross Layer Filtering in GeoServer

Come  ho anticipato in questo esempio ho sfruttato la funzionalità di cross-layer filtering offerte da GeoServer. Questa funzionalità permette di ricercare features di un layer (A) che abbiano una qualche relazione spaziale con features di un altro layer (B).

In generale quindi permette ad esempio di cercare tutte le stazioni di autobus (layer A)  che sono entro una certa distanza da un certo negozio (features del layer B), oppure che sono dentro un certo quartiere (layer B).

Ho utilizzato un pc Windows 7 con 4 core e 8 Gbyte di RAM con GeoServer 2.2.3 con le seguenti caratteristiche:

  • Git Revision 0fd3212ede1a8e13257ae5785cc8a752ee0a645c
  • Build Date 22-Dec-2012 15:59
  • GeoTools Version 8.5 (rev 06286dc3c15c2498aa5b3580de5df928f07d31dc)

Nello specifico l’esempio che ho implementato permette di individuare quali sono gli esercizi commerciali che sono nell’intorno di un certo indirizzo.

La funzionalità è stata implementata completamente in GeoServer quindi come funzionalità server-side esposta come WFS quindi potenzialmente fruibile da qualunque client in grado di mandare la richiesta secondo questo protocollo (con i corretti parametri ovviamente), interpretandone poi il GML ottenuto come risposta.

Ecco la chiamata POST nel caso in cui si cerchino le features del layer AttivitaCommerciali che rcadono nell’intorno di 100 metri dal numero civico identificato con la chiave 36748

<wfs:GetFeature

xmlns:wfs=”http://www.opengis.net/wfs&#8221;

xmlns:CesareWorkspace=”http://www.openplans.org/spearfish&#8221;

xmlns:ogc=”http://www.opengis.net/ogc&#8221;

service=”WFS” version=”1.0.0″>

<wfs:Query typeName=”CesareWorkspace:AttivitaCommerciali900913″>

<ogc:Filter>

<ogc:DWithin>

<ogc:PropertyName>the_geom</ogc:PropertyName>

<ogc:Function name=”collectGeometries”>

<ogc:Function name=”queryCollection”>

<ogc:Literal>CesareWorkspace:NumeriCivici900913</ogc:Literal>

<ogc:Literal>the_geom</ogc:Literal>

<ogc:Literal>KEY = 36748</ogc:Literal>

</ogc:Function>

</ogc:Function>

<ogc:Distance units=”meter”>100</ogc:Distance>

</ogc:DWithin>

</ogc:Filter>

</wfs:Query>

</wfs:GetFeature>

Il tutto lo potete eseguire dal Demo Request che trovate una classica installazione di GeoServer in

http://localhost:8080/geoserver/web/?wicket:bookmarkablePage=:org.geoserver.web.demo.DemoRequestsPage)

usando come url per l’esecuzione qualcosa di questo genere

http://localhost:8080/geoserver/CesareWorkspace/ows?

(in questo caso il mio layer si trova in un workspace denominato CesareWorkspace.

Il risultato sarà un GML con l’elenco delle features individuate dal filtro spaziale DWithin: faccio notare che nel GML sono restituite non solo le coordinate delle features ma le intere features come oggetti e quindi comprensive dei dati alfanumerici descrittivi

GMLGeoserver

Un esempio di utilizzo in OpenLayers

Per poter visualizzare questo risultato ho utilizzato OpenLayers 2.12 scrivendo una piccola applicazione web che illustra come visualizzare i dati di partenza, Numeri Civici e Attività Commerciali su sfondo OpenStreetMap e che al tempo stesso permette all’utente di selezionare un indirizzo e sulla base di questo indicare una distanza di ricerca: confermando l’operazione l’applicazione esegue una chiamata in POST verso GeoServer e ne visualizza i risultato sotto forma di VectorLayer di OpenLayers tratto dal GML di risposta.

L’intero codice dell’applicazione è scaricabile e liberamente utilizzabile. Il codice è ampiamente commentato e quindi dovrebbe essere piuttosto chiaro (ovviamente per chi conosce OpenLayers …), il suo modo di operare.

Ecco solo alcune note importanti per la sua esecuzione:

1) se Apache e GeoServer sono su server diversi o sono sullo stesso server ma rispondono su porte diverse è necessario usare un proxypass definito nell’httpd.conf di Apache. Nel mio caso Apache e GeoServer sono sullo stesso server ma Apache risponde sulla porta 80 mentre GeoServer sull’8080 e quindi nel file ci configurazione di Apache ho riportato quanto segue:

<Location /local-geoserver/>

             ProxyPass http://localhost:8080/geoserver/

             ProxyPassReverse http://localhost:8080/geoserver/

          </Location>

2) come anticipato i due layers adottano il sistema di riferimento EPSG:900913. Questa è stata una semplificazione voluta visto lo scopo didattico dell’esempio. Se si intende replicare ed adattare l’esempio con latri dati occorre tenere presente il sistema di riferimento adottato e fare le opportune modifiche

// *****************************************************************

            // ** Set up projection used                                      **

            // *****************************************************************

            var map_projection = new OpenLayers.Projection(“EPSG:900913”);           

            var map_display_projection = new OpenLayers.Projection(“EPSG:900913”);

e nella definzione del layer la riga

   projection: new OpenLayers.Projection(“EPSG:900913”) 

3) ad ogni cambio di indirizzo e/o di distanza di ricerca è necessario aggiornare la mappa ma al tempo stesso occorre anche eliminare le features precedentemente disegnate: nel mio caso ho deciso di essere un po “drastico” eliminando e ricreando i layer interessati ogni volta

// ***********************************************************************************

            // ** Remove overlay layers: I’ve to update them ….                                                                     **

            // ***********************************************************************************

            if (my_address_wfs != null) {              

               layers = map.getLayersByName(‘Indirizzo in esame’);                

               for(layerIndex = 0; layerIndex < layers.length; layerIndex++)

                  {

                 map.removeLayer(layers[layerIndex]);

                  }

            }

          

            if (my_address_wfs != null) {             

               layers = map.getLayersByName(‘Attività Commerciali vicino ad indirizzo’);                 

               for(var layerIndex = 0; layerIndex < layers.length; layerIndex++)

                  {

                 map.removeLayer(layers[layerIndex]);

                  }

            }

4) occorre considerare che la chiamata verso geoserver e la successiva elaborazione della risposta è un processo asincrono per cui si perde un po’ il controllo del flusso di esecuzione che è demandato completamente ad OpenLayers: può essere quindi un po’ complicato disegnare le features al momento giusto, effettuare i corretti zoom (le features potrebbero non ancora essere state disegnate e il layer risulta “vuoto” ….), ecc .. Nel mio caso per il layer che rappresenta il mio indirizzo in esame (my_address_wfs) ho deciso di utilizzare una strategia Fixed

strategies: [new OpenLayers.Strategy.Fixed()]

e un listener che “scatta” quando tutte le features sono state aggiunte così da poter fare, solo a quel punto, le necessarie considerazioni e azioni, nello specifico fare uno zoom all’indirizzo in esame solo se non siano state individuate attività commerciali nell’intorno dell’indirizzo stesso.

eventListeners: {

                “featuresadded”: function(event) {

                      if (theAttivitaExtent == null) {

                         this.map.zoomToExtent(this.getDataExtent());

                      }

                }

            }

Non potendo mettere a disposizione una versione live dell’esempio in oggetto eccovi un filmato di una sessione di utilizzo

(doveroso … un ringraziamento a Fabrizio C., Diego S. e Fabrizio M., in memoria dei vecchi tempi e per la pazienza ed il supporto che mi hanno dato nella realizzazione di questo esempio di fruizione in OpenLayers)

Conclusioni

Questo è solo un esempio ma illustra un principio di utilizzo che si può estendere e generalizzare, ad esempio:

  • il fatto di sfruttare una funzionalità offerta server-side da GeoServer basata su protocolli standard (WFS, GML), permette di riusare la funzionalità stessa da client diversi, sfruttando anche, in caso di necessità, la scalabilità server side offerta dal motore GIS
  • la stessa applicazione, pur didattica, sarebbe portabile su un dispositivo mobile. In questo caso la scelta dell’indirizzo potrebbe essere facilmente sostituita dalla posizione corrente dell’utente via localizzazione GPS
  • i dati messi a disposizione potrebbero essere più significativi di quelli utilizzati nell’esempio per rendere più utile l’applicazione stessa. Ad esempio localizzazione di servizi di pubblica utilità (ad esempio nel caso in cui si sia in una città che non si conosce …), offerte di business nel campo del commercio (quali negozi offrono quali opportunità nell’intorno di un indirizzo o posizione … ), micro-marketing (caratteristiche dell’utenza nell’intorno di un indirizzo o in un’area), ecc ..
  • utilizzo di altre tipologie di filtro spaziale
  1. Non c'è ancora nessun commento.
  1. No trackbacks yet.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: