LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mvt - mvt_tile.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 410 441 93.0 %
Date: 2025-01-18 12:42:00 Functions: 36 36 100.0 %

          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             : #include "gpb.h"
      14             : 
      15             : #include <cmath>
      16             : #include <limits>
      17             : #include <memory>
      18             : #include <vector>
      19             : 
      20             : #include "mvt_tile.h"
      21             : 
      22             : constexpr int knSIZE_KEY = 1;
      23             : 
      24             : /************************************************************************/
      25             : /*                        MVTTileLayerValue()                           */
      26             : /************************************************************************/
      27             : 
      28        9467 : MVTTileLayerValue::MVTTileLayerValue() : m_nUIntValue(0)
      29             : {
      30        9467 : }
      31             : 
      32       35796 : MVTTileLayerValue::MVTTileLayerValue(const MVTTileLayerValue &oOther)
      33             : {
      34       35796 :     operator=(oOther);
      35       35822 : }
      36             : 
      37             : /************************************************************************/
      38             : /*                       ~MVTTileLayerValue()                           */
      39             : /************************************************************************/
      40             : 
      41       90625 : MVTTileLayerValue::~MVTTileLayerValue()
      42             : {
      43       45303 :     unset();
      44       45322 : }
      45             : 
      46             : /************************************************************************/
      47             : /*                            operator=                                 */
      48             : /************************************************************************/
      49             : 
      50       35795 : MVTTileLayerValue &MVTTileLayerValue::operator=(const MVTTileLayerValue &oOther)
      51             : 
      52             : {
      53       35795 :     if (this != &oOther)
      54             :     {
      55       35799 :         unset();
      56       35781 :         m_eType = oOther.m_eType;
      57       35781 :         if (m_eType == ValueType::STRING)
      58             :         {
      59        9467 :             const size_t nSize = strlen(oOther.m_pszValue);
      60        9467 :             m_pszValue = static_cast<char *>(CPLMalloc(1 + nSize));
      61        9523 :             memcpy(m_pszValue, oOther.m_pszValue, nSize);
      62        9523 :             m_pszValue[nSize] = 0;
      63             :         }
      64             :         else
      65             :         {
      66       26314 :             m_nUIntValue = oOther.m_nUIntValue;
      67             :         }
      68             :     }
      69       35833 :     return *this;
      70             : }
      71             : 
      72             : /************************************************************************/
      73             : /*                            operator<                                 */
      74             : /************************************************************************/
      75             : 
      76       54076 : bool MVTTileLayerValue::operator<(const MVTTileLayerValue &rhs) const
      77             : {
      78       54076 :     if (m_eType < rhs.m_eType)
      79        4345 :         return false;
      80       49731 :     if (m_eType > rhs.m_eType)
      81       17484 :         return true;
      82       32247 :     if (m_eType == ValueType::NONE)
      83           0 :         return false;
      84       32247 :     if (m_eType == ValueType::STRING)
      85       14337 :         return strcmp(m_pszValue, rhs.m_pszValue) < 0;
      86       17910 :     if (m_eType == ValueType::FLOAT)
      87          98 :         return m_fValue < rhs.m_fValue;
      88       17812 :     if (m_eType == ValueType::DOUBLE)
      89        9346 :         return m_dfValue < rhs.m_dfValue;
      90        8466 :     if (m_eType == ValueType::INT)
      91           0 :         return m_nIntValue < rhs.m_nIntValue;
      92        8466 :     if (m_eType == ValueType::UINT)
      93        2400 :         return m_nUIntValue < rhs.m_nUIntValue;
      94        6066 :     if (m_eType == ValueType::SINT)
      95          84 :         return m_nIntValue < rhs.m_nIntValue;
      96        5982 :     if (m_eType == ValueType::BOOL)
      97          80 :         return m_bBoolValue < rhs.m_bBoolValue;
      98        5902 :     if (m_eType == ValueType::STRING_MAX_8)
      99        5902 :         return strncmp(m_achValue, rhs.m_achValue, 8) < 0;
     100           0 :     CPLAssert(false);
     101             :     return false;
     102             : }
     103             : 
     104             : /************************************************************************/
     105             : /*                             unset()                                  */
     106             : /************************************************************************/
     107             : 
     108       90561 : void MVTTileLayerValue::unset()
     109             : {
     110       90561 :     if (m_eType == ValueType::STRING)
     111       13295 :         CPLFree(m_pszValue);
     112       90570 :     m_eType = ValueType::NONE;
     113       90570 :     m_nUIntValue = 0;
     114       90570 : }
     115             : 
     116             : /************************************************************************/
     117             : /*                            GetSizeMax8()                             */
     118             : /************************************************************************/
     119             : 
     120        6354 : static size_t GetSizeMax8(const char achValue[8])
     121             : {
     122        6354 :     size_t nSize = 0;
     123       27063 :     while (nSize < 8 && achValue[nSize] != 0)
     124       20709 :         nSize++;
     125        6354 :     return nSize;
     126             : }
     127             : 
     128             : /************************************************************************/
     129             : /*                        setStringValue()                              */
     130             : /************************************************************************/
     131             : 
     132        5598 : void MVTTileLayerValue::setStringValue(const std::string &osValue)
     133             : {
     134        5598 :     unset();
     135        5598 :     const size_t nSize = osValue.size();
     136        5598 :     if (nSize <= 8)
     137             :     {
     138        1889 :         m_eType = ValueType::STRING_MAX_8;
     139        1889 :         if (nSize)
     140        1889 :             memcpy(m_achValue, osValue.c_str(), nSize);
     141        1889 :         if (nSize < 8)
     142        1781 :             m_achValue[nSize] = 0;
     143             :     }
     144             :     else
     145             :     {
     146        3709 :         m_eType = ValueType::STRING;
     147        3709 :         m_pszValue = static_cast<char *>(CPLMalloc(1 + nSize));
     148        3709 :         memcpy(m_pszValue, osValue.c_str(), nSize);
     149        3709 :         m_pszValue[nSize] = 0;
     150             :     }
     151        5598 : }
     152             : 
     153             : /************************************************************************/
     154             : /*                          setValue()                                  */
     155             : /************************************************************************/
     156             : 
     157         140 : void MVTTileLayerValue::setValue(double dfVal)
     158             : {
     159         277 :     if (dfVal >= 0 &&
     160         277 :         dfVal <= static_cast<double>(std::numeric_limits<GUInt64>::max()) &&
     161         137 :         dfVal == static_cast<double>(static_cast<GUInt64>(dfVal)))
     162             :     {
     163           0 :         setUIntValue(static_cast<GUInt64>(dfVal));
     164             :     }
     165         280 :     else if (dfVal >= static_cast<double>(std::numeric_limits<GInt64>::min()) &&
     166         280 :              dfVal < 0 &&
     167           3 :              dfVal == static_cast<double>(static_cast<GInt64>(dfVal)))
     168             :     {
     169           0 :         setSIntValue(static_cast<GInt64>(dfVal));
     170             :     }
     171         280 :     else if (!std::isfinite(dfVal) ||
     172         140 :              (dfVal >= -std::numeric_limits<float>::max() &&
     173         140 :               dfVal <= std::numeric_limits<float>::max() &&
     174         140 :               dfVal == static_cast<float>(dfVal)))
     175             :     {
     176           6 :         setFloatValue(static_cast<float>(dfVal));
     177             :     }
     178             :     else
     179             :     {
     180         134 :         setDoubleValue(dfVal);
     181             :     }
     182         140 : }
     183             : 
     184             : /************************************************************************/
     185             : /*                            getSize()                                 */
     186             : /************************************************************************/
     187             : 
     188       23946 : size_t MVTTileLayerValue::getSize() const
     189             : {
     190       23946 :     switch (m_eType)
     191             :     {
     192           0 :         case ValueType::NONE:
     193           0 :             return 0;
     194        9442 :         case ValueType::STRING:
     195             :         {
     196        9442 :             const size_t nSize = strlen(m_pszValue);
     197        9442 :             return knSIZE_KEY + GetVarUIntSize(nSize) + nSize;
     198             :         }
     199        4801 :         case ValueType::STRING_MAX_8:
     200             :         {
     201        4801 :             const size_t nSize = GetSizeMax8(m_achValue);
     202        4788 :             return knSIZE_KEY + GetVarUIntSize(nSize) + nSize;
     203             :         }
     204         145 :         case ValueType::FLOAT:
     205         145 :             return knSIZE_KEY + sizeof(float);
     206        4655 :         case ValueType::DOUBLE:
     207        4655 :             return knSIZE_KEY + sizeof(double);
     208           0 :         case ValueType::INT:
     209           0 :             return knSIZE_KEY + GetVarIntSize(m_nIntValue);
     210        4806 :         case ValueType::UINT:
     211        4806 :             return knSIZE_KEY + GetVarUIntSize(m_nUIntValue);
     212          84 :         case ValueType::SINT:
     213          84 :             return knSIZE_KEY + GetVarSIntSize(m_nIntValue);
     214          52 :         case ValueType::BOOL:
     215          52 :             return knSIZE_KEY + 1;
     216           0 :         default:
     217           0 :             return 0;
     218             :     }
     219             : }
     220             : 
     221             : /************************************************************************/
     222             : /*                             write()                                  */
     223             : /************************************************************************/
     224             : 
     225        8005 : void MVTTileLayerValue::write(GByte **ppabyData) const
     226             : {
     227        8005 :     GByte *pabyData = *ppabyData;
     228             : 
     229        8005 :     switch (m_eType)
     230             :     {
     231        3156 :         case ValueType::STRING:
     232             :         {
     233        3156 :             const size_t nSize = strlen(m_pszValue);
     234        3156 :             WriteVarUIntSingleByte(&pabyData,
     235             :                                    MAKE_KEY(knVALUE_STRING, WT_DATA));
     236        3165 :             WriteVarUInt(&pabyData, nSize);
     237        3153 :             memcpy(pabyData, m_pszValue, nSize);
     238        3153 :             pabyData += nSize;
     239        3153 :             break;
     240             :         }
     241             : 
     242        1598 :         case ValueType::STRING_MAX_8:
     243             :         {
     244        1598 :             const size_t nSize = GetSizeMax8(m_achValue);
     245        1599 :             WriteVarUIntSingleByte(&pabyData,
     246             :                                    MAKE_KEY(knVALUE_STRING, WT_DATA));
     247        1594 :             WriteVarUInt(&pabyData, nSize);
     248        1590 :             if (nSize)
     249        1595 :                 memcpy(pabyData, m_achValue, nSize);
     250        1590 :             pabyData += nSize;
     251        1590 :             break;
     252             :         }
     253             : 
     254          49 :         case ValueType::FLOAT:
     255          49 :             WriteVarUIntSingleByte(&pabyData,
     256             :                                    MAKE_KEY(knVALUE_FLOAT, WT_32BIT));
     257          48 :             WriteFloat32(&pabyData, m_fValue);
     258          48 :             break;
     259             : 
     260        1553 :         case ValueType::DOUBLE:
     261        1553 :             WriteVarUIntSingleByte(&pabyData,
     262             :                                    MAKE_KEY(knVALUE_DOUBLE, WT_64BIT));
     263        1558 :             WriteFloat64(&pabyData, m_dfValue);
     264        1534 :             break;
     265             : 
     266           0 :         case ValueType::INT:
     267           0 :             WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knVALUE_INT, WT_VARINT));
     268           0 :             WriteVarInt(&pabyData, m_nIntValue);
     269           0 :             break;
     270             : 
     271        1590 :         case ValueType::UINT:
     272        1590 :             WriteVarUIntSingleByte(&pabyData,
     273             :                                    MAKE_KEY(knVALUE_UINT, WT_VARINT));
     274        1605 :             WriteVarUInt(&pabyData, m_nUIntValue);
     275        1594 :             break;
     276             : 
     277          28 :         case ValueType::SINT:
     278          28 :             WriteVarUIntSingleByte(&pabyData,
     279             :                                    MAKE_KEY(knVALUE_SINT, WT_VARINT));
     280          28 :             WriteVarSInt(&pabyData, m_nIntValue);
     281          27 :             break;
     282             : 
     283          17 :         case ValueType::BOOL:
     284          17 :             WriteVarUIntSingleByte(&pabyData,
     285             :                                    MAKE_KEY(knVALUE_BOOL, WT_VARINT));
     286          17 :             WriteVarUIntSingleByte(&pabyData, m_bBoolValue ? 1 : 0);
     287          16 :             break;
     288             : 
     289          14 :         default:
     290          14 :             break;
     291             :     }
     292             : 
     293        7976 :     CPLAssert(pabyData == *ppabyData + getSize());
     294        8009 :     *ppabyData = pabyData;
     295        8009 : }
     296             : 
     297             : /************************************************************************/
     298             : /*                             read()                                   */
     299             : /************************************************************************/
     300             : 
     301        4448 : bool MVTTileLayerValue::read(const GByte **ppabyData,
     302             :                              const GByte *pabyDataLimit)
     303             : {
     304        4448 :     const GByte *pabyData = *ppabyData;
     305             : 
     306             :     try
     307             :     {
     308        4448 :         unsigned int nKey = 0;
     309        4448 :         if (pabyData < pabyDataLimit)
     310             :         {
     311        4448 :             READ_FIELD_KEY(nKey);
     312             : 
     313        4448 :             if (nKey == MAKE_KEY(knVALUE_STRING, WT_DATA))
     314             :             {
     315        2656 :                 char *pszValue = nullptr;
     316        2656 :                 READ_TEXT(pabyData, pabyDataLimit, pszValue);
     317             :                 // cppcheck-suppress nullPointer
     318        2656 :                 setStringValue(pszValue);
     319        2656 :                 CPLFree(pszValue);
     320             :             }
     321        1792 :             else if (nKey == MAKE_KEY(knVALUE_FLOAT, WT_32BIT))
     322             :             {
     323          28 :                 setFloatValue(ReadFloat32(&pabyData, pabyDataLimit));
     324             :             }
     325        1764 :             else if (nKey == MAKE_KEY(knVALUE_DOUBLE, WT_64BIT))
     326             :             {
     327         853 :                 setDoubleValue(ReadFloat64(&pabyData, pabyDataLimit));
     328             :             }
     329         911 :             else if (nKey == MAKE_KEY(knVALUE_INT, WT_VARINT))
     330             :             {
     331           0 :                 GIntBig nVal = 0;
     332           0 :                 READ_VARINT64(pabyData, pabyDataLimit, nVal);
     333           0 :                 setIntValue(nVal);
     334             :             }
     335         911 :             else if (nKey == MAKE_KEY(knVALUE_UINT, WT_VARINT))
     336             :             {
     337         881 :                 GUIntBig nVal = 0;
     338         881 :                 READ_VARUINT64(pabyData, pabyDataLimit, nVal);
     339         881 :                 setUIntValue(nVal);
     340             :             }
     341          30 :             else if (nKey == MAKE_KEY(knVALUE_SINT, WT_VARINT))
     342             :             {
     343          18 :                 GIntBig nVal = 0;
     344          18 :                 READ_VARSINT64(pabyData, pabyDataLimit, nVal);
     345          18 :                 setSIntValue(nVal);
     346             :             }
     347          12 :             else if (nKey == MAKE_KEY(knVALUE_BOOL, WT_VARINT))
     348             :             {
     349          12 :                 unsigned nVal = 0;
     350          12 :                 READ_VARUINT32(pabyData, pabyDataLimit, nVal);
     351          12 :                 setBoolValue(nVal != 0);
     352             :             }
     353             :         }
     354        4448 :         *ppabyData = pabyData;
     355        4448 :         return true;
     356             :     }
     357           0 :     catch (const GPBException &)
     358             :     {
     359           0 :         return false;
     360             :     }
     361             : }
     362             : 
     363             : /************************************************************************/
     364             : /*                           MVTTileLayer()                             */
     365             : /************************************************************************/
     366             : 
     367        7358 : MVTTileLayerFeature::MVTTileLayerFeature()
     368             : {
     369        7352 : }
     370             : 
     371             : /************************************************************************/
     372             : /*                             setOwner()                               */
     373             : /************************************************************************/
     374             : 
     375        7315 : void MVTTileLayerFeature::setOwner(MVTTileLayer *poOwner)
     376             : {
     377        7315 :     CPLAssert(!m_poOwner);
     378        7315 :     m_poOwner = poOwner;
     379        7315 :     m_poOwner->invalidateCachedSize();
     380        7308 : }
     381             : 
     382             : /************************************************************************/
     383             : /*                       invalidateCachedSize()                         */
     384             : /************************************************************************/
     385             : 
     386       53710 : void MVTTileLayerFeature::invalidateCachedSize()
     387             : {
     388       53710 :     m_bCachedSize = false;
     389       53710 :     m_nCachedSize = 0;
     390       53710 :     if (m_poOwner)
     391       41378 :         m_poOwner->invalidateCachedSize();
     392       53579 : }
     393             : 
     394             : /************************************************************************/
     395             : /*                        GetPackedArraySize()                          */
     396             : /************************************************************************/
     397             : 
     398       10041 : static size_t GetPackedArraySize(const std::vector<GUInt32> &anVals)
     399             : {
     400       10041 :     size_t nPackedSize = 0;
     401       70525 :     for (const auto &nVal : anVals)
     402             :     {
     403       60765 :         nPackedSize += GetVarUIntSize(nVal);
     404             :     }
     405       10115 :     return nPackedSize;
     406             : }
     407             : 
     408             : /************************************************************************/
     409             : /*                            getSize()                                 */
     410             : /************************************************************************/
     411             : 
     412        9498 : size_t MVTTileLayerFeature::getSize() const
     413             : {
     414        9498 :     if (m_bCachedSize)
     415        6323 :         return m_nCachedSize;
     416        3175 :     m_bCachedSize = true;
     417        3175 :     m_nCachedSize = 0;
     418        3175 :     if (m_bHasId)
     419         100 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nId);
     420        3175 :     if (!m_anTags.empty())
     421             :     {
     422        1855 :         size_t nPackedSize = GetPackedArraySize(m_anTags);
     423        1883 :         m_nCachedSize += knSIZE_KEY;
     424        1883 :         m_nCachedSize += GetVarUIntSize(nPackedSize);
     425        1878 :         m_nCachedSize += nPackedSize;
     426             :     }
     427        3185 :     if (m_bHasType)
     428        3172 :         m_nCachedSize += knSIZE_KEY + 1;  // fixed size for m_eType
     429        3185 :     if (!m_anGeometry.empty())
     430             :     {
     431        3163 :         size_t nPackedSize = GetPackedArraySize(m_anGeometry);
     432        3176 :         m_nCachedSize += knSIZE_KEY;
     433        3176 :         m_nCachedSize += GetVarUIntSize(nPackedSize);
     434        3168 :         m_nCachedSize += nPackedSize;
     435             :     }
     436        3172 :     return m_nCachedSize;
     437             : }
     438             : 
     439             : /************************************************************************/
     440             : /*                        WriteUIntPackedArray()                        */
     441             : /************************************************************************/
     442             : 
     443        5038 : static void WriteUIntPackedArray(GByte **ppabyData, int nKey,
     444             :                                  const std::vector<GUInt32> &anVals)
     445             : {
     446        5038 :     GByte *pabyData = *ppabyData;
     447        5038 :     const size_t nPackedSize = GetPackedArraySize(anVals);
     448        5059 :     WriteVarUIntSingleByte(&pabyData, nKey);
     449        5049 :     WriteVarUInt(&pabyData, nPackedSize);
     450       35388 :     for (const auto &nVal : anVals)
     451             :     {
     452       30370 :         WriteVarUInt(&pabyData, nVal);
     453             :     }
     454        5047 :     *ppabyData = pabyData;
     455        5047 : }
     456             : 
     457             : /************************************************************************/
     458             : /*                             write()                                  */
     459             : /************************************************************************/
     460             : 
     461        3168 : void MVTTileLayerFeature::write(GByte **ppabyData) const
     462             : {
     463        3168 :     GByte *pabyData = *ppabyData;
     464             : 
     465        3168 :     if (m_bHasId)
     466             :     {
     467         104 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knFEATURE_ID, WT_VARINT));
     468         102 :         WriteVarUInt(&pabyData, m_nId);
     469             :     }
     470        3165 :     if (!m_anTags.empty())
     471             :     {
     472        1865 :         WriteUIntPackedArray(&pabyData, MAKE_KEY(knFEATURE_TAGS, WT_DATA),
     473        1865 :                              m_anTags);
     474             :     }
     475        3179 :     if (m_bHasType)
     476             :     {
     477        3171 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knFEATURE_TYPE, WT_VARINT));
     478        3162 :         WriteVarUIntSingleByte(&pabyData, static_cast<GUIntBig>(m_eType));
     479             :     }
     480        3169 :     if (!m_anGeometry.empty())
     481             :     {
     482        3156 :         WriteUIntPackedArray(&pabyData, MAKE_KEY(knFEATURE_GEOMETRY, WT_DATA),
     483        3156 :                              m_anGeometry);
     484             :     }
     485             : 
     486        3180 :     CPLAssert(pabyData == *ppabyData + getSize());
     487        3174 :     *ppabyData = pabyData;
     488        3174 : }
     489             : 
     490             : /************************************************************************/
     491             : /*                             read()                                   */
     492             : /************************************************************************/
     493             : 
     494        1688 : bool MVTTileLayerFeature::read(const GByte **ppabyData,
     495             :                                const GByte *pabyDataLimit)
     496             : {
     497        1688 :     const GByte *pabyData = *ppabyData;
     498             : 
     499             :     try
     500             :     {
     501        1688 :         unsigned int nKey = 0;
     502        6111 :         while (pabyData < pabyDataLimit)
     503             :         {
     504        4423 :             READ_FIELD_KEY(nKey);
     505        4423 :             if (nKey == MAKE_KEY(knFEATURE_ID, WT_VARINT))
     506             :             {
     507          53 :                 GUIntBig nID = 0;
     508          53 :                 READ_VARUINT64(pabyData, pabyDataLimit, nID);
     509          53 :                 setId(nID);
     510             :             }
     511        4370 :             else if (nKey == MAKE_KEY(knFEATURE_TAGS, WT_DATA))
     512             :             {
     513         994 :                 unsigned int nTagsSize = 0;
     514         994 :                 READ_SIZE(pabyData, pabyDataLimit, nTagsSize);
     515         994 :                 const GByte *pabyDataTagsEnd = pabyData + nTagsSize;
     516        9890 :                 while (pabyData < pabyDataTagsEnd)
     517             :                 {
     518        8896 :                     unsigned int nTag = 0;
     519        8896 :                     READ_VARUINT32(pabyData, pabyDataTagsEnd, nTag);
     520        8896 :                     addTag(nTag);
     521             :                 }
     522         994 :                 pabyData = pabyDataTagsEnd;
     523             :             }
     524        3376 :             else if (nKey == MAKE_KEY(knFEATURE_TYPE, WT_VARINT))
     525             :             {
     526        1688 :                 unsigned int nType = 0;
     527        1688 :                 READ_VARUINT32(pabyData, pabyDataLimit, nType);
     528        1688 :                 if (nType <= knGEOM_TYPE_POLYGON)
     529        1688 :                     setType(static_cast<GeomType>(nType));
     530             :             }
     531        1688 :             else if (nKey == MAKE_KEY(knFEATURE_GEOMETRY, WT_DATA))
     532             :             {
     533        1688 :                 unsigned int nGeometrySize = 0;
     534        1688 :                 READ_SIZE(pabyData, pabyDataLimit, nGeometrySize);
     535        1688 :                 const GByte *pabyDataGeometryEnd = pabyData + nGeometrySize;
     536        8940 :                 while (pabyData < pabyDataGeometryEnd)
     537             :                 {
     538        7252 :                     unsigned int nGeometry = 0;
     539        7252 :                     READ_VARUINT32(pabyData, pabyDataGeometryEnd, nGeometry);
     540        7252 :                     addGeometry(nGeometry);
     541             :                 }
     542        1688 :                 pabyData = pabyDataGeometryEnd;
     543             :             }
     544             :             else
     545             :             {
     546           0 :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     547             :             }
     548             :         }
     549        1688 :         *ppabyData = pabyData;
     550        1688 :         return true;
     551             :     }
     552           0 :     catch (const GPBException &)
     553             :     {
     554           0 :         return false;
     555             :     }
     556             : }
     557             : 
     558             : /************************************************************************/
     559             : /*                           MVTTileLayer()                             */
     560             : /************************************************************************/
     561             : 
     562        7094 : MVTTileLayer::MVTTileLayer()
     563             : {
     564        7062 : }
     565             : 
     566             : /************************************************************************/
     567             : /*                             setOwner()                               */
     568             : /************************************************************************/
     569             : 
     570        1401 : void MVTTileLayer::setOwner(MVTTile *poOwner)
     571             : {
     572        1401 :     CPLAssert(!m_poOwner);
     573        1401 :     m_poOwner = poOwner;
     574        1401 :     m_poOwner->invalidateCachedSize();
     575        1401 : }
     576             : 
     577             : /************************************************************************/
     578             : /*                       invalidateCachedSize()                         */
     579             : /************************************************************************/
     580             : 
     581       88311 : void MVTTileLayer::invalidateCachedSize()
     582             : {
     583       88311 :     m_bCachedSize = false;
     584       88311 :     m_nCachedSize = 0;
     585       88311 :     if (m_poOwner)
     586       14949 :         m_poOwner->invalidateCachedSize();
     587       88311 : }
     588             : 
     589             : /************************************************************************/
     590             : /*                          addFeature()                                */
     591             : /************************************************************************/
     592             : 
     593        7329 : size_t MVTTileLayer::addFeature(std::shared_ptr<MVTTileLayerFeature> poFeature)
     594             : {
     595        7329 :     poFeature->setOwner(this);
     596        7304 :     m_apoFeatures.push_back(poFeature);
     597        7338 :     invalidateCachedSize();
     598        7325 :     return m_apoFeatures.size() - 1;
     599             : }
     600             : 
     601             : /************************************************************************/
     602             : /*                            getSize()                                 */
     603             : /************************************************************************/
     604             : 
     605        7220 : size_t MVTTileLayer::getSize() const
     606             : {
     607        7220 :     if (m_bCachedSize)
     608        4291 :         return m_nCachedSize;
     609        2929 :     m_nCachedSize = knSIZE_KEY + GetTextSize(m_osName);
     610        6082 :     for (const auto &poFeature : m_apoFeatures)
     611             :     {
     612        3139 :         const size_t nFeatureSize = poFeature->getSize();
     613        3167 :         m_nCachedSize +=
     614        3176 :             knSIZE_KEY + GetVarUIntSize(nFeatureSize) + nFeatureSize;
     615             :     }
     616       10776 :     for (const auto &osKey : m_aosKeys)
     617             :     {
     618        7872 :         m_nCachedSize += knSIZE_KEY + GetTextSize(osKey);
     619             :     }
     620       10893 :     for (const auto &oValue : m_aoValues)
     621             :     {
     622        7962 :         const size_t nValueSize = oValue.getSize();
     623        8008 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(nValueSize) + nValueSize;
     624             :     }
     625        2913 :     if (m_bHasExtent)
     626             :     {
     627        1413 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nExtent);
     628             :     }
     629        2913 :     m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nVersion);
     630        2916 :     m_bCachedSize = true;
     631        2916 :     return m_nCachedSize;
     632             : }
     633             : 
     634             : /************************************************************************/
     635             : /*                             write()                                  */
     636             : /************************************************************************/
     637             : 
     638        2851 : void MVTTileLayer::write(GByte **ppabyData) const
     639             : {
     640        2851 :     GByte *pabyData = *ppabyData;
     641             : 
     642        2851 :     WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_NAME, WT_DATA));
     643        2871 :     WriteText(&pabyData, m_osName);
     644             : 
     645        6048 :     for (const auto &poFeature : m_apoFeatures)
     646             :     {
     647        3142 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_FEATURES, WT_DATA));
     648        3146 :         WriteVarUInt(&pabyData, poFeature->getSize());
     649        3127 :         poFeature->write(&pabyData);
     650             :     }
     651             : 
     652       10837 :     for (const auto &osKey : m_aosKeys)
     653             :     {
     654        7871 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_KEYS, WT_DATA));
     655        7874 :         WriteText(&pabyData, osKey);
     656             :     }
     657             : 
     658       10917 :     for (const auto &oValue : m_aoValues)
     659             :     {
     660        8000 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_VALUES, WT_DATA));
     661        7991 :         WriteVarUInt(&pabyData, oValue.getSize());
     662        7987 :         oValue.write(&pabyData);
     663             :     }
     664             : 
     665        2913 :     if (m_bHasExtent)
     666             :     {
     667        1401 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_EXTENT, WT_VARINT));
     668        1401 :         WriteVarUInt(&pabyData, m_nExtent);
     669             :     }
     670             : 
     671        2913 :     WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_VERSION, WT_VARINT));
     672        2901 :     WriteVarUInt(&pabyData, m_nVersion);
     673             : 
     674        2889 :     CPLAssert(pabyData == *ppabyData + getSize());
     675        2888 :     *ppabyData = pabyData;
     676        2888 : }
     677             : 
     678             : /************************************************************************/
     679             : /*                             write()                                  */
     680             : /************************************************************************/
     681             : 
     682        1468 : void MVTTileLayer::write(GByte *pabyData) const
     683             : {
     684        1468 :     write(&pabyData);
     685        1473 : }
     686             : 
     687             : /************************************************************************/
     688             : /*                             write()                                  */
     689             : /************************************************************************/
     690             : 
     691        1489 : std::string MVTTileLayer::write() const
     692             : {
     693        1489 :     std::string buffer;
     694        1501 :     size_t nSize = getSize();
     695        1504 :     buffer.resize(nSize);
     696        1463 :     write(reinterpret_cast<GByte *>(&buffer[0]));
     697        1451 :     return buffer;
     698             : }
     699             : 
     700             : /************************************************************************/
     701             : /*                             read()                                   */
     702             : /************************************************************************/
     703             : 
     704        1688 : bool MVTTileLayer::read(const GByte **ppabyData, const GByte *pabyDataLimit)
     705             : {
     706        1688 :     const GByte *pabyData = *ppabyData;
     707             : 
     708             :     try
     709             :     {
     710        1688 :         unsigned int nKey = 0;
     711       15648 :         while (pabyData < pabyDataLimit)
     712             :         {
     713       13960 :             READ_FIELD_KEY(nKey);
     714       13960 :             if (nKey == MAKE_KEY(knLAYER_NAME, WT_DATA))
     715             :             {
     716        1688 :                 char *pszLayerName = nullptr;
     717        1688 :                 READ_TEXT(pabyData, pabyDataLimit, pszLayerName);
     718             :                 // cppcheck-suppress nullPointer
     719        1688 :                 setName(pszLayerName);
     720        1688 :                 CPLFree(pszLayerName);
     721             :             }
     722       12272 :             else if (nKey == MAKE_KEY(knLAYER_FEATURES, WT_DATA))
     723             :             {
     724        1688 :                 unsigned int nFeatureLength = 0;
     725        1688 :                 READ_SIZE(pabyData, pabyDataLimit, nFeatureLength);
     726        1688 :                 const GByte *pabyDataFeatureEnd = pabyData + nFeatureLength;
     727             :                 std::shared_ptr<MVTTileLayerFeature> poFeature(
     728        1688 :                     new MVTTileLayerFeature());
     729        1688 :                 addFeature(poFeature);
     730        1688 :                 if (!poFeature->read(&pabyData, pabyDataFeatureEnd))
     731           0 :                     return false;
     732        1688 :                 pabyData = pabyDataFeatureEnd;
     733             :             }
     734       10584 :             else if (nKey == MAKE_KEY(knLAYER_KEYS, WT_DATA))
     735             :             {
     736        4448 :                 char *pszKey = nullptr;
     737        4448 :                 READ_TEXT(pabyData, pabyDataLimit, pszKey);
     738             :                 // cppcheck-suppress nullPointer
     739        4448 :                 addKey(pszKey);
     740        4448 :                 CPLFree(pszKey);
     741             :             }
     742        6136 :             else if (nKey == MAKE_KEY(knLAYER_VALUES, WT_DATA))
     743             :             {
     744        4448 :                 unsigned int nValueLength = 0;
     745        4448 :                 READ_SIZE(pabyData, pabyDataLimit, nValueLength);
     746        4448 :                 const GByte *pabyDataValueEnd = pabyData + nValueLength;
     747        4448 :                 MVTTileLayerValue oValue;
     748        4448 :                 if (!oValue.read(&pabyData, pabyDataValueEnd))
     749           0 :                     return false;
     750        4448 :                 addValue(oValue);
     751        4448 :                 pabyData = pabyDataValueEnd;
     752             :             }
     753        1688 :             else if (nKey == MAKE_KEY(knLAYER_EXTENT, WT_VARINT))
     754             :             {
     755           0 :                 unsigned int nExtent = 0;
     756           0 :                 READ_VARUINT32(pabyData, pabyDataLimit, nExtent);
     757           0 :                 setExtent(nExtent);
     758             :             }
     759        1688 :             else if (nKey == MAKE_KEY(knLAYER_VERSION, WT_VARINT))
     760             :             {
     761        1688 :                 unsigned int nVersion = 0;
     762        1688 :                 READ_VARUINT32(pabyData, pabyDataLimit, nVersion);
     763        1688 :                 setVersion(nVersion);
     764             :             }
     765             :             else
     766             :             {
     767           0 :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     768             :             }
     769             :         }
     770        1688 :         *ppabyData = pabyData;
     771        1688 :         return true;
     772             :     }
     773           0 :     catch (const GPBException &)
     774             :     {
     775           0 :         return false;
     776             :     }
     777             : }
     778             : 
     779             : /************************************************************************/
     780             : /*                             read()                                   */
     781             : /************************************************************************/
     782             : 
     783        1688 : bool MVTTileLayer::read(const GByte *pabyData, const GByte *pabyEnd)
     784             : {
     785        1688 :     return read(&pabyData, pabyEnd);
     786             : }
     787             : 
     788             : /************************************************************************/
     789             : /*                             MVTTile()                                */
     790             : /************************************************************************/
     791             : 
     792         935 : MVTTile::MVTTile()
     793             : {
     794         935 : }
     795             : 
     796             : /************************************************************************/
     797             : /*                            addLayer()                                */
     798             : /************************************************************************/
     799             : 
     800        1401 : void MVTTile::addLayer(std::shared_ptr<MVTTileLayer> poLayer)
     801             : {
     802        1401 :     poLayer->setOwner(this);
     803        1401 :     invalidateCachedSize();
     804        1401 :     m_apoLayers.push_back(poLayer);
     805        1401 : }
     806             : 
     807             : /************************************************************************/
     808             : /*                            getSize()                                 */
     809             : /************************************************************************/
     810             : 
     811        1957 : size_t MVTTile::getSize() const
     812             : {
     813        1957 :     if (m_bCachedSize)
     814         985 :         return m_nCachedSize;
     815         972 :     m_nCachedSize = 0;
     816        2385 :     for (const auto &poLayer : m_apoLayers)
     817             :     {
     818        1413 :         const size_t nLayerSize = poLayer->getSize();
     819        1413 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(nLayerSize) + nLayerSize;
     820             :     }
     821         972 :     m_bCachedSize = true;
     822         972 :     return m_nCachedSize;
     823             : }
     824             : 
     825             : /************************************************************************/
     826             : /*                             write()                                  */
     827             : /************************************************************************/
     828             : 
     829         960 : void MVTTile::write(GByte **ppabyData) const
     830             : {
     831         960 :     GByte *pabyData = *ppabyData;
     832             : 
     833        2361 :     for (const auto &poLayer : m_apoLayers)
     834             :     {
     835        1401 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER, WT_DATA));
     836        1401 :         WriteVarUInt(&pabyData, poLayer->getSize());
     837        1401 :         poLayer->write(&pabyData);
     838             :     }
     839             : 
     840         960 :     CPLAssert(pabyData == *ppabyData + getSize());
     841         960 :     *ppabyData = pabyData;
     842         960 : }
     843             : 
     844             : /************************************************************************/
     845             : /*                             write()                                  */
     846             : /************************************************************************/
     847             : 
     848         960 : void MVTTile::write(GByte *pabyData) const
     849             : {
     850         960 :     write(&pabyData);
     851         960 : }
     852             : 
     853             : /************************************************************************/
     854             : /*                             write()                                  */
     855             : /************************************************************************/
     856             : 
     857         960 : std::string MVTTile::write() const
     858             : {
     859         960 :     std::string buffer;
     860         960 :     size_t nSize = getSize();
     861         960 :     if (nSize)
     862             :     {
     863         960 :         buffer.resize(nSize);
     864         960 :         write(reinterpret_cast<GByte *>(&buffer[0]));
     865             :     }
     866         960 :     return buffer;
     867             : }
     868             : 
     869             : #ifdef ADD_MVT_TILE_READ
     870             : 
     871             : /************************************************************************/
     872             : /*                             read()                                   */
     873             : /************************************************************************/
     874             : 
     875             : bool MVTTile::read(const GByte **ppabyData, const GByte *pabyDataLimit)
     876             : {
     877             :     const GByte *pabyData = *ppabyData;
     878             : 
     879             :     try
     880             :     {
     881             :         unsigned int nKey = 0;
     882             :         while (pabyData < pabyDataLimit)
     883             :         {
     884             :             READ_FIELD_KEY(nKey);
     885             :             if (nKey == MAKE_KEY(knLAYER, WT_DATA))
     886             :             {
     887             :                 unsigned int nLayerSize = 0;
     888             :                 READ_SIZE(pabyData, pabyDataLimit, nLayerSize);
     889             :                 const GByte *pabyDataLimitLayer = pabyData + nLayerSize;
     890             :                 std::shared_ptr<MVTTileLayer> poLayer(new MVTTileLayer());
     891             :                 addLayer(poLayer);
     892             :                 if (!poLayer->read(&pabyData, pabyDataLimitLayer))
     893             :                     return false;
     894             :                 pabyData = pabyDataLimitLayer;
     895             :             }
     896             :             else
     897             :             {
     898             :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     899             :             }
     900             :         }
     901             :         *ppabyData = pabyData;
     902             :         return true;
     903             :     }
     904             :     catch (const GPBException &)
     905             :     {
     906             :         return false;
     907             :     }
     908             : }
     909             : 
     910             : /************************************************************************/
     911             : /*                             read()                                   */
     912             : /************************************************************************/
     913             : 
     914             : bool MVTTile::read(const GByte *pabyData, const GByte *pabyEnd)
     915             : {
     916             :     return read(&pabyData, pabyEnd);
     917             : }
     918             : 
     919             : #endif

Generated by: LCOV version 1.14