Dimensions d’un jeu de tuiles

Author:Thomas Bonfort
Contact:tbonfort at terriscope.fr
Author:Seth Girvin
Contact:sgirvin at compass.ie
Author:Jerome Boue
Last Updated:2018/05/04
Version:1.6.1

Introduction

Les couches WMS dans MapServer peuvent supporter les dimensions, voir WMS Dimension pour les détails. MapCache supporte également les dimensions pour les jeux de tuiles.

Stocker des caches de tuiles distincts pour différentes dimensions est utile dans un certain nombre de situations comme créer des caches pour différentes limites spatiales, altitudes ou périodes de temps. Cela fournit aussi un mécanisme pour changer de Mapfile selon une valeur de dimension donnée.

MapCache utilise les dimensions pour:

  • créer la structure de dossiers des caches disque et SQLite qui utilisent la variable de substitution {dim} dans le template de leur configuration, voir Template Structure dans Caches disque et Using Multiple SQLite Database Files dans Caches SQLite.
  • créer le schéma de données des caches SQLite qui utilisent la variable de substitution :dim, voir Custom Schema dans Caches SQLite.
  • construire les requêtes à destination des sources WMS: toute dimension spécifiée pour un jeu de tuile est transmise à sa source WMS lorsqu’un défaut de cache survient.

Activation des dimensions dans MapCache

Les dimensions sont activées dans le fichier de configuration au niveau du Jeu de tuiles. Chaque jeu de tuile peut définir ses propres dimensions à l’aide d’une section <dimensions> qui inclut un ou plusieurs éléments <dimension>.

Attributs de dimension

Plusieurs attributs sont définis pour l’élément <dimension>.

  • name (requis): Le nom de la dimension dans une requête WMS (sans le préfixe dim_ spécifié dans WMS 1.1.1 Specification).
  • default (requis): La valeur par défaut de la dimension lorsqu’aucune valeur n’est fournie explicitement dans la requête WMS.
  • type (requis): MapCache définit plusieurs façons de spécifier une dimension: values, regex, sqlite et time. Ces types de dimensions sont décrits dans la suite.
  • unit (optionnel): unité physique de la dimension. Cette information n’est utilisée que dans la réponse à une requête GetCapabilities.

Types de dimensions

Plusieurs types de dimensions sont supportés par MapCache: values, regex, sqlite et time. Ils peuvent être classés en deux groupes selon comment les valeurs de la dimension sont définies:

  • Dimensions de premier niveau: values et regex. Les valeurs de la dimension sont spécifiées statiquement dans le fichier de configuration.
  • Dimensions de deuxième niveau: sqlite et time. Les valeurs de la dimension sont stockées via un mécanisme dynamique (un fichier SQLite) de sorte qu’une modification de ces valeurs ne nécessite pas de redémarrage du serveur MapCache.

Dimensions de premier niveau

Les dimensions de premier niveau définissent leurs valeurs dans le fichier de configuration.

Dimensions de type values

Une dimension de type values donne la liste de toutes ses valeurs possibles. Le nom de la dimension est utilisée comme clé dans une requête WMS ou WMTS, par exemple &DIM1=foobarbaz.

Lorsqu’un client ne fournit pas de valeur explicite pour la dimension, alors la valeur par défaut est prise en compte (c’est-à-dire foobar dans cet exemple).

<tileset name="LayerName">
    <source>LayerSource</source>
    <cache>sqlite</cache>
    <grid>GoogleMapsCompatible</grid>
    <format>PNG</format>
    <metatile>5 5</metatile>
    <metabuffer>10</metabuffer>
    <dimensions>
        <dimension type="values" name="DIM1" default="foobar">
            <value>foobar</value>
            <value>foobarbaz</value>
            <value>foo</value>
            <value>bar</value>
        </dimension>
    </dimensions>
</tileset>

Dimensions de type regex

Une alternative à une liste de valeurs en dur, est l’utilisation d’expressions régulières.

L’exemple suivant crée une dimension MAPFILE, afin d’utiliser le même jeu de tuiles MapCache avec différents Mapfiles MapServer. MapCache n’a pas besoin de connaître les noms des Mapfiles, qui peuvent alors être créés après le démarrage de MapCache.

Lorsqu’un utilisateur passe MAPFILE=/path/to/mapfile, MapCache vérifie que la chaîne /path/to/mapfile répond à l’expression régulière (PCRE) définie dans le fichier de configuration. Dans cet exemple, l’expression régulière valide un nom composé de caractères alphanumériques séparés par des barres obliques (/) et se terminant par « .map » ( [a-zA-Z0-9./]*.map$ ), mais échoue en présence de deux points consécutifs (..) afin d’empêcher toute traversée du système de fichiers.

<dimension type="regex" name="MAPFILE" default="/path/to/mapfile.map">
        <regex>^(?!.*\.\.)[a-zA-Z0-9\./]*\.map$</regex>
</dimension>

Dimensions de deuxième niveau

Les dimensions de deuxième niveau stockent leurs valeurs via un mécanisme dynamique externe, initialement un fichier SQLite. Cela permet d’ajouter de nouvelles valeurs pour la dimension sans modifier le fichier de configuration, ce qui sinon obligerait à redémarrer le serveur.

Dimensions de type time

MapCache supporte les requêtes WMTS et WMS qui incluent un paramètre TIME, aussi bien pour les dates que pour les intervalles de temps. Voir MS RFC 96: Time Dimension Support in MapCache Tilesets pour plus de détails.

La définition d’une dimension de type time met en œuvre un fichier SQLite. Deux éléments sont à spécifier:

  • <dbfile>: Emplacement du fichier SQLite qui sert de support à la dimension de type time
  • <query>: Requête SQL qui renvoie la liste des valeurs de dates disponibles dans un intervalle de temps donné. Dans cette requête, la date de début et la date de fin sont représentées par les variables de substitution :start_timestamp et :end_time_stamp. Les valeurs renvoyées doivent être au format de date yyyy-mm-ddThh:mm:ssZ, tel que spécifié dans la RFC 3339 mais restreint à l’UTC.

Les valeurs temporelles dans le fichier SQLite sont exprimées en temps Unix, c’est-à-dire un nombre de secondes depuis le premier janvier 1970 à minuit UTC.

Une requête temporelle avec un intervalle peut renvoyer plusieurs valeurs de dates, chacune faisant référence à des tuiles distinctes. Assembler ces tuiles est décrit dans la section Tile Assembly Policies plus loin.

<!-- "time" dimension

     This example defines a "time" dimension whose possible values are
     stored in the /path/to/mapcache-time.sqlite SQLite file. The default
     value is "2010".

     A WMS request with that dimension may contain, e.g.
     "... &time=1999-08-11T11:03:07Z/2001-09-21T08:17:56Z& ..."
-->
<dimension type="time" name="time" default="2010">
    <dbfile>/path/to/mapcache-time.sqlite</dbfile>
    <query>
         SELECT strftime("%Y-%m-%dT%H:%M:%SZ",ts) FROM time
          WHERE ts &gt;= datetime(:start_timestamp,"unixepoch")
            AND ts &lt;= datetime(:end_timestamp,"unixepoch")
       ORDER BY ts DESC
    </query>
</dimension>

Dimensions de type sqlite

Dans une dimension de type sqlite les valeurs de dimension sont stockées dans un fichier SQLite. De plus, chaque valeur référence une liste de valeurs internes, dites de sous-dimension, qui sont utilisées pour formuler les requêtes au cache.

Par exemple, soit une dimension « sensor » dont les valeurs possibles représentent divers satellites d’observation de la Terre. Une requête WMS avec cette dimension peut contenir: ...&dim_sensor=spot&... Dans cet exemple, chaque capteur référence plusieurs types de données selon une sous-dimension interne nommée « product ». Un exemple du contenu de la dimension « sensor » est représenté sur la table suivante:

Dimension « sensor » Sous-dimension « product »
spot spot-img1
spot spot-img2
phr phr-img1
phr phr-img2
phr phr-img3

La requête WMS se passe au niveau de la dimension « sensor ». La requête sur le cache a lieu au niveau de la sous-dimension « product ». Dans le cas d’un défaut de cache, les valeurs de la sous-dimension « product » sont utilisées pour formuler une requête à la source de données.

Une requête à une dimension de type sqlite peut alors renvoyer plusieurs valeurs de sous-dimensions, chacune faisant référence à des tuiles distinctes. Assembler ces tuiles est décrit dans la section Tile Assembly Policies plus loin.

<!-- "sqlite" dimension

     This example defines a "sensor" dimension whose possible values are
     stored in the /data/sensor.sqlite SQLite file. The default value is
     "phr".

     A WMS request with that dimension may contain, e.g.
     "... &dim_sensor=spot& ..."
-->
<dimension type="sqlite" name="sensor" default="phr">
   <dbfile>/data/sensor.sqlite</dbfile>
   <list_query>
      SELECT distinct(product) FROM dim
   </list_query>
   <validate_query>
      SELECT product FROM dim
       WHERE sensor=:dim
   </validate_query>
</dimension>

Politiques d’assemblage des tuiles

Lorsque plusieurs valeurs de temps ou de sous-dimensions sont renvoyées suite à une requête à une dimension de deuxième niveau, la tuile résultante est un assemblage de toutes les tuiles simples associées à chaque valeur. La façon dont ces tuiles sont assemblées est définie avec l’élément <assembly_type> de la section <dimensions>. Seulement deux valeurs sont prises en charge par MapCache:

  • none: Aucun assemblage n’est réalisé, la tuile résultante est la première tuile récupérée du cache. C’est la valeur par défaut.

  • stack: Chaque pixel de la tuile résultante est rempli avec le premier pixel opaque trouvé dans toutes les tuiles dans leur ordre de récupération, par exemple:

    Type d’assemblage: stack
    ../_images/mapcache-assembly-stack-1.png ../_images/mapcache-assembly-stack-2.png ../_images/mapcache-assembly-stack-3.png
    Produit 1 Produit 2 Assemblage stack des produits 1 et 2

Il est possible de choisir si la tuile résultante doit être stockée dans le cache ou non, via l’élément <store_assemblies> de la section <dimensions>. Les deux valeurs possibles sont true et false. La valeur par défaut est true.

L’élément <subdimensions_read_only> de la section <dimensions> indique si la source de données doit être interrogée en cas de défaut de cache. Les deux valeurs possibles sont true et false. La valeur par défaut est false.

<dimensions>
    <assembly_type>stack</assembly_type>
    <store_assemblies>true</store_assemblies>
    <subdimensions_read_only>false</subdimensions_read_only>
    <dimension >...</dimension>
</dimensions>

Stockage des dimensions

Dans un cache de type disque, les tuiles sont stockées dans une structure de dossier ressemblant à base/gridname/DIM1/value/xx/xx/xx/xx/xx/xx.png (où DIM1 est la valeur de dimension).

L’ordre des éléments <dimension> à l’intérieur de la section <dimensions> est important car il est utilisé pour créer la structure de répertoires pour le cache de type disque. Si l’ordre est modifié, toutes les tuiles qui ont été déjà stockées dans le cache sont invalidées (elles deviennent inaccessibles à MapCache mais ne sont pas détruites).

Les « templates » peuvent être utilisés pour adapter la structure des dossiers, par exemple:

<cache name="tmpl" type="disk">
    <template>/tmp/template-test/{tileset}#{grid}#{dim}/{z}/{x}/{y}.{ext}</template>
</cache>

Les « templates » peuvent aussi être utilisés pour adapter le nom d’un fichier SQLite, par exemple:

<!-- the following will create databases named TilesetName-#DimensionValue.db -->
<cache name="sqlite" type="sqlite3">
   <dbfile>{tileset}-{dim}.db</dbfile>
   <detect_blank />
</cache>

Accès à un cache de tuiles à l’aide des dimensions

Pour obtenir une tuile avec une dimension spécifique, il suffit d’ajouter le nom de la dimension et sa valeur à la requête, par exemple: &DIM1=value

Seuls les clients WMS et WMTS supportent le passage des dimensions à MapCache. Les autres services de tuiles, tels que gmaps (GoogleMaps), tms et KML ne supportent pas les dimensions. Toutefois, WMTS permet l’accès à une tuile selon un schéma d’adressage x,y,z, ce qui ouvre la possibilité à des clients de tuiles (par exemple une couche OpenLayers ol.source.XYZ) d’accéder à un jeu de tuiles avec dimensions grâce à une réécriture d’URL sur le serveur web.

# a URL such as the following
http://servername/tiles/13/3914/2687.png
# can be rewritten into a WMTS request - note WMTS uses {z}/{y}/{x} rather than {z}/{x}/{y}
# so these values need to be swapped
http://servername/mapcache/wmts/1.0.0/layername/default/dimension/GoogleMapsCompatible/13/2687/3914.png

Alimenter un cache de tuiles à l’aide des dimensions

L’outil d’alimentation de MapCache autorise d’alimenter des dimensions spécifiques avec la syntaxe suivante:

mapcache_seed -c mapcache_config.xml -t tileset1 -e -1187000,6695000,-605000,7450000 -z 7,10 --dimension DIMENSION_NAME=DIMENSION_VALUE