Layer e sorgenti

In OpenLayers gli strati geografici vengono gestiti tramite oggetti di tipo ol.layer.Layer. Concretamente però non utilizziamo questo oggetto ma le varie classi derivate, ognuna specializzata nella gestione di strati raster, immagini, vettoriali, tile, ecc. I tipi di layer più comunemente usati sono:

  • ol.layer.Image, per l’impiego di immagini statiche o servite da server, come nel caso di servizi OGC WMS
  • ol.layer.Tile, per la definizione di strati con immagini “tilizzate” (tasselli), come nel caso di servizi OSM, Bing, Mapbox, o anche WMS, nel caso si vogliano interrogare a tile
  • ol.layer.Vector , per gli strati di tipo vettoriale

Oltre a questi tre ne esistono altri più specifici che non andremo ad analizzare. Nelle prossime lezioni approfondimento l’utilizzo di questi tre tipi di layer, ma intanto anticipiamo un concetto strettamente legato ai layer, e presente in ogni tipo di strato: le sorgenti.

Ogni strato ha bisogno di sapere da dove, e come recuperare i dati da rappresentare in mappa. In alcuni contesti gli oggetti dedicati a fornire l’accesso ai dati vengono detti “provider”. In OL si chiamano sources. Quando istanziamo un layer di qualsiasi tipo è necessario passargli anche l’oggetto di tipo ol.source.Source con cui dovrà dialogare per ottenere i dati. Per ogni tipo di sorgente a cui OL è in grado di accedere esiste un oggetto specializzato, che saprà cosa fare per recuperare e fornire i dati richiesti (in base a diverse strategie di cui parleremo in seguito).

I principali tipi di sorgenti usate nel corso sono:

  • ol.source.ImageWMS, per utilizzare servizi OGC WMS
  • ol.source.XYZ, per usare servizi con tile prerenderizzati e suddivisi per livello (z) e coordinate tile (x, y)
  • ol.source.OSM, un ol.source.XYZ preconfigurato per l’accesso ai servizi OpenStreetMap
  • ol.source.Vector, per l’impiego di sorgenti vettoriali, gestiti poi tramite oggetti ol.format di cui parleremo ampiamente

Ci sono poi sorgenti specializzate per l’utlizzo di sorgenti MVT (Mapbox Vector Tiles), dei servizi Bing, CartoDB, Stamen, ecc. Una sorgente un po’ particolare è ol.source.Zoomify che permette di utilizzare OL come visualizzatore di grandi immagini fotografiche, non georiferite, secondo il formato di Zoomify.

Configurazioni di un layer

I principali parametri di configurazione di un layer sono la proiezione, la visibilità, l’opacità e i limiti di scala di visualizzazione. Se non specificati vengono assegnati dei valori di default: proiezione della mappa a cui viene aggiunto il layer, visibilità attiva, opacità massima e visualizzazione ad ogni scala.

var ortofoto = new ol.layer.Image({
  source: sorgente,
  projection: ol.proj.Projection("EPSG:3003", // associo il SR Gauss Boaga Ovest,
  visible: true, // se il layer è visibile o no
  opacity: 0.5, // valore [0-1] che indica il livello di opacità
  maxResolution: 200, // risoluzione massima di visualizzazione
  minResolution: 0 // risoluzione minima di visualizzazione
});

NB Sebbene OL offra gli strumenti per poter riproiettare al volo layer vettoriali e raster, ognuno con le proprie modalità, è sempre opportuno, soprattutto per le immagini, utilizzare layer con SR congruente con quello della mappa, in modo da non sovraccaricare eccessivamente il lavoro che deve effettuare il browser e migliorare le performance generali del client. È anche per questo motivo che di default OL associa al layer, se non indicato diversamente, la stessa proiezione della mappa.

Ogni proprietà di inizializzazione degli oggetti di OL può essere alterata e ottenuta tramite i relativi metodi esposti dall’API dell’oggetto. Generalmente i metodi per ottenere e definire il valore di una proprietà xxx di un oggetto sono oggetto.getXxx e oggetto.setXxx (prima lettera del nome della proprietà in maiuscolo).

Qui sotto potete vedere un esempio in azione, nel quale:

  • modifichiamo una proprietà di ol.View a sua volta ottenuta da ol.Map
  • modifichiamo due proprietà del nostro ol.layer.Image ortofoto.
map.getView().setZoom(17); // ottengo la ol.View della mappa e setto il nuovo livello di zoom
ortofoto.setOpacity(0.5); // setto un'opacità del 50%
ortofoto.setMaxResolution(19); // imposto la risoluzione massima (livello di zoom 19) entro la quale limitare la rappresentazione del layer

Ordinamento dei layer nella mappa

Come in ogni software grafico e GIS l’ordine di rappresentazione dei layer è un elemento fondamentale per la corretta visualizzazione dei loro contenuti. La logica è semplice:

  • le basi cartografiche di sfondo, come ad esempio uno strato OpenStreetMap o l’ombreggiatura di un DTM, stanno nella posizione più bassa della pila di layers
  • gli strati contenenti elementi poligonali stanno al di sotto di quelli contenenti elementi lineari
  • gli strati con elementi lineari stanno al di sotto di quelli contenenti elementi puntuali


Pila dei layer


Ipotizzando di avere i quattro layer dell’immagine, il loro inserimento in mappa può essere fatto almeno in tre modi:

  • aggiunta dei layer in fase di inizializzazione della mappa in forma di array, ordinato dal layer da posizionare più in basso a quello da posizionare più in alto nella pila.
    var map = new ol.Map({
      layers: [osm, poligoni, linee, punti]
    });
    
  • aggiunti uno per uno.
    map.addLayer(osm);
    map.addLayer(poligoni);
    map.addLayer(linee);
    map.addLayer(punti);
    
  • aggiunti tutti insieme in un secono momento come ol.Layer.Group, che è una particolare collezione OpenLayers (ol.Collection) dedicata alla gestione di un insieme di layer.
    var layersGroup = new ol.Layer.Group({
      layers: [osm, poligoni, linee, punti]
    })
    map.addLayer(layersGroup);
    

    Questo è permesso dal fatto che il metodo ol.Map.addLayer() accetta una qualsiasi classe figlia di ol.layer.Base, ovvero sia ol.layer.Layer che ol.layer.Group.

Uno dei motivi per cui l’insieme dei layer della mappa può essere gestito come ol.Collection (in quanto ol.layer.Group) è quello di poter usufruire dei molti metodi offerti dalle collezioni OpenLayers. Oltre ai vari metodi per gestire i contenuti della collezione (inserimento e rimozione di elementi), ne esiste uno per gestirne l’ordinamento. Ne deriva che, tramite questo metodo di ol.Collection, è possibile cambiare anche l’ordinamento dei layer della mappa.

Supponiamo di voler spostare lo strato delle linee sopra tutti gli altri, possiamo fare così:

var layersGroup = map.getLayers(); // ottengo tutti i layer come ol.layer.Group
var topPosition = layersGroup.getLength() - 1; // numero di elementi - 1 == indice massimo
layersGroup.setAt(topPosition, linee); // posiziono il layer delle linee all'indice 4, ovvero in testa

Gli indici vanno da 0: prima posizione -> layer più in basso a (numero di layer - 1): ultima posizione -> layer più in alto.

(Nota tecnica: il fatto che lo spostamento di un layer in una collezione provochi l’effettivo spostamento nella mappa, è dovuto al fatto che ogni cambiamento di proprietà di un oggetto OpenLayers scatena un evento che può essere intercettato da noi o da altri oggetti di OL. In questo caso il cambiamento dell’ordine degli oggetti nella collezione dei layer della mappa viene intercettata dalla mappa stessa, che provvederà ad eseguire tutte le operazioni per cambiare, visivamente, la posizione degli strati. Approfondiremo questo aspetto in un capitolo apposito dedicato agli eventi).