Correction de l'erreur "Unknown TILEMATRIX" avec GeoServer WMTS et l'API JavaScript d'AMap

Problématique de Compatibilité entre l'API JavaScript d'AMap et le Service WMTS de GeoServer

Lors de l'intégration d'un service WMTS (Web Map Tile Service) fourni par GeoServer avec l'API JavaScript de cartographie AMap (également connue sous le nom de Gaode Maps), il est fréquent de rencontrer une erreur signalant un Unknown TILEMATRIX. Ce problème survient principalement en raison d'une différence dans le format attendu pour le paramètre TILEMATRIX entre le client AMap et l'implémentation WMTS de GeoServer (qui repose sur GeoWebCache).

Le Contexte des Paramètres WMTS

Un service WMTS utilise des jeux de matrices de tuiles (TileMatrixSet) pour définir les niveaux de zoom et la résolution des tuiles. Chaque requête de tuile inclut un paramètre TILEMATRIX qui spécifie le niveau de zoom désiré. L'API JavaScript d'AMap requiert spécifiquement que les services WMTS soient configurés avec le système de coordonnées EPSG:3857.

Généralement, d'autres bibliothèques cartographiques comme Leaflet envoient le paramètre TILEMATRIX dans un format qui inclut l'identifiant du jeu de matrices, par exemple :

TILEMATRIX: EPSG:3857:13

EPSG:3857 est l'identifiant du jeu de matrices et 13 est le niveau de zoom.

Cependant, l'API JavaScript d'AMap tend à omettre l'identifiant du jeu de matrices, envoyant simplement le niveau de zoom :

TILEMATRIX: 13

Analyse du Problème dans GeoServer (GeoWebCache)

L'implémentation WMTS de GeoServer, gérée par GeoWebCache (GWC), s'attend à un format spécifique pour le paramètre TILEMATRIX. Le code source pertinent se trouve dans la classe org.geowebcache.service.wmts.WMTSService.java.

Voici un extrait simplifié du code de GWC qui traite ce paramètre :

final String paramMatriceTuile = valeurs.get("tilematrix");
if (paramMatriceTuile == null) {
    throw new OWSException(
            400, "MissingParameterValue", "TILEMATRIX", "Paramètre TILEMATRIX manquant");
}

long niveauZoom = jeuSousGrille.getGridIndex(paramMatriceTuile); // Cette ligne attend un format préfixé
if (niveauZoom < 0) {
    throw new OWSException(
            400, "InvalidParameterValue", "TILEMATRIX", "TILEMATRIX inconnu : " + paramMatriceTuile);
}

Si la valeur de paramMatriceTuile est simplement "13", la méthode getGridIndex(paramMatriceTuile) ne trouvera pas de correspondance car elle recherche un format comme "EPSG:3857:13". Cela déclenche l'exception OWSException avec le message "Unknown TILEMATRIX".

Solution : Modifictaion du Code Source de GeoWebCache

Pour résoudre cette incompatibilité, il est nécessaire de modifier la logique d'analyse du paramètre TILEMATRIX dans GeoWebCache afin qu'il puisse interpréter à la fois le format préfixé et le format numérique simple. L'objectif est de vérifier si le paramètre contient l'identifiant du jeu de matrices. Si c'est le cas, on utilise la méthode d'analyse standard ; sinon, on suppose que la valeur est directement le niveau de zoom.

Voici la modification proposée pour la classe org.geowebcache.service.wmts.WMTSService.java :

package org.geowebcache.service.wmts;

// ... imports existants ...

public class WMTSService extends Service {

    // ... code existant ...

    private long obtenirNiveauZoom(Map<String, String> valeursRequete, GridSubset jeuSousGrille) throws OWSException {
        final String paramMatriceTuile = valeursRequete.get("tilematrix");
        if (paramMatriceTuile == null) {
            throw new OWSException(
                    400, "MissingParameterValue", "TILEMATRIX", "Le paramètre TILEMATRIX est manquant.");
        }

        long niveauZoom = -1;
        // Obtenir l'identifiant du jeu de matrices de tuiles pour la comparaison
        // Assumons que gridSubset.getGridSet().getName() retourne l'ID comme "EPSG:3857"
        final String identifiantJeuMatrice = jeuSousGrille.getGridSet().getName();

        if (paramMatriceTuile.contains(identifiantJeuMatrice)) {
            // Le paramètre contient l'identifiant du jeu de matrices (ex: "EPSG:3857:13")
            niveauZoom = jeuSousGrille.getGridIndex(paramMatriceTuile);
        } else {
            // Le paramètre est probablement juste le niveau de zoom (ex: "13")
            try {
                niveauZoom = Long.parseLong(paramMatriceTuile);
            } catch (NumberFormatException e) {
                throw new OWSException(
                        400, "InvalidParameterValue", "TILEMATRIX",
                        "Format de TILEMATRIX non reconnu : " + paramMatriceTuile, e);
            }
        }

        if (niveauZoom < 0) {
            throw new OWSException(
                    400, "InvalidParameterValue", "TILEMATRIX", "Valeur de TILEMATRIX invalide ou inconnue : " + paramMatriceTuile);
        }
        return niveauZoom;
    }

    // Le reste de la classe WMTSService utiliserait cette nouvelle méthode,
    // par exemple en remplaçant l'appel direct à gridSubset.getGridIndex(tileMatrix)
    // dans la méthode traitant les requêtes GetTile ou GetFeatureInfo.
    // ...
}

Cette modification introduit une logique de vérification qui s'adapte au format du paramètre TILEMATRIX. Si l'identifiant du jeu de matrices (par exemple, "EPSG:3857") est présent dans la chaîne, elle est traitée de manière standard. Sinon, la chaîne est directement convertie en un nombre entier représentant le niveau de zoom.

Mise en Œuvre de la Modification

Pour appliquer cette correction, plusieurs approches sont possibles :

  1. Modification directe et recompilation de GeoServer : La méthode la plus directe consiste à obtenir le code source de GeoServer (qui inclut GeoWebCache), modifier le fichier WMTSService.java comme indiqué, puis recompiler GeoServer. Ce processus générera un nouveau fichier JAR pour GeoWebCache qui contiendra la modification.
  2. Surcharge de classe (moins recomandé pour des environnements de production sans un contrôle strict) : En théorie, il serait possible de placer une version modifiée de la classe WMTSService.java directement dans les répertoires d'extensions ou de classes de GeoServer, de manière à ce qu'elle surcharge la version originale du JAR. Cependant, cette approche peut être sujette à des problèmes de classpath ou de compatibilité lors des mises à jour de GeoServer.

Après avoir mis en œuvre cette modification et redémarré GeoServer, l'API JavaScript d'AMap devrait être en mesure de consommer les services WMTS de GeoServer sans rencontrer l'erreur Unknown TILEMATRIX, à condition que le jeu de matrices soit correctement configuré en EPSG:3857 dans GeoServer.

Étiquettes: GeoServer WMTS AMap GeoWebCache Java

Publié le 10 juillet à 05h49