Overlay (ovveri i “popup”)

In OpenLayers è disponibile un oggetto ol.Overlay che permette di posizionare sulla mappa, ad una data posizione, un qualsiasi elemento HTML presente nella pagina web. Nel momento in cui istanziamo un ol.Overlay e gli passiamo come elemento contenitore un elemento già presente nella pagina, questo viene rimosso dalla sua posizione e inserito come elemento figlio dell’elemento contenente la mappa. Questa modifica (operata automaticamente da OL) fa sì che quell’elemento potrà essere posizionato all’interno della mappa alla coordinata richiesta dall’utente.

Di seguito un esempio di un popup statico, fissato al fianco di una determinata coordinata.

Un overlay può essere posizionato utilizzando il metodo ol.overlay.setPosition(). Lo stesso metodo può essere usato per nascondere il popup se viene chiamato senza argomento (ovvero passandogli un argomento undefined).

Possiamo modificare il metodo per mostrare i risultati delle query WMS in modo che la tabella degli attributi venga visualizzata all’interno di un overlay:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// creo un overlay con una serie di opzioni
var popup = new ol.Overlay({
    element: document.getElementById('results'), // elemento contenitore
    autoPan: true, // muove la mappa in modo da far rientrare (possibilmente) l'overlay nell'area visualizzata
    autoPanAnimation: {
      duration: 250
    },
    offset: [10,0] // distanziamento orizzontale/verticale, in pixel, rispetto alla posizione in cui sarà posizionato l'elemento
});
map.addOverlay(popup); // aggiungo l'overlay alla mappa

(...)

map.on('click', function(evt) {
    // ad ogni click sulla mappa nascondo l'overlay, nel caso fosse già visibile
    popup.setPosition(undefined);
    queryLayer(evt.coordinate);
});

(...)

var resultsLayer; // layer che conterrà le geometrie dei risultati, per mostrarli in mappa
function showResults(feature) {
    (...)
    
    // popolo la tabella e la inserisco in #results allo stesso dell'esempio precedente
    var tableEl = $("<table>");
    for (key in attributes) {
        if (key == "geometryProperty") {
            continue;
        }
        var trEl = $("<tr>");
        trEl.append($("<td class='fieldname'>" + key + "</td>"));
        trEl.append($("<td>" + attributes[key] + "</td>"));
        tableEl.append(trEl);
    }
    resultsEl.append(tableEl);
    
    // posiziono il popup al vertice superiore destro del BBOX della geometria
    var geomExtent = feature.getGeometry().getExtent();
    var popupPosition = ol.extent.getTopRight(geomExtent);
    popup.setPosition(popupPosition);
}

Il popolamento della tabella dei risultati, e il suo inserimento nell’elemento #results è esattamente lo stesso dell’esempio precedente. Quello che cambia è che stavolta abbiamo:

  1. Creato un Overlay, usando come contenitore l’elemento #results, e lo abbiamo inserito in mappa (righe 2-10)
  2. Ad ogni click sulla mappa forniamo una posizione undefined all’overlay, in modo da rimuoverlo dalla mappa (riga 15)
  3. Una volta popolata la tabella dei risultati, visualizziamo e posizionamo l’overlay ad una certa coordinata. In questo esempio abbiamo scelto l’angolo superiore destro del BBOX della geometria. (riga 42)

La struttura, i contenuti e la stilizzazione del popup è tutta a carico nostro, il che fornisce una totale flessibilità nella rappresentazione dei popup.