PostGIS + Geoserver + Leaflet: mini tutorial

  • 14 October 2016
  • deinic

 

 

Questo tutorial si compone di tre parti, all'interno delle quali si vedrà in maniera più dettagliata come:
 

  1. Creare un database spaziale PostGIS

  2. Configurare Geoserver per elargire un servizio WFS

  3. Produrre il codice in Leaflet necessario alla pubblicazione del WebGIS

 

Lo scopo finale sarà la visualizzazione di una mappa di sfondo OSM e un vettoriale puntuale, fornito direttamente dal servizio WFS di Geoserver.

Prima di iniziare, una premessa necessaria. Purtroppo sul mio server personale non è possibile installare Geoserver e PostGIS, pertanto le simulazioni sono in locale sul mio PC. A fine esercitazione rimando ad un demo funzionante attraverso GeoJSON,ma che simulerà in maniera impeccabile il funzionamento di un Web Feature Service, offerto da GeoServer. Inoltre il tutto è stato eseguito sotto il sistema operativo Lubuntu v.14.04 .

Infine, ho creato qui un semplice shapefile, con due attributi, utile per il nostro articolo, che servirà, poi, per essere importato nel nostro futuro database geospaziale: Download.

 

Creazione database spaziale in PostGIS

PostGIS si presenta come l'estensione spaziale del più famoso database PostgreSQL, il quale può essere amministrato e gestito in maniera molto agevole anche attraverso l'applicativo PgAdmin III che ne fa da interfaccia grafica oppure via shell con linea di comando.
Per questioni di brevità, si è preferito l'utilizzo di PgAdmin III.

Aprendo il programma dobbiamo innanzitutto configurare il Server che contiene il nostro db. Cliccando sull'icona Add a connection to a Server a forma di spina, inseriamo i seguenti dati.

 

 

Definiamo il database d'interesse, nel nostro caso chiamato postgis

 

 

Non dimentichiamo di apporre anche il proprietario ( owner ) che nel nostro caso è postgres.

 

 

A questo punto bisogna creare l'estensione spaziale al database, ovvero dichiarare postGIS inviando comandi in SQL. Quindi esplodiamo l'albero del database postgis, clicchiamo sul public e apriamo la finestra dei comandi SQL.

 

 

Inviamo i seguenti comandi nella finestra che si aprirà, eseguendoli cliccando sul tasto play.

 

CREATE EXTENSION postgis;

 

per dare l'estensione geospaziale al db postgis. Successivamente, inviamo :

 

SELECT postgis_full_version();

 

per confermare che l'estensione sia stata aggiunta correttamente.

Una volta creato il db, dobbiamo creare uno shape file con QGIS affinché possiamo poi importarlo nel db postgis.

Lo strumento che si utilizza è SPLIT, plugin di QGIS. Questo tipo di plugin l'ho usato su una versione più datata di QGIS.

 

Se non sia ha disposizione tale strumento, è sempre possibile utilizzare da linea di comando l'applicativo shp2pgsql , navigado da terminale fin dentro la cartella del nostro shapefile ed utilizzando la seguente dicitura:

shp2pgsql -s [EPSG] [shpfile] [schema].[table] | psql -h [myserver] -d [mydb] -U [myuser]

Una volta importato il nostro shape all'interno del nostro database , possiamo verificare che tutto stia funzionando nel corretto modo attraverso QGIS. Abbiamo due modalità di verifica, o connettendoci al db importando un layer di tipo PostGIS oppure utilizzando dbManager, un plugin che permette visualizzare gli elementi geospaziali.

Quest'ultimo è utile anche se volessimo importare i nostri shapefile, in fatti dal menu Tabella ->Importa Layer/file sarà possibile importare direttamente i vettoriali nel database di riferimento.

 

 

Configurazione Geoserver per servizio WFS

Geoserver è un server open source, capace di gestire layer di differenti tipologie divisi tra raster e vettoriali. Agisce come un webserver fornendo, lato client, servizi di mappe dettati dagli standard OGC come WMS, WFS, WCS per la gestione e la visualizzazione delle mappe.

Iniziamo col dichiarare un layer di tipo PostGIS nel seguente modo.

Dopo essersi loggati, entriamo nella pagina di amministrazione di Geoserver.

 

 

Nel menu laterale andiamo a creare un Workspace, per cui Workspace - > Add new workspace , oltre al nome è possibile dare un URI fittizio, come nell'esempio:

 


 

Definiamo il nostro vettoriale, fornito dal nostro database andando in Store - > Add new Store Scegliamo un layer di tipo PostGIS.

 

 

Infine, una volta collegato il nostro db a geoserver siamo pronti per importare il nostro layer, cliccando su Layer - > Add new Layer , all'interno del quale ci appare il nostro vettoriale ( o la tabella de db) che dovrà essere, poi, pubblicata. Quindi cliccare su Publish.

 

 

Ora siamo pronti per visualizzare il nostro layer da Layer preview. Geoserver permette di visualizzare in differenti modi il singolo layer, ad esempio creando una pagina webGIS scritta in Openlayer

 

 

Ciò che è più interessante ai fini della pubblicazione in leaflet del nostro webGIS, è in che formato Geoserver elargisce le mappe per i servizi WFS o WFS. Nel nostro caso abbiamo scelto un formato di esportazione come il GeoJSON.

 

 

 

Come output otteniamo tale pagina http dove alla nostra richiesta geoserver ci fornisce l'intero JSON relativo all'intero database postgis.

 

Da notare bene l'URL dell'output geoJSON che Geoserver crea, ovvero :

 

http://localhost:8080/geoserver/nicola_gis/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=nicola_gis:buche&maxFeatures=50&outputFormat=application/json

Tale link ci servirà successivamente per richiamare da Leaflet il nostro servizio WFS.

Produzione Codice Leaflet

Qui di seguito viene riportato il codice attraverso il quale il webGIS funziona.

Nella parte <head> del nostro html inseriamo le librerie di leaflet e jquery, necessarie al funzionamento dello script javascript per sviluppare la mappa.

 

<!doctype html>

<html>

<head>

<title>Test</title>

 

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />

<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>

<script src="https://code.jquery.com/jquery-3.1.1.js" ></script>

 

<style type="text/css">

        html, body,#map {

            height: 100%;

            width: 100%

             }

</style>

</head>

 

Nel body inseriamo il nostro script con le API di leaflet.

 

<body>

<div id="map"></div>

<script>

 

Dichiariamo l'oggetto map con le option center e zoom:

 

var map = L.map('map', {

         center: [40.84603,14.26603],

         zoom: 17

    });

 

 

Passiamo alla costruzione dell'indirizzo di geoserver dove dovremmo ripescare il nostro geoJSON.

 

var owsrootUrl = 'http://localhost:8080/geoserver/nicola_gis/ows';

 

var defaultParameters = {

          service: 'WFS',

          version: '1.0.0',

          request: 'GetFeature',

          typeName: 'nicola_gis:buche',

          maxFeatures: '50',

         outputFormat: 'application/json',

};

 

var parameters = L.Util.extend(defaultParameters);

var URL = owsrootUrl + L.Util.getParamString(parameters);

 

L'ndirizzo URL ci servirà per costruire la chiamata AJAX alla pagina che contiene il nostro GeoJSON. La chiamat ajax è costruita attraverso Jquery, attraverso la quale vengono passati l'URL e una funzione di success, ovvero quale effetto deve produrre la chiamata. Nell'esempio vorremo che al click del mouse sui marker che costituiscono il nostro vettoriale, si apra un popup contenente info catturate dal geoJSON. In tal caso visualizzeremo un foto di una buca stradale e della data d'inserimento nel database.

 

$.ajax({

        url: URL,

        success: function (data) {

//create a new geojson layer

       var geojson = new L.geoJson(data, {

// apply a style

       style: {"color":"#ff7800","weight":2},

// and bind a popup showing the data and photo for each feature extracted.

  onEachFeature: function(feature, layer){

layer.bindPopup("data: " + feature.properties.data +" <img width='300px' height='150px'         src='"+feature.properties.photo+"'>");}}).addTo(map);

}

});

 

Infine qui dichiariamo  una mappa di sfondo Open Street Map.

 

var basemap0 = L.tileLayer('http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://www.opencyclemap.org">OpenCycleMap</a>,&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors,<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',maxZoom: 28});

basemap0.addTo(map);

</script>

</body>

</html>

 

 

Concludendo ho implementato una versione demo, che simula il comportamento di Geoserver e PostGIS, in modo da poter capire quale possa essere il risultato finale che abbiamo appena implementato.(1)

 

(1) Potrebbe capitare un problema di visualizzazione del layer inerente al WFS inviato da Geoserver, in tal caso bisogna abilitare i CORS headers, modificando il seguente file al seguente path var/lib/tomcat7/webapps/geoserver/WEB-INF/web.xml aggiugendo il seguente codice:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

 

Salvare il file ed eseguire un restart di Tomcat.

 

 

Italiano