LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mvt - mvt_tile.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 136 143 95.1 %
Date: 2024-11-21 22:18:42 Functions: 36 37 97.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  MVT Translator
       4             :  * Purpose:  Mapbox Vector Tile decoder and encoder
       5             :  * Author:   Even Rouault, Even Rouault <even dot rouault at spatialys dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef MVT_TILE_H
      14             : #define MVT_TILE_H
      15             : 
      16             : #include "cpl_port.h"
      17             : 
      18             : #include <memory>
      19             : #include <string>
      20             : #include <vector>
      21             : 
      22             : /* See
      23             :  * https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto
      24             :  */
      25             : constexpr int knLAYER = 3;
      26             : 
      27             : constexpr int knLAYER_NAME = 1;
      28             : constexpr int knLAYER_FEATURES = 2;
      29             : constexpr int knLAYER_KEYS = 3;
      30             : constexpr int knLAYER_VALUES = 4;
      31             : constexpr int knLAYER_EXTENT = 5;
      32             : constexpr int knLAYER_VERSION = 15;
      33             : 
      34             : constexpr int knVALUE_STRING = 1;
      35             : constexpr int knVALUE_FLOAT = 2;
      36             : constexpr int knVALUE_DOUBLE = 3;
      37             : constexpr int knVALUE_INT = 4;
      38             : constexpr int knVALUE_UINT = 5;
      39             : constexpr int knVALUE_SINT = 6;
      40             : constexpr int knVALUE_BOOL = 7;
      41             : 
      42             : constexpr int knFEATURE_ID = 1;
      43             : constexpr int knFEATURE_TAGS = 2;
      44             : constexpr int knFEATURE_TYPE = 3;
      45             : constexpr int knFEATURE_GEOMETRY = 4;
      46             : 
      47             : constexpr int knGEOM_TYPE_UNKNOWN = 0;
      48             : constexpr int knGEOM_TYPE_POINT = 1;
      49             : constexpr int knGEOM_TYPE_LINESTRING = 2;
      50             : constexpr int knGEOM_TYPE_POLYGON = 3;
      51             : 
      52             : constexpr int knCMD_MOVETO = 1;
      53             : constexpr int knCMD_LINETO = 2;
      54             : constexpr int knCMD_CLOSEPATH = 7;
      55             : 
      56             : constexpr unsigned knDEFAULT_EXTENT = 4096;
      57             : 
      58             : /************************************************************************/
      59             : /*                         MVTTileLayerValue                            */
      60             : /************************************************************************/
      61             : 
      62             : class MVTTileLayerValue
      63             : {
      64             :   public:
      65             :     enum class ValueType
      66             :     {
      67             :         NONE,
      68             :         STRING,
      69             :         FLOAT,
      70             :         DOUBLE,
      71             :         INT,
      72             :         UINT,
      73             :         SINT,
      74             :         BOOL,
      75             :         STRING_MAX_8,  // optimization for short strings.
      76             :     };
      77             : 
      78             :   private:
      79             :     // Layout optimized for small memory footprint
      80             :     union
      81             :     {
      82             :         float m_fValue;
      83             :         double m_dfValue;
      84             :         GInt64 m_nIntValue;
      85             :         GUInt64 m_nUIntValue;
      86             :         bool m_bBoolValue;
      87             :         char *m_pszValue;
      88             :         char m_achValue[8];  // optimization for short strings
      89             :     };
      90             : 
      91             :     ValueType m_eType = ValueType::NONE;
      92             : 
      93             :     void unset();
      94             : 
      95             :   public:
      96             :     MVTTileLayerValue();
      97             :     ~MVTTileLayerValue();
      98             :     MVTTileLayerValue(const MVTTileLayerValue &oOther);
      99             :     MVTTileLayerValue &operator=(const MVTTileLayerValue &oOther);
     100             : 
     101             :     bool operator<(const MVTTileLayerValue &rhs) const;
     102             : 
     103        7360 :     ValueType getType() const
     104             :     {
     105        7360 :         return m_eType;
     106             :     }
     107             : 
     108        4920 :     bool isNumeric() const
     109             :     {
     110        4886 :         return m_eType == ValueType::FLOAT || m_eType == ValueType::DOUBLE ||
     111       12716 :                m_eType == ValueType::INT || m_eType == ValueType::UINT ||
     112        7830 :                m_eType == ValueType::SINT;
     113             :     }
     114             : 
     115        2783 :     bool isString() const
     116             :     {
     117        3745 :         return m_eType == ValueType::STRING ||
     118        3745 :                m_eType == ValueType::STRING_MAX_8;
     119             :     }
     120             : 
     121             :     float getFloatValue() const
     122             :     {
     123             :         return m_fValue;
     124             :     }
     125             : 
     126             :     double getDoubleValue() const
     127             :     {
     128             :         return m_dfValue;
     129             :     }
     130             : 
     131             :     GInt64 getIntValue() const
     132             :     {
     133             :         return m_nIntValue;
     134             :     }
     135             : 
     136         881 :     GUInt64 getUIntValue() const
     137             :     {
     138         881 :         return m_nUIntValue;
     139             :     }
     140             : 
     141          13 :     bool getBoolValue() const
     142             :     {
     143          13 :         return m_bBoolValue;
     144             :     }
     145             : 
     146        2030 :     double getNumericValue() const
     147             :     {
     148        2030 :         if (m_eType == ValueType::FLOAT)
     149          34 :             return m_fValue;
     150        1996 :         if (m_eType == ValueType::DOUBLE)
     151        1023 :             return m_dfValue;
     152         973 :         if (m_eType == ValueType::INT || m_eType == ValueType::SINT)
     153          20 :             return static_cast<double>(m_nIntValue);
     154         953 :         if (m_eType == ValueType::UINT)
     155         953 :             return static_cast<double>(m_nUIntValue);
     156           0 :         return 0.0;
     157             :     }
     158             : 
     159        2676 :     std::string getStringValue() const
     160             :     {
     161        2676 :         if (m_eType == ValueType::STRING)
     162        1751 :             return m_pszValue;
     163         925 :         else if (m_eType == ValueType::STRING_MAX_8)
     164             :         {
     165             :             char szBuf[8 + 1];
     166         925 :             memcpy(szBuf, m_achValue, 8);
     167         925 :             szBuf[8] = 0;
     168         925 :             return szBuf;
     169             :         }
     170           0 :         return std::string();
     171             :     }
     172             : 
     173             :     void setStringValue(const std::string &osValue);
     174             : 
     175          34 :     void setFloatValue(float fValue)
     176             :     {
     177          34 :         unset();
     178          34 :         m_eType = ValueType::FLOAT;
     179          34 :         m_fValue = fValue;
     180          34 :     }
     181             : 
     182        2767 :     void setDoubleValue(double dfValue)
     183             :     {
     184        2767 :         unset();
     185        2767 :         m_eType = ValueType::DOUBLE;
     186        2767 :         m_dfValue = dfValue;
     187        2767 :     }
     188             : 
     189           0 :     void setIntValue(GInt64 nVal)
     190             :     {
     191           0 :         unset();
     192           0 :         m_eType = ValueType::INT;
     193           0 :         m_nIntValue = nVal;
     194           0 :     }
     195             : 
     196        1021 :     void setUIntValue(GUInt64 nVal)
     197             :     {
     198        1021 :         unset();
     199        1021 :         m_eType = ValueType::UINT;
     200        1021 :         m_nUIntValue = nVal;
     201        1021 :     }
     202             : 
     203          21 :     void setSIntValue(GInt64 nVal)
     204             :     {
     205          21 :         unset();
     206          21 :         m_eType = ValueType::SINT;
     207          21 :         m_nIntValue = nVal;
     208          21 :     }
     209             : 
     210          26 :     void setBoolValue(bool bVal)
     211             :     {
     212          26 :         unset();
     213          26 :         m_eType = ValueType::BOOL;
     214          26 :         m_bBoolValue = bVal;
     215          26 :     }
     216             : 
     217             :     void setValue(double dfVal);
     218             : 
     219             :     void setValue(int nVal)
     220             :     {
     221             :         setValue(static_cast<GInt64>(nVal));
     222             :     }
     223             : 
     224         143 :     void setValue(GInt64 nVal)
     225             :     {
     226         143 :         if (nVal < 0)
     227           3 :             setSIntValue(nVal);
     228             :         else
     229         140 :             setUIntValue(nVal);
     230         143 :     }
     231             : 
     232             :     size_t getSize() const;
     233             :     void write(GByte **ppabyData) const;
     234             :     bool read(const GByte **ppabyData, const GByte *pabyEnd);
     235             : };
     236             : 
     237             : /************************************************************************/
     238             : /*                       MVTTileLayerFeature                            */
     239             : /************************************************************************/
     240             : 
     241             : class MVTTileLayer;
     242             : 
     243             : class MVTTileLayerFeature
     244             : {
     245             :   public:
     246             :     enum class GeomType : char
     247             :     {
     248             :         UNKNOWN = 0,
     249             :         POINT = 1,
     250             :         LINESTRING = 2,
     251             :         POLYGON = 3
     252             :     };
     253             : 
     254             :   private:
     255             :     mutable size_t m_nCachedSize = 0;
     256             :     GUInt64 m_nId = 0;
     257             :     std::vector<GUInt32> m_anTags;
     258             :     std::vector<GUInt32> m_anGeometry;
     259             :     GeomType m_eType = GeomType::UNKNOWN;
     260             :     mutable bool m_bCachedSize = false;
     261             :     bool m_bHasId = false;
     262             :     bool m_bHasType = false;
     263             :     MVTTileLayer *m_poOwner = nullptr;
     264             : 
     265             :   public:
     266             :     MVTTileLayerFeature();
     267             :     void setOwner(MVTTileLayer *poOwner);
     268             : 
     269        1592 :     bool hasId() const
     270             :     {
     271        1592 :         return m_bHasId;
     272             :     }
     273             : 
     274          53 :     GUInt64 getId() const
     275             :     {
     276          53 :         return m_nId;
     277             :     }
     278             : 
     279        1578 :     const std::vector<GUInt32> &getTags() const
     280             :     {
     281        1578 :         return m_anTags;
     282             :     }
     283             : 
     284             :     bool hasType() const
     285             :     {
     286             :         return m_bHasType;
     287             :     }
     288             : 
     289        4696 :     GeomType getType() const
     290             :     {
     291        4696 :         return m_eType;
     292             :     }
     293             : 
     294        4122 :     GUInt32 getGeometryCount() const
     295             :     {
     296        4122 :         return static_cast<GUInt32>(m_anGeometry.size());
     297             :     }
     298             : 
     299        1687 :     const std::vector<GUInt32> &getGeometry() const
     300             :     {
     301        1687 :         return m_anGeometry;
     302             :     }
     303             : 
     304         159 :     void setId(GUInt64 nId)
     305             :     {
     306         159 :         m_bHasId = true;
     307         159 :         m_nId = nId;
     308         159 :         invalidateCachedSize();
     309         159 :     }
     310             : 
     311       26298 :     void addTag(GUInt32 nTag)
     312             :     {
     313       26298 :         m_anTags.push_back(nTag);
     314       26302 :         invalidateCachedSize();
     315       26296 :     }
     316             : 
     317        7186 :     void setType(GeomType eType)
     318             :     {
     319        7186 :         m_bHasType = true;
     320        7186 :         m_eType = eType;
     321        7186 :         invalidateCachedSize();
     322        7186 :     }
     323             : 
     324        2608 :     void resizeGeometryArray(GUInt32 nNewSize)
     325             :     {
     326        2608 :         m_anGeometry.resize(nNewSize);
     327        2605 :         invalidateCachedSize();
     328        2605 :     }
     329             : 
     330       14414 :     void addGeometry(GUInt32 nGeometry)
     331             :     {
     332       14414 :         m_anGeometry.push_back(nGeometry);
     333       14431 :         invalidateCachedSize();
     334       14419 :     }
     335             : 
     336         634 :     void setGeometry(GUInt32 nIdx, GUInt32 nVal)
     337             :     {
     338         634 :         m_anGeometry[nIdx] = nVal;
     339         629 :         invalidateCachedSize();
     340         628 :     }
     341             : 
     342        1592 :     void setGeometry(const std::vector<GUInt32> &anGeometry)
     343             :     {
     344        1592 :         m_anGeometry = anGeometry;
     345        1592 :         invalidateCachedSize();
     346        1592 :     }
     347             : 
     348             :     size_t getSize() const;
     349             :     void write(GByte **ppabyData) const;
     350             :     bool read(const GByte **ppabyData, const GByte *pabyEnd);
     351             : 
     352             :     void invalidateCachedSize();
     353             : };
     354             : 
     355             : /************************************************************************/
     356             : /*                           MVTTileLayer                               */
     357             : /************************************************************************/
     358             : 
     359             : class MVTTile;
     360             : 
     361             : class MVTTileLayer
     362             : {
     363             :     mutable bool m_bCachedSize = false;
     364             :     mutable size_t m_nCachedSize = 0;
     365             :     GUInt32 m_nVersion = 1;
     366             :     std::string m_osName;
     367             :     std::vector<std::shared_ptr<MVTTileLayerFeature>> m_apoFeatures;
     368             :     std::vector<std::string> m_aosKeys;
     369             :     std::vector<MVTTileLayerValue> m_aoValues;
     370             :     bool m_bHasExtent = false;
     371             :     GUInt32 m_nExtent = 4096;
     372             :     MVTTile *m_poOwner = nullptr;
     373             : 
     374             :   public:
     375             :     MVTTileLayer();
     376             :     void setOwner(MVTTile *poOwner);
     377             : 
     378             :     GUInt32 getVersion() const
     379             :     {
     380             :         return m_nVersion;
     381             :     }
     382             : 
     383             :     const std::string &getName() const
     384             :     {
     385             :         return m_osName;
     386             :     }
     387             : 
     388        1592 :     const std::vector<std::shared_ptr<MVTTileLayerFeature>> &getFeatures() const
     389             :     {
     390        1592 :         return m_apoFeatures;
     391             :     }
     392             : 
     393        1578 :     const std::vector<std::string> &getKeys() const
     394             :     {
     395        1578 :         return m_aosKeys;
     396             :     }
     397             : 
     398        1578 :     const std::vector<MVTTileLayerValue> &getValues() const
     399             :     {
     400        1578 :         return m_aoValues;
     401             :     }
     402             : 
     403             :     GUInt32 getExtent() const
     404             :     {
     405             :         return m_nExtent;
     406             :     }
     407             : 
     408        2939 :     void setVersion(GUInt32 nVersion)
     409             :     {
     410        2939 :         m_nVersion = nVersion;
     411        2939 :         invalidateCachedSize();
     412        2939 :     }
     413             : 
     414        2939 :     void setName(const std::string &osName)
     415             :     {
     416        2939 :         m_osName = osName;
     417        2939 :         invalidateCachedSize();
     418        2939 :     }
     419             : 
     420             :     size_t addFeature(std::shared_ptr<MVTTileLayerFeature> poFeature);
     421             : 
     422       12352 :     GUInt32 addKey(const std::string &osKey)
     423             :     {
     424       12352 :         m_aosKeys.push_back(osKey);
     425       12354 :         invalidateCachedSize();
     426       12352 :         return static_cast<GUInt32>(m_aosKeys.size()) - 1;
     427             :     }
     428             : 
     429       12480 :     GUInt32 addValue(const MVTTileLayerValue &oValue)
     430             :     {
     431       12480 :         m_aoValues.push_back(oValue);
     432       12478 :         invalidateCachedSize();
     433       12473 :         return static_cast<GUInt32>(m_aoValues.size()) - 1;
     434             :     }
     435             : 
     436        1347 :     void setExtent(GUInt32 nExtent)
     437             :     {
     438        1347 :         m_nExtent = nExtent;
     439        1347 :         m_bHasExtent = true;
     440        1347 :         invalidateCachedSize();
     441        1347 :     }
     442             : 
     443             :     size_t getSize() const;
     444             :     void write(GByte **ppabyData) const;
     445             :     void write(GByte *pabyData) const;
     446             :     std::string write() const;
     447             :     bool read(const GByte **ppabyData, const GByte *pabyEnd);
     448             :     bool read(const GByte *pabyData, const GByte *pabyEnd);
     449             : 
     450             :     void invalidateCachedSize();
     451             : };
     452             : 
     453             : /************************************************************************/
     454             : /*                              MVTTile                                 */
     455             : /************************************************************************/
     456             : 
     457             : class MVTTile
     458             : {
     459             :     std::vector<std::shared_ptr<MVTTileLayer>> m_apoLayers;
     460             :     mutable size_t m_nCachedSize = 0;
     461             :     mutable bool m_bCachedSize = false;
     462             : 
     463             :   public:
     464             :     MVTTile();
     465             : 
     466             :     const std::vector<std::shared_ptr<MVTTileLayer>> &getLayers() const
     467             :     {
     468             :         return m_apoLayers;
     469             :     }
     470             : 
     471          13 :     void clear()
     472             :     {
     473          13 :         m_apoLayers.clear();
     474          13 :         invalidateCachedSize();
     475          13 :     }
     476             : 
     477             :     void addLayer(std::shared_ptr<MVTTileLayer> poLayer);
     478             :     size_t getSize() const;
     479             :     void write(GByte **ppabyData) const;
     480             :     void write(GByte *pabyData) const;
     481             :     std::string write() const;
     482             : #ifdef ADD_MVT_TILE_READ
     483             :     bool read(const GByte **ppabyData, const GByte *pabyEnd);
     484             :     bool read(const GByte *pabyData, const GByte *pabyEnd);
     485             : #endif
     486       17236 :     void invalidateCachedSize()
     487             :     {
     488       17236 :         m_bCachedSize = false;
     489       17236 :         m_nCachedSize = 0;
     490       17236 :     }
     491             : };
     492             : 
     493             : #endif  // MVT_TILE_H

Generated by: LCOV version 1.14