Table of Contents

MapServer

Scaletta

Note sui file .map

LAYER STATUS

DEFAULT Il layer è sempre attivo (attivo per default), non può essere spento.
ON/OFF Il layer è attivo o meno e può essere cambiato a “runtime”, ad esempio in modalità browse con l'opportuno template.

WFS con layer in diversi SRS

È possibile configurare un WFS con diversi layer, ciascuno in un differente SRS. Lo standard WFS non consente di annunciare un layer con più di un SRS.

Se si esplicita la proiezione in MAP.PROJECTION o MAP.WEB.METADATA.wfs_srs, questa (e solo questa) viene annunciata per tutti i layer.

La LAYER.PROJECTION è comunque necessaria per calcolare correttamente la <LatLongBoundingBox> del layer. Tale misura viene annunciata dalla GetCapabilities e deve essere espressa in WGS84.

Mescolare layer con proiezioni differenti crea un grosso problema nel definire la MAP.EXTENT (ancora più evidente se si mescolano SRS in proiezione metrica e SRS in lat/lon). La richiesta GetFeature viene limitata dalla MAP.EXTENT, affinché siano restituite tutte le feature di tutti i layer bisogna quindi considerare l'extent di tutti i layer come numeri puri e trovare il min/max fra tali numeri.

Ad esempio se abbiamo due layer con le seguenti EXTENT:

EXTENT 1680955 4846472 1687816 4852211
UNITS meters
EXTENT 11.128482 43.626412 11.553594 43.829166
UNITS dd

è necessario dichiarare una MAP.EXTENT di questo tipo:

EXTENT 11.128482 43.626412 1687816 4852211

Limitare i formati offerti da un WMS

Questa configurazione non funziona con MapServer 5.0.3, funziona invece con la 5.6.3.

È possibile limitare il tipo di immagine offerto da un WMS, cioè il valore viene restituito dalla GetCapabilities in <Capability><Request><GetMap><Format>.

L'impostazione predefinita è quella di annunciare tutti i formati grafici supportati dal MapServer (lanciare mapserv -v), non solo quelli per cui è definito il MAP.OUTPUTFORMAT.

Ecco le sezioni rilevanti da mettere in un mapfile per limitare - ad esempio - al formato PNG/24 bit e JPEG:

MAP
  ...
  IMAGETYPE aggpng24
  ...
  OUTPUTFORMAT
    NAME "aggpng24"
    DRIVER AGG/PNG
    IMAGEMODE RGB
  END
  OUTPUTFORMAT
    NAME "jpeg"
    DRIVER "GD/JPEG"
    IMAGEMODE RGB
  END
  ...
  WEB
    METADATA
      ...
      wms_getmap_formatlist "image/png; mode=24bit,image/jpeg"
    END
    ...
  END
  ...
END

Sistemi di riferimento

Nome Codice EPSG
Cartografia italiana
Gauss-Boaga Roma40 (Italia Monte Mario) zona 1 3003
Gauss-Boaga Roma40 (Italia Monte Mario) zona 2 3004
Cartografia internazionale GPS
WGS84 4326

Tool GDAL/OGR

ogrinfo

Per avere informazioni su un file OGR (formati vettoriali; es. shapefile, gpx, ecc.) si usa il programma ogrinfo (fornito dal pacchetto gdal-bin). Prima lo si esegue sul file stesso, per avere informazioni sui layer contenuti:

ogrinfo track.gpx
Had to open data source read-only.
INFO: Open of `track.gpx'
      using driver `GPX' successful.
1: waypoints (Point)
2: routes (Line String)
3: tracks (Multi Line String)
4: route_points (Point)
5: track_points (Point)

Si vede che esistono diversi layer al suo interno, a noi interessa quello di nome tracks. Per avere informazioni sul layer si esegue:

ogrinfo -summary track.gpx tracks
Had to open data source read-only.
INFO: Open of `track.gpx'
      using driver `GPX' successful.

Layer name: tracks
Geometry: Multi Line String
Feature Count: 5
Extent: (11.128482, 43.626412) - (11.553594, 43.829166)
Layer SRS WKT:
GEOGCS["WGS 84",
    DATUM["WGS_1984",
        ...

Utilissimo ad esempio per avere la EXTENT.

gdalinfo

Il programma gdalinfo (fornito dal pacchetto gdal-bin) è analogo a ogrinfo, consente di avere informazioni su file raster supportati dalla libreria GDAL:

gdalinfo 1353.tif
Driver: GTiff/GeoTIFF
Files: 1353.tif
Size is 5071, 8851
Coordinate System is `'
Origin = (1670696.939930999884382,4707728.060069000348449)
Pixel Size = (2.120138000000000,-2.120138000000000)
...
Corner Coordinates:
Upper Left  ( 1670696.940, 4707728.060)
Lower Left  ( 1670696.940, 4688962.719)
Upper Right ( 1681448.160, 4707728.060)
Lower Right ( 1681448.160, 4688962.719)
...

Path relativi

Mai usare path assoluti nei file map! Nella peggiore delle ipotesi l'unico path assoluto può essere contenuto in SHAPEPATH.

SHAPEPATH Directory in cui sono memorizzati gli shapefile, compresi i tileindex (indici) per i raster. Si intende relativa alla directory del file map.
TILEINDEX In generale i file raster potrebbero trovarsi in sottodirectory della SHAPEPATH, tuttavia conviene che i file indice siano tutti direttamente nella SHAPEPATH.
tileindex.shp L'indice contiene il path dei file raster, MapServer interpreta il percorso come relativo allo SHAPEPATH, non relativo alla posizione del file indice stesso.

Ad esempio nella directory /usr/local/share/shape/ abbiamo la sottodirectory toscana/ctr25/ con i raster della Carta Tecnica Regionale. Il file map contiene:

SHAPEPATH "/usr/local/share/shape"

LAYER
  TYPE RASTER
  TILEINDEX "toscana_ctr25k_tindex.shp"
END

L'indice deve contenere il percorso relativo toscana/ctr_25k/ e quindi deve essere costruito in questo modo:

cd /usr/local/share/shape
gdaltindex toscana_ctr_25k_index toscana/ctr_25k/*.tif

Tool per tiles

tile4ms

Il programma tile4ms fornito dal pacchetto mapserver-bin serve a creare un indice di shapefile.

Prima di usare tile4ms bisogna creare un elenco dei file che devono essere indicizzati, può tornare utile il comando find o simili. L'elenco creato viene dato in pasto a tile4ms che produce l'indice.

In questo esempio si cercano tutti gli shapefile relativi alla medesima feature elementi lineari, contraddistinti dal nome *el.shp e contenuti in varie sottodirectory, l'elenco viene scritto in un metafile. Il comando tile4ms crea l'indice leggendo dal metafile:

cd /usr/local/share/gisdata
find shape/geofesta2008/firenze10k/ -name "*el.shp" > firenze10k_el_metafile
tile4ms firenze10k_el_metafile firenze10k_el_index

La porzione di mapfile corrispondente è del tipo:

SHAPEPATH "/usr/local/share/gisdata"

LAYER
  NAME "EL entità lineari"
  STATUS DEFAULT
  TYPE LINE
  TILEINDEX "firenze10k_el_index"
  TILEITEM "Location"
  CLASS
    COLOR 120 120 120
  END
END

gdaltindex

Il programma gdaltindex fornito dal pacchetto gdal-bin serve per creare un indice di raster.

cd /usr/local/share/gisdata
gdaltindex toscana_ctr25k_index.shp raster/toscana_ctr25k/*.tif

Il file indice è uno shapefile, analogamente a quanto visto con tile4ms. Va indicato con la direttiva TILEINDEX che si intende relativa a SHAPEPATH. L'indice deve contenere il percorso dei file raster relativi a SHAPEPATH, non al file indice. Con OFFSITE si indica quale colore deve essere considerato trasparente:

SHAPEPATH "/usr/local/share/gisdata"

LAYER
  NAME "ctr25k"
  STATUS DEFAULT
  TYPE RASTER
  TILEINDEX "toscana_ctr25k_index.dbf"
  TILEITEM "Location"
  PROCESSING "RESAMPLE=AVERAGE"
  OFFSITE 255 255 255
END

gdalbuildvrt

In alternativa all'indice di raster si può creare un virtual raster (che può essere agevolmente aperto con tutti i programmi che utilizzano una moderna libreria GDAL, come QGIS):

cd /usr/local/share/gisdata
gdalbuildvrt toscana_ctr25k.vrt raster/toscana_ctr25k/*.tif

In questo caso il mapfile ha questa forma:

SHAPEPATH "/usr/local/share/gisdata"

LAYER
  NAME "ctr25k"
  STATUS DEFAULT
  TYPE RASTER
  DATA toscana_ctr25k.vrt
  PROCESSING "RESAMPLE=AVERAGE"
  OFFSITE 255 255 255
END

gdal_merge.py

Come mosaicare diverse tile troppo piccole per riassemblare un unico raster. L'immagine viene inizializzata bianca (valore 255 per ognuna delle tre bande RGB)

gdal_merge.py -v -o /tmp/075k.tif -init 255 *.tif

Si sarebbe tentati di aggiungere il parametro -n 255 per indicare che il bianco è trasparente. In realtà si ottiene che un valore 255 in una qualunque delle bande origine diventa trasparente rispetto al valore di -init.

gdal_retile.py

Si vuole cambiare la mattonellatura. Se ad esempio le tile originali sono troppe (79 tile 242×181, per un raster totale di 2420×1991), si vorrebbe ottenere solo 4 tile 1210×996.

Si crea anche il nuovo tileindex (questa operazione potrebbe essere svolta da gdal_retile.py stesso).

gdal_retile.py -v -co COMPRESS=LZW -ps 1000 1000 -targetDir 1k_retiled 1k/*.tif
gdaltindex 1k_retiled_index.shp 1k_retiled/*.tif

Manca la possibilità di inizializzare l'immagine con un colore di sfondo (vedi parametro -init di gdal_merge.py).

Se è necessario si può provare ad assemblare tutto in un unico raster e successivamente suddividere. In questo caso le mattonelle le facciamo quadrate 1024×1024.

gdal_merge.py -v -o 25k_merged/25k.tif -init 255 25k/*.tif
gdal_retile.py -v -ps 1024 1024 -targetDir 25k_retiled/ 25k_merged/25k.tif
gdaltindex 25k_retiled_index.shp 25k_retiled/*.tif

Ricetta per creazione di un servizio WMS

  1. Creare indice (quadro d'unione) dei raster:
    gdaltindex 2002_index.shp 2002/*.tif
  2. Creare le piramidi (overview). Per un singolo file .tif:
    gdaladdo --config USE_RRD YES 287050.tif 2 4 8 16 32 64
  3. Oppure per tutti i .tif in una directory:
    ls *.tif | xargs -I nome_file gdaladdo --config USE_RRD YES nome_file 2 4 8 16 32 64
  4. Con GDAL > 1.6.0 vedere man gdaladdo per il parametro -ro e -r gauss per creare file esterni e fare il resample di qualità migliore.
  5. Creare il file .map:
    1. Controllare l'estensione complessiva
      ogrinfo 2002_index.shp -summary 2002_index
    2. Verificare che esistano almeno i seguenti parametri
      MAP.EXTENT                       1672800 4843801 1688801 4856418
      MAP.IMAGETYPE                    jpeg
      MAP.PROJECTION                   "+init=epsg:3003"
      WEB.METADATA.wms_title           "WMS Ortofoto"
      WEB.METADATA.wms_onlineresource  "http://192.168.2.10/cgi-bin/mapserv?map=..."
      WEB.METADATA.wms_srs             "EPSG:3003"
      LAYER.STATUS                     OFF
      LAYER.PROJECTION                 "+init=epsg:3003"
      LAYER.METADATA.wms_title         "Ortofoto 2001"
      LAYER.METADATA.wms_srs           "EPSG:3003"

Legende

Per il corretto funzionamento delle LABEL sono necessarie diverse librerie, tra cui freetype e iconv. Per vedere se MapServer è stato compilato con il supporto FreeType digitare:

/usr/lib/cgi-bin/mapserv -v
MapServer version 5.0.3 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP
OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=AGG SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER
SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER
SUPPORTS=FASTCGI SUPPORTS=THREADS SUPPORTS=GEOS INPUT=EPPL7 INPUT=POSTGIS
INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE

Ottimizzazione

Ad ogni esecuzione di MapServer CGI vengono consumate molte risorse per inizializzare l'ambiente. La modalità FastCGI permette di mantenere un'istanza del programma sempre in esecuzione, risparmiando molto su ciascuna connessione. Ad esempio per 100 richieste GetCapabilities di un layer WMS si può passare da 8 a 2 secondi di attesa.

Installare il pacchetto Debian libapache2-mod-fastcgi. La configurazione predefinita prevede di passare al modulo FastCGI tutte le richieste per eseguibili con estensione .fcgi. Con MapServer si può creare un link simbolico /usr/lib/cgi-bin/mapserv.fcgi -> mapserv da utilizzare al posto dell'originale mapserv.

Tra i processi in esecuzione si noterà un'istanza di mapserv.fcgi anche in assenza di richieste da parte dei client.

Se un file .map ha diversi layer provenienti dallo stesso database può essere utile aprire una sola connessione per tutto il mapfile, invece di aprire e chiudere la connessione per ogni layer. Nei layer interessati si aggiunge la direttiva PROCESSING:

LAYER
  CONNECTIONTYPE POSTGIS
  PROCESSING "CLOSE_CONNECTION=DEFER"
  ...