diff --git a/CHANGELOG.md b/CHANGELOG.md index 6632391..0a3fa64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ Le format est basé sur [Keep a Changelog](https://keepachangelog.com/) et ce pr ## [Unreleased] ### Added + +- `Terrainrgb` : Ajout d'un style terrainrgb pour transformer les MNT en format Terrain RGB. +- `TerrainrgbImage` : Ajout du processus de traitement du style Terrainrgb. +- `Style` : Ajout d'une fonction permettant de savoir si une palette existe ou non. +- Ajout du traitement en cas de style terrainrgb. Il doit être l'unique style déclaré pour fonctionner. + ### Changed - `Cache` : Export de toutes les classes implémentées dans Cache dans leurs propres fichiers. Les fichiers ajoutés sont : @@ -22,6 +28,9 @@ Le format est basé sur [Keep a Changelog](https://keepachangelog.com/) et ce pr ### Deprecated ### Removed ### Fixed + +- `Style` : Vérification de l'existance d'un bloc palette dans le json de style avant la création d'un objet palette. Ce changement nécessite la vérification de l'existance d'une palette qui n'était pas vérifié avant. + ### Security ## [2.0.6] - 2025-09-11 diff --git a/include/rok4/image/TerrainrgbImage.h b/include/rok4/image/TerrainrgbImage.h new file mode 100644 index 0000000..1690aa9 --- /dev/null +++ b/include/rok4/image/TerrainrgbImage.h @@ -0,0 +1,79 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +/** + * \file TerrainrgbImage.h + ** \~french + * \brief D�finition de la classe TerrainrgbImage + ** \~english + * \brief Define class TerrainrgbImage + */ + +#pragma once + +#include "rok4/image/Image.h" +#include "rok4/style/Terrainrgb.h" + +class TerrainrgbImage : public Image +{ +private: + Image *source_image; + Terrainrgb *terrainrgb; + + template + int _getline(T *buffer, int line); + +public: + virtual int get_line(float *buffer, int line); + virtual int get_line(uint16_t *buffer, int line); + virtual int get_line(uint8_t *buffer, int line); + TerrainrgbImage(Image *image, Terrainrgb *terrainrgb); + virtual ~TerrainrgbImage(); + /** \~french + * \brief Sortie des informations sur l'image reprojetée + ** \~english + * \brief Reprojected image description output + */ + void print() { + BOOST_LOG_TRIVIAL(info) << "" ; + BOOST_LOG_TRIVIAL(info) << "--------- TerrainrgbImage -----------" ; + Image::print(); + BOOST_LOG_TRIVIAL(info) << "\t- Min elevation " << terrainrgb->min_elevation ; + BOOST_LOG_TRIVIAL(info) << "\t- Step = " << terrainrgb->step ; + BOOST_LOG_TRIVIAL(info) << "" ; + } +}; diff --git a/include/rok4/style/Style.h b/include/rok4/style/Style.h index 33bc955..5f483a2 100644 --- a/include/rok4/style/Style.h +++ b/include/rok4/style/Style.h @@ -55,6 +55,7 @@ class Style; #include "rok4/style/Pente.h" #include "rok4/style/Estompage.h" #include "rok4/style/Aspect.h" +#include "rok4/style/Terrainrgb.h" #include "rok4/enums/Interpolation.h" #include "rok4/utils/Configuration.h" #include "rok4/utils/StoragePool.h" @@ -163,6 +164,11 @@ private : * \~english \brief Define wether the server must compute a relief shadow */ Estompage* estompage; + /** + * \~french \brief Définit si un calcul de terrainrgb doit être appliqué + * \~english \brief Define wether the server must compute a RGB terrain + */ + Terrainrgb* terrainrgb; /** * \~french \brief Valeur de nodata attendue dans les données en entrée @@ -220,7 +226,7 @@ private : * \~english \brief Style is allowed ? */ bool handle (int spp) { - if (estompage_defined() || pente_defined() || aspect_defined()) { + if (estompage_defined() || pente_defined() || aspect_defined() || terrainrgb_defined()) { return (spp == 1); } else { return true; @@ -238,7 +244,11 @@ private : } else { return 4; } - } else { + } + else if (terrainrgb_defined()){ + return 3; + } + else { if (estompage_defined() || pente_defined() || aspect_defined()) { return 1; } else { @@ -246,6 +256,7 @@ private : return orig_channels; } } + } /** @@ -253,7 +264,7 @@ private : * \~english \brief Which sample format after style */ SampleFormat::eSampleFormat get_sample_format (SampleFormat::eSampleFormat sf) { - if (palette && ! palette->is_empty()) { + if ((palette && ! palette->is_empty()) || terrainrgb_defined()) { return SampleFormat::UINT8; } else { return sf; @@ -293,7 +304,7 @@ private : return false; } - if (estompage_defined() || pente_defined() || aspect_defined()) { + if (estompage_defined() || pente_defined() || aspect_defined() || terrainrgb_defined()) { return false; } else { return true; @@ -348,6 +359,17 @@ private : return &legends; } + /** + * \~french + * \brief Détermine si le style décrit une table de correspondance + * \return true si oui + * \~english + * \brief Determine if the style describe a lookup table + * \return true if it does + */ + inline bool palette_defined() { + return (palette != 0); + } /** * \~french * \brief Retourne la table de correspondance @@ -422,6 +444,27 @@ private : inline Aspect* get_aspect() { return aspect; } + + /** + * \~french + * \brief Return vrai si le style est un terrainrgb + * \return bool + * \~english + * \brief Return true if the style is an rgb terrain + * \return bool + */ + inline bool terrainrgb_defined() { + return (terrainrgb != 0); + } + /** + * \~french + * \brief Retourne le terrainrgb + * \~english + * \brief Return rgb terrain + */ + inline Terrainrgb* get_terrainrgb() { + return terrainrgb; + } /** diff --git a/include/rok4/style/Terrainrgb.h b/include/rok4/style/Terrainrgb.h new file mode 100644 index 0000000..58f80ab --- /dev/null +++ b/include/rok4/style/Terrainrgb.h @@ -0,0 +1,102 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + + /** + * \file Terrainrgb.h + ** \~french + * \brief D�finition de la classe Terrainrgb + ** \~english + * \brief Define class Terrainrgb + */ + + +#pragma once + +#include "rok4/utils/Configuration.h" + +#include +#include +#include +#include + +class Terrainrgb : public Configuration +{ +public: + /** \~french + * \brief min_elevation : élévation minimale à partir de laquelle est calculée la couleur + ** \~english + * \brief min_elevation : minimum elevation from which the color is calculated + */ + float min_elevation; + + /** \~french + * \brief step : résolution verticale + ** \~english + * \brief step : vertical resolution + */ + float step; + + /** \~french + * \brief noData : valeur de nodata pour l'image source + ** \~english + * \brief noData : value of nodata for the source image + */ + float input_nodata_value; + + /** \~french + * \brief noData : valeur de nodata pour le terrainrgb + ** \~english + * \brief noData : value of nodata for the RGB terrain + */ + float terrainrgb_nodata_value; + + /** + * \~french + * \brief Constructeurs avec des arguments + * \~english + * \brief Constructor with arguments + */ + Terrainrgb(json11::Json doc); + + /** + * \~french + * \brief Destructeur + * \~english + * \brief Destructor + */ + virtual ~Terrainrgb(); +}; diff --git a/src/image/PaletteImage.cpp b/src/image/PaletteImage.cpp index 4843964..d4beba8 100644 --- a/src/image/PaletteImage.cpp +++ b/src/image/PaletteImage.cpp @@ -40,7 +40,7 @@ #include int PaletteImage::get_line ( float* buffer, int line ) { - if ( source_image->get_channels() == 1 && ! palette->is_empty() ) { + if ( source_image->get_channels() == 1 && palette != NULL && ! palette->is_empty() ) { return _getline ( buffer, line ); } else { return source_image->get_line ( buffer, line ); @@ -48,7 +48,7 @@ int PaletteImage::get_line ( float* buffer, int line ) { } int PaletteImage::get_line ( uint16_t* buffer, int line ) { - if ( source_image->get_channels() == 1 && ! palette->is_empty() ) { + if ( source_image->get_channels() == 1 && palette != NULL && ! palette->is_empty() ) { return _getline ( buffer, line ); } else { return source_image->get_line ( buffer, line ); @@ -56,7 +56,7 @@ int PaletteImage::get_line ( uint16_t* buffer, int line ) { } int PaletteImage::get_line ( uint8_t* buffer, int line ) { - if ( source_image->get_channels() == 1 && ! palette->is_empty() ) { + if ( source_image->get_channels() == 1 && palette != NULL && ! palette->is_empty() ) { return _getline ( buffer, line ); } else { return source_image->get_line ( buffer, line ); diff --git a/src/image/TerrainrgbImage.cpp b/src/image/TerrainrgbImage.cpp new file mode 100644 index 0000000..f7f4167 --- /dev/null +++ b/src/image/TerrainrgbImage.cpp @@ -0,0 +1,108 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + + /** + * \file TerrainrgbImage.cpp + * \~french + * \brief Implémentation de la classe TerrainrgbImage permettant l'application du terrainrgb à une image. + * \~english + * \brief Implement the TerrainrgbImage Class handling computing of Terrainrgb style to an image. + */ +#include "image/TerrainrgbImage.h" + +#include + +int TerrainrgbImage::get_line(float *buffer, int line) { + if (source_image->get_channels() == 1) { + return _getline(buffer, line); + } else { + return source_image->get_line(buffer, line); + } +} + +int TerrainrgbImage::get_line(uint16_t *buffer, int line) { + if (source_image->get_channels() == 1) { + return _getline(buffer, line); + } else { + return source_image->get_line(buffer, line); + } +} + +int TerrainrgbImage::get_line(uint8_t *buffer, int line) { + if (source_image->get_channels() == 1) { + return _getline(buffer, line); + } else { + return source_image->get_line(buffer, line); + } +} + +TerrainrgbImage::TerrainrgbImage(Image *image, Terrainrgb *terrainrgb) : Image(image->get_width(), image->get_height(), 1, image->get_bbox()), source_image(image), terrainrgb(terrainrgb) { + if (source_image->get_channels() == 1) { + channels = 3; + } else { + channels = image->get_channels(); + } +} + +TerrainrgbImage::~TerrainrgbImage() { + delete source_image; +} + +template +int TerrainrgbImage::_getline ( T* buffer, int line ) { + float* source = new float[source_image->get_width() * source_image->get_channels()]; + source_image->get_line ( source, line ); + switch ( channels ) { + case 3: + for (int i = 0; i < source_image->get_width() ; i++ ) { + + // découpage de l'altitude en RGB suivant la formule suivante : height = min_elevation + ((Red * 256 * 256 + Green * 256 + Blue) * step) + int base = (std::max( *(source+i), terrainrgb->min_elevation) - terrainrgb->min_elevation) / terrainrgb->step; + int red = (base / (256 * 256) % 256); + int green = ((base - red * 256 * 256) / 256 % 256); + int blue = (base - red * 256 * 256 - green * 256); + + * ( buffer+i*3 ) = (T) red; + * ( buffer+i*3+1 ) = (T) green; + * ( buffer+i*3+2 ) = (T) blue; + } + break; + } + + delete[] source; + return width * sizeof ( T ) * channels; +} diff --git a/src/style/Style.cpp b/src/style/Style.cpp index 4962dc8..2d0ef49 100644 --- a/src/style/Style.cpp +++ b/src/style/Style.cpp @@ -61,6 +61,7 @@ bool Style::parse(json11::Json& doc) { aspect = 0; estompage = 0; palette = 0; + terrainrgb = 0; input_nodata_value = NULL; output_nodata_value = NULL; @@ -105,10 +106,12 @@ bool Style::parse(json11::Json& doc) { legends.push_back(leg); } - palette = new Palette(doc["palette"].object_items()); - if (! palette->is_ok()) { - error_message = "Palette issue for style " + id + ": " + palette->get_error_message(); + if (doc["palette"].is_object()) { + palette = new Palette(doc["palette"].object_items()); + if (! palette->is_ok()) { + error_message = "Palette issue for style " + id + ": " + palette->get_error_message(); return false; + } } if (doc["estompage"].is_object()) { @@ -143,6 +146,17 @@ bool Style::parse(json11::Json& doc) { } } + if (doc["terrainrgb"].is_object()) { + if (estompage != 0 || pente != 0 || aspect !=0 || palette !=0) { + error_message = "Style " + id + " define exposition, estompage, pente or palette rules"; + return false; + } + terrainrgb = new Terrainrgb(doc["terrainrgb"].object_items()); + if (! terrainrgb->is_ok()) { + error_message = "Terrainrgb issue for style " + id + ": " + terrainrgb->get_error_message(); + return false; + } + } return true; } @@ -152,6 +166,7 @@ Style::Style ( std::string path ) : Configuration(path) { estompage = 0; palette = 0; aspect = 0; + terrainrgb = 0; input_nodata_value = NULL; output_nodata_value = NULL; @@ -218,7 +233,11 @@ Style::Style ( std::string path ) : Configuration(path) { else if (pente_defined()) { input_nodata_value = new int[1]; input_nodata_value[0] = (int) pente->input_nodata_value; - } + } + else if (terrainrgb_defined()) { + input_nodata_value = new int[1]; + input_nodata_value[0] = (int) terrainrgb->input_nodata_value; + } else if (palette && ! palette->is_empty()) { input_nodata_value = new int[1]; input_nodata_value[0] = (int) palette->get_colours_map()->begin()->first; @@ -241,8 +260,8 @@ Style::Style ( std::string path ) : Configuration(path) { } } else if (estompage_defined()) { - output_nodata_value = new int[1]; - output_nodata_value[0] = (int) estompage->estompage_nodata_value; + output_nodata_value = new int[1]; + output_nodata_value[0] = (int) estompage->estompage_nodata_value; } else if (aspect_defined()) { output_nodata_value = new int[1]; @@ -252,6 +271,12 @@ Style::Style ( std::string path ) : Configuration(path) { output_nodata_value = new int[1]; output_nodata_value[0] = (int) pente->slope_nodata_value; } + else if (terrainrgb_defined()) { + output_nodata_value = new int[3]; + output_nodata_value[0] = 0; + output_nodata_value[1] = 0; + output_nodata_value[2] = 0; + } } Style::~Style() { @@ -267,6 +292,9 @@ Style::~Style() { if (aspect != 0) { delete aspect; } + if (terrainrgb != 0) { + delete terrainrgb; + } if (input_nodata_value != NULL) { delete[] input_nodata_value; } diff --git a/src/style/Terrainrgb.cpp b/src/style/Terrainrgb.cpp new file mode 100644 index 0000000..c0992d8 --- /dev/null +++ b/src/style/Terrainrgb.cpp @@ -0,0 +1,70 @@ +/* + * Copyright © (2011) Institut national de l'information + * géographique et forestière + * + * Géoportail SAV + * + * This software is a computer program whose purpose is to publish geographic + * data using OGC WMS and WMTS protocol. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * + * knowledge of the CeCILL-C license and that you accept its terms. + */ + + /** + * \file Terrainrgb.cpp + * \~french + * \brief Implémentation de la classe Terrainrgb modélisant un terrainrgb. + * \~english + * \brief Implement the Terrainrgb Class handling RGB terrain definition. + */ + +#include "style/Terrainrgb.h" +#include +#include "zlib.h" +#include +#include "byteswap.h" +#include + +Terrainrgb::Terrainrgb(json11::Json doc) : Configuration() +{ + + if (doc["min_elevation"].is_number()) { + min_elevation = doc["min_elevation"].number_value(); + } else { + min_elevation = -10000; + } + if (doc["step"].is_number()) { + step = doc["step"].number_value(); + } else { + step = 0.1; + } + input_nodata_value=min_elevation; +} + +Terrainrgb::~Terrainrgb() { +}