From aa40ab7d4d1b0a7f1655612fe3ab5102b96b2410 Mon Sep 17 00:00:00 2001 From: Theo Satabin Date: Mon, 12 May 2025 12:10:48 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Le=20GetCapabilities=20WMTS=20explicite=20l?= =?UTF-8?q?e=20style=20par=20d=C3=A9faut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-and-release.yaml | 7 +++---- CHANGELOG.md | 18 +++++++++++++----- src/configurations/Layer.cpp | 4 +++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-and-release.yaml b/.github/workflows/build-and-release.yaml index f08965b..2465fcf 100644 --- a/.github/workflows/build-and-release.yaml +++ b/.github/workflows/build-and-release.yaml @@ -39,7 +39,6 @@ jobs: fail-fast: true matrix: include: - - os: ubuntu-20.04 - os: ubuntu-22.04 runs-on: ${{ matrix.os }} @@ -69,7 +68,7 @@ jobs: make package - name: Run unit tests - if: "matrix.os == 'ubuntu-20.04'" + if: "matrix.os == 'ubuntu-22.04'" run: | cd build make test @@ -82,7 +81,7 @@ jobs: release-tag: ${{ github.ref_name }} - name: Build documentation - if: "matrix.os == 'ubuntu-20.04'" + if: "matrix.os == 'ubuntu-22.04'" run: | cd build make doc @@ -114,7 +113,7 @@ jobs: run: pip install -r docs/requirements.txt - name: Publish documentation - if: "matrix.os == 'ubuntu-20.04'" + if: "matrix.os == 'ubuntu-22.04'" run: | git config user.name github-actions git config user.email github-actions@github.com diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e2cc8..6d83527 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,23 @@ +## 6.1.6 + +* `WMTS` : dans le getcapabilities, le premier style possède l'attribut isDefault à `true` + ## 6.1.5 +### [Added] + +* `WMS` + * Écriture de la valeur de nodata dans les header geotiff + ### [Fixed] * Nettoyage et bascule des styles et TMS lors d'une extinction ou redémarrage du serveur * `WMTS` - * pour que la couche apparaisse dans les capacités Inspire, le style par défaut doit avoir l'identifiant `.Default` + * Pour que la couche apparaisse dans les capacités Inspire, le style par défaut doit avoir l'identifiant `:Default` * `WMS` - * pour que la couche apparaisse dans les capacités Inspire, le style par défaut doit avoir l'identifiant `.Default` - * on vérifie que la donnée a bien 3 canaux pour répondre une tuile en JPEG - * Dans le cas d'une couche inconnu, le code est `LayerNotDefined` - * Écriture de la valeur de nodata dans les header geotiff + * Pour que la couche apparaisse dans les capacités Inspire, le style par défaut doit avoir l'identifiant `:Default` + * On vérifie que la donnée a bien 3 canaux pour répondre une tuile en JPEG + * Dans le cas d'une couche inconnue, le code est `LayerNotDefined` * `TMS` * Dans la description des couches, les niveaux (`TileSet`) doivent être définis dans la balise `TileSets` et non `TileMap` et `Origin` est le coin en bas à gauche et non en haut à gauche diff --git a/src/configurations/Layer.cpp b/src/configurations/Layer.cpp index dc98a70..508cad4 100644 --- a/src/configurations/Layer.cpp +++ b/src/configurations/Layer.cpp @@ -752,6 +752,7 @@ void Layer::add_node_wmts(ptree& parent, WmtsService* service, bool only_inspire m.add_node_wmts(node); } + bool is_first = true; for ( Style* s : available_styles) { /* Un style est applicable en WMTS si : @@ -763,7 +764,8 @@ void Layer::add_node_wmts(ptree& parent, WmtsService* service, bool only_inspire Cela permet de n'avoir à modifier que l'en tête de la tuile PNG pour que le style "soit appliqué" */ if (s->is_identity() || (pyramid->get_channels() == 1 && pyramid->get_sample_compression() == Compression::PNG)) { - s->add_node_wmts(node); + s->add_node_wmts(node, is_first); + is_first = false; } } From d337ebcf682e384da9dc930a7c1329a0a92d2a7d Mon Sep 17 00:00:00 2001 From: Theo Satabin Date: Fri, 16 May 2025 15:20:51 +0200 Subject: [PATCH 2/2] Correction des getcapabilities (WMS et WMTS) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### [Fixed] * `WMTS` : * dans le getcapabilities, le premier style possède l'attribut isDefault à `true` * pour la version inspire, peu importe l'identifiant du style et le nom de la couche * `WMS` : * pour le getcapabilities inspire : si le nom est normalisé, son style doit être `.Default`, sinon `DEFAULT` * si une dimension est nulle (et pas juste négative) pour le GetMap ou GetFeatureInfo, on sort en erreur immédiatement --- CHANGELOG.md | 9 +++++++- src/Inspire.cpp | 34 +++++++++++------------------ src/Inspire.h | 2 +- src/services/wms/getfeatureinfo.cpp | 20 ++++++++--------- src/services/wms/getmap.cpp | 8 +++---- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d83527..0c7a377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ## 6.1.6 -* `WMTS` : dans le getcapabilities, le premier style possède l'attribut isDefault à `true` +### [Fixed] + +* `WMTS` : + * dans le getcapabilities, le premier style possède l'attribut isDefault à `true` + * pour la version inspire, peu importe l'identifiant du style et le nom de la couche +* `WMS` : + * pour le getcapabilities inspire : si le nom est normalisé, son style doit être `.Default`, sinon `DEFAULT` + * si une dimension est nulle (et pas juste négative) pour le GetMap ou GetFeatureInfo, on sort en erreur immédiatement ## 6.1.5 diff --git a/src/Inspire.cpp b/src/Inspire.cpp index b48c00a..f411d20 100644 --- a/src/Inspire.cpp +++ b/src/Inspire.cpp @@ -126,17 +126,12 @@ const std::vector layer_names = { "US.SubsidiaryServicesToEducation", "US.ThermalNetwork", "US.UpperSecondaryEducation", "US.UtilityNetwork", "US.WaterNetwork", "GE.VspSurevey" }; -bool is_inspire_layer_name ( std::string ln ) { +bool is_normalized_layer_name ( std::string ln ) { return std::find(layer_names.begin(), layer_names.end(), ln) != layer_names.end(); } bool is_inspire_wmts ( Layer* layer ) { - if (! is_inspire_layer_name(layer->get_id())) { - BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMTS (" << layer->get_id() << ") : layer name non harmonisé" ; - return false; - } - if (layer->get_keywords()->size() == 0) { BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMTS (" << layer->get_id() << ") : pas de mots-clés" ; return false; @@ -152,31 +147,28 @@ bool is_inspire_wmts ( Layer* layer ) { return false; } - // Pour être inspire, le style par défaut doit avoir le bon identifiant - if (layer->get_default_style()->get_identifier() != layer->get_id() + ":Default") { - BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMTS (" << layer->get_id() << ") : style par défaut != " + layer->get_id() + ":Default" ; - return false; - } - return true; } bool is_inspire_wms ( Layer* layer ) { - if (! is_inspire_layer_name(layer->get_id())) { - BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMS (" << layer->get_id() << ") : layer name non harmonisé" ; - return false; - } - if (layer->get_keywords()->size() == 0) { BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMS (" << layer->get_id() << ") : pas de mots-clés" ; return false; } - // Pour être inspire, le style par défaut doit avoir le bon identifiant - if (layer->get_default_style()->get_identifier() != layer->get_id() + ":Default") { - BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMS (" << layer->get_id() << ") : style par défaut != " + layer->get_id() + ":Default" ; - return false; + if (is_normalized_layer_name(layer->get_id())) { + // On doit avoir un style dont l'identifiant est .Default + if (layer->get_style_by_identifier(layer->get_id() + ".Default") == NULL) { + BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMS (" << layer->get_id() << ") : layer name harmonisé mais pas de style .Default" ; + return false; + } + } else { + // On doit avoir un style avec l'identifiant DEFAULT + if (layer->get_style_by_identifier("DEFAULT") == NULL) { + BOOST_LOG_TRIVIAL(debug) << "Non conforme INSPIRE WMS (" << layer->get_id() << ") : layer name non harmonisé mais pas de style DEFAULT" ; + return false; + } } return true; diff --git a/src/Inspire.h b/src/Inspire.h index da2ad36..427f249 100644 --- a/src/Inspire.h +++ b/src/Inspire.h @@ -63,7 +63,7 @@ namespace Inspire { * \~english \brief Is layer name a harmonized inspire one * \param[in] ln Layer name to test */ -bool is_inspire_layer_name ( std::string ln ); +bool is_normalized_layer_name ( std::string ln ); /** * \~french \brief La couche est-elle conforme Inspire WMTS diff --git a/src/services/wms/getfeatureinfo.cpp b/src/services/wms/getfeatureinfo.cpp index 54124b9..e071954 100644 --- a/src/services/wms/getfeatureinfo.cpp +++ b/src/services/wms/getfeatureinfo.cpp @@ -124,8 +124,8 @@ DataStream* WmsService::get_feature_info ( Request* req, Rok4Server* serv ) { if (sscanf(str_width.c_str(), "%d", &width) != 1) throw WmsException::get_error_message("Invalid WIDTH value", "InvalidParameterValue", 400); - if ( width < 0 ) - throw WmsException::get_error_message("WIDTH query parameter have to be a positive integer", "InvalidParameterValue", 400); + if ( width <= 0 ) + throw WmsException::get_error_message("WIDTH query parameter have to be a strictly positive integer", "InvalidParameterValue", 400); if ( width > max_width ) throw WmsException::get_error_message("WIDTH query parameter exceed the limit (" + std::to_string(max_width) + ")", "InvalidParameterValue", 400); @@ -136,8 +136,8 @@ DataStream* WmsService::get_feature_info ( Request* req, Rok4Server* serv ) { if (sscanf(str_height.c_str(), "%d", &height) != 1) throw WmsException::get_error_message("Invalid HEIGHT value", "InvalidParameterValue", 400); - if ( height < 0 ) - throw WmsException::get_error_message("HEIGHT query parameter have to be a positive integer", "InvalidParameterValue", 400); + if ( height <= 0 ) + throw WmsException::get_error_message("HEIGHT query parameter have to be a strictly positive integer", "InvalidParameterValue", 400); if ( height > max_height ) throw WmsException::get_error_message("HEIGHT query parameter exceed the limit (" + std::to_string(max_width) + ")", "InvalidParameterValue", 400); @@ -264,8 +264,8 @@ DataStream* WmsService::get_feature_info ( Request* req, Rok4Server* serv ) { if (sscanf(str_dpi.c_str(), "%d", &dpi) != 1) throw WmsException::get_error_message("Invalid DPI value", "InvalidParameterValue", 400); - if ( width < 0 ) - throw WmsException::get_error_message("DPI query parameter have to be a positive integer", "InvalidParameterValue", 400); + if ( width <= 0 ) + throw WmsException::get_error_message("DPI query parameter have to be a strictly positive integer", "InvalidParameterValue", 400); } // info_format @@ -293,8 +293,8 @@ DataStream* WmsService::get_feature_info ( Request* req, Rok4Server* serv ) { } if ( i < 0 ) throw WmsException::get_error_message("I query parameter have to be a positive integer", "InvalidPoint", 400); - if ( i > width ) - throw WmsException::get_error_message("I query parameter have to be smaller than width", "InvalidPoint", 400); + if ( i >= width ) + throw WmsException::get_error_message("I query parameter have to be strictly smaller than width", "InvalidPoint", 400); // j @@ -307,8 +307,8 @@ DataStream* WmsService::get_feature_info ( Request* req, Rok4Server* serv ) { } if ( j < 0 ) throw WmsException::get_error_message("J query parameter have to be a positive integer", "InvalidPoint", 400); - if ( j > height ) - throw WmsException::get_error_message("J query parameter have to be smaller than height", "InvalidPoint", 400); + if ( j >= height ) + throw WmsException::get_error_message("J query parameter have to be strictly smaller than height", "InvalidPoint", 400); // feature_count int feature_count = 1; diff --git a/src/services/wms/getmap.cpp b/src/services/wms/getmap.cpp index 8d2e27f..96c440b 100644 --- a/src/services/wms/getmap.cpp +++ b/src/services/wms/getmap.cpp @@ -100,8 +100,8 @@ DataStream* WmsService::get_map ( Request* req, Rok4Server* serv ) { if (sscanf(str_width.c_str(), "%d", &width) != 1) throw WmsException::get_error_message("Invalid WIDTH value", "InvalidParameterValue", 400); - if ( width < 0 ) - throw WmsException::get_error_message("WIDTH query parameter have to be a positive integer", "InvalidParameterValue", 400); + if ( width <= 0 ) + throw WmsException::get_error_message("WIDTH query parameter have to be a strictly positive integer", "InvalidParameterValue", 400); if ( width > max_width ) throw WmsException::get_error_message("WIDTH query parameter exceed the limit (" + std::to_string(max_width) + ")", "InvalidParameterValue", 400); @@ -112,8 +112,8 @@ DataStream* WmsService::get_map ( Request* req, Rok4Server* serv ) { if (sscanf(str_height.c_str(), "%d", &height) != 1) throw WmsException::get_error_message("Invalid HEIGHT value", "InvalidParameterValue", 400); - if ( height < 0 ) - throw WmsException::get_error_message("HEIGHT query parameter have to be a positive integer", "InvalidParameterValue", 400); + if ( height <= 0 ) + throw WmsException::get_error_message("HEIGHT query parameter have to be a strictly positive integer", "InvalidParameterValue", 400); if ( height > max_height ) throw WmsException::get_error_message("HEIGHT query parameter exceed the limit (" + std::to_string(max_width) + ")", "InvalidParameterValue", 400);