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-02-20 10:14:44 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       36036 : MVTTileLayerValue::MVTTileLayerValue(const MVTTileLayerValue &oOther)
      33             : {
      34       36036 :     operator=(oOther);
      35       36039 : }
      36             : 
      37             : /************************************************************************/
      38             : /*                       ~MVTTileLayerValue()                           */
      39             : /************************************************************************/
      40             : 
      41       91013 : MVTTileLayerValue::~MVTTileLayerValue()
      42             : {
      43       45507 :     unset();
      44       45506 : }
      45             : 
      46             : /************************************************************************/
      47             : /*                            operator=                                 */
      48             : /************************************************************************/
      49             : 
      50       36030 : MVTTileLayerValue &MVTTileLayerValue::operator=(const MVTTileLayerValue &oOther)
      51             : 
      52             : {
      53       36030 :     if (this != &oOther)
      54             :     {
      55       36027 :         unset();
      56       36033 :         m_eType = oOther.m_eType;
      57       36033 :         if (m_eType == ValueType::STRING)
      58             :         {
      59        9599 :             const size_t nSize = strlen(oOther.m_pszValue);
      60        9599 :             m_pszValue = static_cast<char *>(CPLMalloc(1 + nSize));
      61        9602 :             memcpy(m_pszValue, oOther.m_pszValue, nSize);
      62        9602 :             m_pszValue[nSize] = 0;
      63             :         }
      64             :         else
      65             :         {
      66       26434 :             m_nUIntValue = oOther.m_nUIntValue;
      67             :         }
      68             :     }
      69       36039 :     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       90992 : void MVTTileLayerValue::unset()
     109             : {
     110       90992 :     if (m_eType == ValueType::STRING)
     111       13320 :         CPLFree(m_pszValue);
     112       90990 :     m_eType = ValueType::NONE;
     113       90990 :     m_nUIntValue = 0;
     114       90990 : }
     115             : 
     116             : /************************************************************************/
     117             : /*                            GetSizeMax8()                             */
     118             : /************************************************************************/
     119             : 
     120        6459 : static size_t GetSizeMax8(const char achValue[8])
     121             : {
     122        6459 :     size_t nSize = 0;
     123       27569 :     while (nSize < 8 && achValue[nSize] != 0)
     124       21110 :         nSize++;
     125        6459 :     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       24315 : size_t MVTTileLayerValue::getSize() const
     189             : {
     190       24315 :     switch (m_eType)
     191             :     {
     192           0 :         case ValueType::NONE:
     193           0 :             return 0;
     194        9575 :         case ValueType::STRING:
     195             :         {
     196        9575 :             const size_t nSize = strlen(m_pszValue);
     197        9575 :             return knSIZE_KEY + GetVarUIntSize(nSize) + nSize;
     198             :         }
     199        4844 :         case ValueType::STRING_MAX_8:
     200             :         {
     201        4844 :             const size_t nSize = GetSizeMax8(m_achValue);
     202        4847 :             return knSIZE_KEY + GetVarUIntSize(nSize) + nSize;
     203             :         }
     204         147 :         case ValueType::FLOAT:
     205         147 :             return knSIZE_KEY + sizeof(float);
     206        4732 :         case ValueType::DOUBLE:
     207        4732 :             return knSIZE_KEY + sizeof(double);
     208           0 :         case ValueType::INT:
     209           0 :             return knSIZE_KEY + GetVarIntSize(m_nIntValue);
     210        4876 :         case ValueType::UINT:
     211        4876 :             return knSIZE_KEY + GetVarUIntSize(m_nUIntValue);
     212          86 :         case ValueType::SINT:
     213          86 :             return knSIZE_KEY + GetVarSIntSize(m_nIntValue);
     214          54 :         case ValueType::BOOL:
     215          54 :             return knSIZE_KEY + 1;
     216           1 :         default:
     217           1 :             return 0;
     218             :     }
     219             : }
     220             : 
     221             : /************************************************************************/
     222             : /*                             write()                                  */
     223             : /************************************************************************/
     224             : 
     225        8106 : void MVTTileLayerValue::write(GByte **ppabyData) const
     226             : {
     227        8106 :     GByte *pabyData = *ppabyData;
     228             : 
     229        8106 :     switch (m_eType)
     230             :     {
     231        3193 :         case ValueType::STRING:
     232             :         {
     233        3193 :             const size_t nSize = strlen(m_pszValue);
     234        3193 :             WriteVarUIntSingleByte(&pabyData,
     235             :                                    MAKE_KEY(knVALUE_STRING, WT_DATA));
     236        3196 :             WriteVarUInt(&pabyData, nSize);
     237        3194 :             memcpy(pabyData, m_pszValue, nSize);
     238        3194 :             pabyData += nSize;
     239        3194 :             break;
     240             :         }
     241             : 
     242        1616 :         case ValueType::STRING_MAX_8:
     243             :         {
     244        1616 :             const size_t nSize = GetSizeMax8(m_achValue);
     245        1615 :             WriteVarUIntSingleByte(&pabyData,
     246             :                                    MAKE_KEY(knVALUE_STRING, WT_DATA));
     247        1614 :             WriteVarUInt(&pabyData, nSize);
     248        1615 :             if (nSize)
     249        1613 :                 memcpy(pabyData, m_achValue, nSize);
     250        1615 :             pabyData += nSize;
     251        1615 :             break;
     252             :         }
     253             : 
     254          49 :         case ValueType::FLOAT:
     255          49 :             WriteVarUIntSingleByte(&pabyData,
     256             :                                    MAKE_KEY(knVALUE_FLOAT, WT_32BIT));
     257          49 :             WriteFloat32(&pabyData, m_fValue);
     258          50 :             break;
     259             : 
     260        1578 :         case ValueType::DOUBLE:
     261        1578 :             WriteVarUIntSingleByte(&pabyData,
     262             :                                    MAKE_KEY(knVALUE_DOUBLE, WT_64BIT));
     263        1578 :             WriteFloat64(&pabyData, m_dfValue);
     264        1574 :             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        1623 :         case ValueType::UINT:
     272        1623 :             WriteVarUIntSingleByte(&pabyData,
     273             :                                    MAKE_KEY(knVALUE_UINT, WT_VARINT));
     274        1626 :             WriteVarUInt(&pabyData, m_nUIntValue);
     275        1628 :             break;
     276             : 
     277          30 :         case ValueType::SINT:
     278          30 :             WriteVarUIntSingleByte(&pabyData,
     279             :                                    MAKE_KEY(knVALUE_SINT, WT_VARINT));
     280          29 :             WriteVarSInt(&pabyData, m_nIntValue);
     281          29 :             break;
     282             : 
     283          18 :         case ValueType::BOOL:
     284          18 :             WriteVarUIntSingleByte(&pabyData,
     285             :                                    MAKE_KEY(knVALUE_BOOL, WT_VARINT));
     286          18 :             WriteVarUIntSingleByte(&pabyData, m_bBoolValue ? 1 : 0);
     287          17 :             break;
     288             : 
     289           0 :         default:
     290           0 :             break;
     291             :     }
     292             : 
     293        8106 :     CPLAssert(pabyData == *ppabyData + getSize());
     294        8107 :     *ppabyData = pabyData;
     295        8107 : }
     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        7427 : MVTTileLayerFeature::MVTTileLayerFeature()
     368             : {
     369        7421 : }
     370             : 
     371             : /************************************************************************/
     372             : /*                             setOwner()                               */
     373             : /************************************************************************/
     374             : 
     375        7400 : void MVTTileLayerFeature::setOwner(MVTTileLayer *poOwner)
     376             : {
     377        7400 :     CPLAssert(!m_poOwner);
     378        7400 :     m_poOwner = poOwner;
     379        7400 :     m_poOwner->invalidateCachedSize();
     380        7397 : }
     381             : 
     382             : /************************************************************************/
     383             : /*                       invalidateCachedSize()                         */
     384             : /************************************************************************/
     385             : 
     386       54004 : void MVTTileLayerFeature::invalidateCachedSize()
     387             : {
     388       54004 :     m_bCachedSize = false;
     389       54004 :     m_nCachedSize = 0;
     390       54004 :     if (m_poOwner)
     391       41667 :         m_poOwner->invalidateCachedSize();
     392       53967 : }
     393             : 
     394             : /************************************************************************/
     395             : /*                        GetPackedArraySize()                          */
     396             : /************************************************************************/
     397             : 
     398       10183 : static size_t GetPackedArraySize(const std::vector<GUInt32> &anVals)
     399             : {
     400       10183 :     size_t nPackedSize = 0;
     401       71537 :     for (const auto &nVal : anVals)
     402             :     {
     403       61361 :         nPackedSize += GetVarUIntSize(nVal);
     404             :     }
     405       10194 :     return nPackedSize;
     406             : }
     407             : 
     408             : /************************************************************************/
     409             : /*                            getSize()                                 */
     410             : /************************************************************************/
     411             : 
     412        9625 : size_t MVTTileLayerFeature::getSize() const
     413             : {
     414        9625 :     if (m_bCachedSize)
     415        6418 :         return m_nCachedSize;
     416        3207 :     m_bCachedSize = true;
     417        3207 :     m_nCachedSize = 0;
     418        3207 :     if (m_bHasId)
     419         106 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nId);
     420        3206 :     if (!m_anTags.empty())
     421             :     {
     422        1881 :         size_t nPackedSize = GetPackedArraySize(m_anTags);
     423        1887 :         m_nCachedSize += knSIZE_KEY;
     424        1887 :         m_nCachedSize += GetVarUIntSize(nPackedSize);
     425        1885 :         m_nCachedSize += nPackedSize;
     426             :     }
     427        3207 :     if (m_bHasType)
     428        3205 :         m_nCachedSize += knSIZE_KEY + 1;  // fixed size for m_eType
     429        3207 :     if (!m_anGeometry.empty())
     430             :     {
     431        3209 :         size_t nPackedSize = GetPackedArraySize(m_anGeometry);
     432        3210 :         m_nCachedSize += knSIZE_KEY;
     433        3210 :         m_nCachedSize += GetVarUIntSize(nPackedSize);
     434        3208 :         m_nCachedSize += nPackedSize;
     435             :     }
     436        3209 :     return m_nCachedSize;
     437             : }
     438             : 
     439             : /************************************************************************/
     440             : /*                        WriteUIntPackedArray()                        */
     441             : /************************************************************************/
     442             : 
     443        5089 : static void WriteUIntPackedArray(GByte **ppabyData, int nKey,
     444             :                                  const std::vector<GUInt32> &anVals)
     445             : {
     446        5089 :     GByte *pabyData = *ppabyData;
     447        5089 :     const size_t nPackedSize = GetPackedArraySize(anVals);
     448        5100 :     WriteVarUIntSingleByte(&pabyData, nKey);
     449        5099 :     WriteVarUInt(&pabyData, nPackedSize);
     450       35794 :     for (const auto &nVal : anVals)
     451             :     {
     452       30691 :         WriteVarUInt(&pabyData, nVal);
     453             :     }
     454        5097 :     *ppabyData = pabyData;
     455        5097 : }
     456             : 
     457             : /************************************************************************/
     458             : /*                             write()                                  */
     459             : /************************************************************************/
     460             : 
     461        3210 : void MVTTileLayerFeature::write(GByte **ppabyData) const
     462             : {
     463        3210 :     GByte *pabyData = *ppabyData;
     464             : 
     465        3210 :     if (m_bHasId)
     466             :     {
     467         106 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knFEATURE_ID, WT_VARINT));
     468         105 :         WriteVarUInt(&pabyData, m_nId);
     469             :     }
     470        3210 :     if (!m_anTags.empty())
     471             :     {
     472        1884 :         WriteUIntPackedArray(&pabyData, MAKE_KEY(knFEATURE_TAGS, WT_DATA),
     473        1884 :                              m_anTags);
     474             :     }
     475        3211 :     if (m_bHasType)
     476             :     {
     477        3210 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knFEATURE_TYPE, WT_VARINT));
     478        3206 :         WriteVarUIntSingleByte(&pabyData, static_cast<GUIntBig>(m_eType));
     479             :     }
     480        3208 :     if (!m_anGeometry.empty())
     481             :     {
     482        3205 :         WriteUIntPackedArray(&pabyData, MAKE_KEY(knFEATURE_GEOMETRY, WT_DATA),
     483        3205 :                              m_anGeometry);
     484             :     }
     485             : 
     486        3216 :     CPLAssert(pabyData == *ppabyData + getSize());
     487        3210 :     *ppabyData = pabyData;
     488        3210 : }
     489             : 
     490             : /************************************************************************/
     491             : /*                             read()                                   */
     492             : /************************************************************************/
     493             : 
     494        1700 : bool MVTTileLayerFeature::read(const GByte **ppabyData,
     495             :                                const GByte *pabyDataLimit)
     496             : {
     497        1700 :     const GByte *pabyData = *ppabyData;
     498             : 
     499             :     try
     500             :     {
     501        1700 :         unsigned int nKey = 0;
     502        6147 :         while (pabyData < pabyDataLimit)
     503             :         {
     504        4447 :             READ_FIELD_KEY(nKey);
     505        4447 :             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        4394 :             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        3400 :             else if (nKey == MAKE_KEY(knFEATURE_TYPE, WT_VARINT))
     525             :             {
     526        1700 :                 unsigned int nType = 0;
     527        1700 :                 READ_VARUINT32(pabyData, pabyDataLimit, nType);
     528        1700 :                 if (nType <= knGEOM_TYPE_POLYGON)
     529        1700 :                     setType(static_cast<GeomType>(nType));
     530             :             }
     531        1700 :             else if (nKey == MAKE_KEY(knFEATURE_GEOMETRY, WT_DATA))
     532             :             {
     533        1700 :                 unsigned int nGeometrySize = 0;
     534        1700 :                 READ_SIZE(pabyData, pabyDataLimit, nGeometrySize);
     535        1700 :                 const GByte *pabyDataGeometryEnd = pabyData + nGeometrySize;
     536        8988 :                 while (pabyData < pabyDataGeometryEnd)
     537             :                 {
     538        7288 :                     unsigned int nGeometry = 0;
     539        7288 :                     READ_VARUINT32(pabyData, pabyDataGeometryEnd, nGeometry);
     540        7288 :                     addGeometry(nGeometry);
     541             :                 }
     542        1700 :                 pabyData = pabyDataGeometryEnd;
     543             :             }
     544             :             else
     545             :             {
     546           0 :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     547             :             }
     548             :         }
     549        1700 :         *ppabyData = pabyData;
     550        1700 :         return true;
     551             :     }
     552           0 :     catch (const GPBException &)
     553             :     {
     554           0 :         return false;
     555             :     }
     556             : }
     557             : 
     558             : /************************************************************************/
     559             : /*                           MVTTileLayer()                             */
     560             : /************************************************************************/
     561             : 
     562        7140 : MVTTileLayer::MVTTileLayer()
     563             : {
     564        7132 : }
     565             : 
     566             : /************************************************************************/
     567             : /*                             setOwner()                               */
     568             : /************************************************************************/
     569             : 
     570        1413 : void MVTTileLayer::setOwner(MVTTile *poOwner)
     571             : {
     572        1413 :     CPLAssert(!m_poOwner);
     573        1413 :     m_poOwner = poOwner;
     574        1413 :     m_poOwner->invalidateCachedSize();
     575        1413 : }
     576             : 
     577             : /************************************************************************/
     578             : /*                       invalidateCachedSize()                         */
     579             : /************************************************************************/
     580             : 
     581       89068 : void MVTTileLayer::invalidateCachedSize()
     582             : {
     583       89068 :     m_bCachedSize = false;
     584       89068 :     m_nCachedSize = 0;
     585       89068 :     if (m_poOwner)
     586       15009 :         m_poOwner->invalidateCachedSize();
     587       89068 : }
     588             : 
     589             : /************************************************************************/
     590             : /*                          addFeature()                                */
     591             : /************************************************************************/
     592             : 
     593        7398 : size_t MVTTileLayer::addFeature(std::shared_ptr<MVTTileLayerFeature> poFeature)
     594             : {
     595        7398 :     poFeature->setOwner(this);
     596        7395 :     m_apoFeatures.push_back(poFeature);
     597        7398 :     invalidateCachedSize();
     598        7393 :     return m_apoFeatures.size() - 1;
     599             : }
     600             : 
     601             : /************************************************************************/
     602             : /*                            getSize()                                 */
     603             : /************************************************************************/
     604             : 
     605        7311 : size_t MVTTileLayer::getSize() const
     606             : {
     607        7311 :     if (m_bCachedSize)
     608        4353 :         return m_nCachedSize;
     609        2958 :     m_nCachedSize = knSIZE_KEY + GetTextSize(m_osName);
     610        6166 :     for (const auto &poFeature : m_apoFeatures)
     611             :     {
     612        3212 :         const size_t nFeatureSize = poFeature->getSize();
     613        3211 :         m_nCachedSize +=
     614        3216 :             knSIZE_KEY + GetVarUIntSize(nFeatureSize) + nFeatureSize;
     615             :     }
     616       10932 :     for (const auto &osKey : m_aosKeys)
     617             :     {
     618        7980 :         m_nCachedSize += knSIZE_KEY + GetTextSize(osKey);
     619             :     }
     620       11058 :     for (const auto &oValue : m_aoValues)
     621             :     {
     622        8103 :         const size_t nValueSize = oValue.getSize();
     623        8105 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(nValueSize) + nValueSize;
     624             :     }
     625        2951 :     if (m_bHasExtent)
     626             :     {
     627        1425 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nExtent);
     628             :     }
     629        2951 :     m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nVersion);
     630        2953 :     m_bCachedSize = true;
     631        2953 :     return m_nCachedSize;
     632             : }
     633             : 
     634             : /************************************************************************/
     635             : /*                             write()                                  */
     636             : /************************************************************************/
     637             : 
     638        2943 : void MVTTileLayer::write(GByte **ppabyData) const
     639             : {
     640        2943 :     GByte *pabyData = *ppabyData;
     641             : 
     642        2943 :     WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_NAME, WT_DATA));
     643        2944 :     WriteText(&pabyData, m_osName);
     644             : 
     645        6145 :     for (const auto &poFeature : m_apoFeatures)
     646             :     {
     647        3206 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_FEATURES, WT_DATA));
     648        3204 :         WriteVarUInt(&pabyData, poFeature->getSize());
     649        3199 :         poFeature->write(&pabyData);
     650             :     }
     651             : 
     652       10925 :     for (const auto &osKey : m_aosKeys)
     653             :     {
     654        7984 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_KEYS, WT_DATA));
     655        7981 :         WriteText(&pabyData, osKey);
     656             :     }
     657             : 
     658       11052 :     for (const auto &oValue : m_aoValues)
     659             :     {
     660        8102 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_VALUES, WT_DATA));
     661        8103 :         WriteVarUInt(&pabyData, oValue.getSize());
     662        8101 :         oValue.write(&pabyData);
     663             :     }
     664             : 
     665        2941 :     if (m_bHasExtent)
     666             :     {
     667        1413 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_EXTENT, WT_VARINT));
     668        1413 :         WriteVarUInt(&pabyData, m_nExtent);
     669             :     }
     670             : 
     671        2941 :     WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_VERSION, WT_VARINT));
     672        2943 :     WriteVarUInt(&pabyData, m_nVersion);
     673             : 
     674        2940 :     CPLAssert(pabyData == *ppabyData + getSize());
     675        2940 :     *ppabyData = pabyData;
     676        2940 : }
     677             : 
     678             : /************************************************************************/
     679             : /*                             write()                                  */
     680             : /************************************************************************/
     681             : 
     682        1527 : void MVTTileLayer::write(GByte *pabyData) const
     683             : {
     684        1527 :     write(&pabyData);
     685        1525 : }
     686             : 
     687             : /************************************************************************/
     688             : /*                             write()                                  */
     689             : /************************************************************************/
     690             : 
     691        1530 : std::string MVTTileLayer::write() const
     692             : {
     693        1530 :     std::string buffer;
     694        1529 :     size_t nSize = getSize();
     695        1523 :     buffer.resize(nSize);
     696        1528 :     write(reinterpret_cast<GByte *>(&buffer[0]));
     697        1519 :     return buffer;
     698             : }
     699             : 
     700             : /************************************************************************/
     701             : /*                             read()                                   */
     702             : /************************************************************************/
     703             : 
     704        1700 : bool MVTTileLayer::read(const GByte **ppabyData, const GByte *pabyDataLimit)
     705             : {
     706        1700 :     const GByte *pabyData = *ppabyData;
     707             : 
     708             :     try
     709             :     {
     710        1700 :         unsigned int nKey = 0;
     711       15696 :         while (pabyData < pabyDataLimit)
     712             :         {
     713       13996 :             READ_FIELD_KEY(nKey);
     714       13996 :             if (nKey == MAKE_KEY(knLAYER_NAME, WT_DATA))
     715             :             {
     716        1700 :                 char *pszLayerName = nullptr;
     717        1700 :                 READ_TEXT(pabyData, pabyDataLimit, pszLayerName);
     718             :                 // cppcheck-suppress nullPointer
     719        1700 :                 setName(pszLayerName);
     720        1700 :                 CPLFree(pszLayerName);
     721             :             }
     722       12296 :             else if (nKey == MAKE_KEY(knLAYER_FEATURES, WT_DATA))
     723             :             {
     724        1700 :                 unsigned int nFeatureLength = 0;
     725        1700 :                 READ_SIZE(pabyData, pabyDataLimit, nFeatureLength);
     726        1700 :                 const GByte *pabyDataFeatureEnd = pabyData + nFeatureLength;
     727             :                 std::shared_ptr<MVTTileLayerFeature> poFeature(
     728        1700 :                     new MVTTileLayerFeature());
     729        1700 :                 addFeature(poFeature);
     730        1700 :                 if (!poFeature->read(&pabyData, pabyDataFeatureEnd))
     731           0 :                     return false;
     732        1700 :                 pabyData = pabyDataFeatureEnd;
     733             :             }
     734       10596 :             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        6148 :             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        1700 :             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        1700 :             else if (nKey == MAKE_KEY(knLAYER_VERSION, WT_VARINT))
     760             :             {
     761        1700 :                 unsigned int nVersion = 0;
     762        1700 :                 READ_VARUINT32(pabyData, pabyDataLimit, nVersion);
     763        1700 :                 setVersion(nVersion);
     764             :             }
     765             :             else
     766             :             {
     767           0 :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     768             :             }
     769             :         }
     770        1700 :         *ppabyData = pabyData;
     771        1700 :         return true;
     772             :     }
     773           0 :     catch (const GPBException &)
     774             :     {
     775           0 :         return false;
     776             :     }
     777             : }
     778             : 
     779             : /************************************************************************/
     780             : /*                             read()                                   */
     781             : /************************************************************************/
     782             : 
     783        1700 : bool MVTTileLayer::read(const GByte *pabyData, const GByte *pabyEnd)
     784             : {
     785        1700 :     return read(&pabyData, pabyEnd);
     786             : }
     787             : 
     788             : /************************************************************************/
     789             : /*                             MVTTile()                                */
     790             : /************************************************************************/
     791             : 
     792         947 : MVTTile::MVTTile()
     793             : {
     794         947 : }
     795             : 
     796             : /************************************************************************/
     797             : /*                            addLayer()                                */
     798             : /************************************************************************/
     799             : 
     800        1413 : void MVTTile::addLayer(std::shared_ptr<MVTTileLayer> poLayer)
     801             : {
     802        1413 :     poLayer->setOwner(this);
     803        1413 :     invalidateCachedSize();
     804        1413 :     m_apoLayers.push_back(poLayer);
     805        1413 : }
     806             : 
     807             : /************************************************************************/
     808             : /*                            getSize()                                 */
     809             : /************************************************************************/
     810             : 
     811        1981 : size_t MVTTile::getSize() const
     812             : {
     813        1981 :     if (m_bCachedSize)
     814         997 :         return m_nCachedSize;
     815         984 :     m_nCachedSize = 0;
     816        2409 :     for (const auto &poLayer : m_apoLayers)
     817             :     {
     818        1425 :         const size_t nLayerSize = poLayer->getSize();
     819        1425 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(nLayerSize) + nLayerSize;
     820             :     }
     821         984 :     m_bCachedSize = true;
     822         984 :     return m_nCachedSize;
     823             : }
     824             : 
     825             : /************************************************************************/
     826             : /*                             write()                                  */
     827             : /************************************************************************/
     828             : 
     829         972 : void MVTTile::write(GByte **ppabyData) const
     830             : {
     831         972 :     GByte *pabyData = *ppabyData;
     832             : 
     833        2385 :     for (const auto &poLayer : m_apoLayers)
     834             :     {
     835        1413 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER, WT_DATA));
     836        1413 :         WriteVarUInt(&pabyData, poLayer->getSize());
     837        1413 :         poLayer->write(&pabyData);
     838             :     }
     839             : 
     840         972 :     CPLAssert(pabyData == *ppabyData + getSize());
     841         972 :     *ppabyData = pabyData;
     842         972 : }
     843             : 
     844             : /************************************************************************/
     845             : /*                             write()                                  */
     846             : /************************************************************************/
     847             : 
     848         972 : void MVTTile::write(GByte *pabyData) const
     849             : {
     850         972 :     write(&pabyData);
     851         972 : }
     852             : 
     853             : /************************************************************************/
     854             : /*                             write()                                  */
     855             : /************************************************************************/
     856             : 
     857         972 : std::string MVTTile::write() const
     858             : {
     859         972 :     std::string buffer;
     860         972 :     size_t nSize = getSize();
     861         972 :     if (nSize)
     862             :     {
     863         972 :         buffer.resize(nSize);
     864         972 :         write(reinterpret_cast<GByte *>(&buffer[0]));
     865             :     }
     866         972 :     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