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: 408 441 92.5 %
Date: 2024-11-21 22:18:42 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        9418 : MVTTileLayerValue::MVTTileLayerValue() : m_nUIntValue(0)
      29             : {
      30        9418 : }
      31             : 
      32       35921 : MVTTileLayerValue::MVTTileLayerValue(const MVTTileLayerValue &oOther)
      33             : {
      34       35921 :     operator=(oOther);
      35       35916 : }
      36             : 
      37             : /************************************************************************/
      38             : /*                       ~MVTTileLayerValue()                           */
      39             : /************************************************************************/
      40             : 
      41       90684 : MVTTileLayerValue::~MVTTileLayerValue()
      42             : {
      43       45341 :     unset();
      44       45343 : }
      45             : 
      46             : /************************************************************************/
      47             : /*                            operator=                                 */
      48             : /************************************************************************/
      49             : 
      50       35917 : MVTTileLayerValue &MVTTileLayerValue::operator=(const MVTTileLayerValue &oOther)
      51             : 
      52             : {
      53       35917 :     if (this != &oOther)
      54             :     {
      55       35916 :         unset();
      56       35919 :         m_eType = oOther.m_eType;
      57       35919 :         if (m_eType == ValueType::STRING)
      58             :         {
      59        9473 :             const size_t nSize = strlen(oOther.m_pszValue);
      60        9473 :             m_pszValue = static_cast<char *>(CPLMalloc(1 + nSize));
      61        9473 :             memcpy(m_pszValue, oOther.m_pszValue, nSize);
      62        9473 :             m_pszValue[nSize] = 0;
      63             :         }
      64             :         else
      65             :         {
      66       26446 :             m_nUIntValue = oOther.m_nUIntValue;
      67             :         }
      68             :     }
      69       35920 :     return *this;
      70             : }
      71             : 
      72             : /************************************************************************/
      73             : /*                            operator<                                 */
      74             : /************************************************************************/
      75             : 
      76       53972 : bool MVTTileLayerValue::operator<(const MVTTileLayerValue &rhs) const
      77             : {
      78       53972 :     if (m_eType < rhs.m_eType)
      79        4345 :         return false;
      80       49627 :     if (m_eType > rhs.m_eType)
      81       17484 :         return true;
      82       32143 :     if (m_eType == ValueType::NONE)
      83           0 :         return false;
      84       32143 :     if (m_eType == ValueType::STRING)
      85       14233 :         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       90671 : void MVTTileLayerValue::unset()
     109             : {
     110       90671 :     if (m_eType == ValueType::STRING)
     111       13134 :         CPLFree(m_pszValue);
     112       90672 :     m_eType = ValueType::NONE;
     113       90672 :     m_nUIntValue = 0;
     114       90672 : }
     115             : 
     116             : /************************************************************************/
     117             : /*                            GetSizeMax8()                             */
     118             : /************************************************************************/
     119             : 
     120        6469 : static size_t GetSizeMax8(const char achValue[8])
     121             : {
     122        6469 :     size_t nSize = 0;
     123       27632 :     while (nSize < 8 && achValue[nSize] != 0)
     124       21163 :         nSize++;
     125        6469 :     return nSize;
     126             : }
     127             : 
     128             : /************************************************************************/
     129             : /*                        setStringValue()                              */
     130             : /************************************************************************/
     131             : 
     132        5549 : void MVTTileLayerValue::setStringValue(const std::string &osValue)
     133             : {
     134        5549 :     unset();
     135        5549 :     const size_t nSize = osValue.size();
     136        5549 :     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        3660 :         m_eType = ValueType::STRING;
     147        3660 :         m_pszValue = static_cast<char *>(CPLMalloc(1 + nSize));
     148        3660 :         memcpy(m_pszValue, osValue.c_str(), nSize);
     149        3660 :         m_pszValue[nSize] = 0;
     150             :     }
     151        5549 : }
     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       24206 : size_t MVTTileLayerValue::getSize() const
     189             : {
     190       24206 :     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        4851 :         case ValueType::STRING_MAX_8:
     200             :         {
     201        4851 :             const size_t nSize = GetSizeMax8(m_achValue);
     202        4853 :             return knSIZE_KEY + GetVarUIntSize(nSize) + nSize;
     203             :         }
     204         150 :         case ValueType::FLOAT:
     205         150 :             return knSIZE_KEY + sizeof(float);
     206        4736 :         case ValueType::DOUBLE:
     207        4736 :             return knSIZE_KEY + sizeof(double);
     208           0 :         case ValueType::INT:
     209           0 :             return knSIZE_KEY + GetVarIntSize(m_nIntValue);
     210        4886 :         case ValueType::UINT:
     211        4886 :             return knSIZE_KEY + GetVarUIntSize(m_nUIntValue);
     212          90 :         case ValueType::SINT:
     213          90 :             return knSIZE_KEY + GetVarSIntSize(m_nIntValue);
     214          54 :         case ValueType::BOOL:
     215          54 :             return knSIZE_KEY + 1;
     216           0 :         default:
     217           0 :             return 0;
     218             :     }
     219             : }
     220             : 
     221             : /************************************************************************/
     222             : /*                             write()                                  */
     223             : /************************************************************************/
     224             : 
     225        8072 : void MVTTileLayerValue::write(GByte **ppabyData) const
     226             : {
     227        8072 :     GByte *pabyData = *ppabyData;
     228             : 
     229        8072 :     switch (m_eType)
     230             :     {
     231        3150 :         case ValueType::STRING:
     232             :         {
     233        3150 :             const size_t nSize = strlen(m_pszValue);
     234        3150 :             WriteVarUIntSingleByte(&pabyData,
     235             :                                    MAKE_KEY(knVALUE_STRING, WT_DATA));
     236        3147 :             WriteVarUInt(&pabyData, nSize);
     237        3146 :             memcpy(pabyData, m_pszValue, nSize);
     238        3146 :             pabyData += nSize;
     239        3146 :             break;
     240             :         }
     241             : 
     242        1617 :         case ValueType::STRING_MAX_8:
     243             :         {
     244        1617 :             const size_t nSize = GetSizeMax8(m_achValue);
     245        1618 :             WriteVarUIntSingleByte(&pabyData,
     246             :                                    MAKE_KEY(knVALUE_STRING, WT_DATA));
     247        1618 :             WriteVarUInt(&pabyData, nSize);
     248        1618 :             if (nSize)
     249        1617 :                 memcpy(pabyData, m_achValue, nSize);
     250        1618 :             pabyData += nSize;
     251        1618 :             break;
     252             :         }
     253             : 
     254          50 :         case ValueType::FLOAT:
     255          50 :             WriteVarUIntSingleByte(&pabyData,
     256             :                                    MAKE_KEY(knVALUE_FLOAT, WT_32BIT));
     257          50 :             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        1579 :             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        1629 :         case ValueType::UINT:
     272        1629 :             WriteVarUIntSingleByte(&pabyData,
     273             :                                    MAKE_KEY(knVALUE_UINT, WT_VARINT));
     274        1628 :             WriteVarUInt(&pabyData, m_nUIntValue);
     275        1629 :             break;
     276             : 
     277          30 :         case ValueType::SINT:
     278          30 :             WriteVarUIntSingleByte(&pabyData,
     279             :                                    MAKE_KEY(knVALUE_SINT, WT_VARINT));
     280          30 :             WriteVarSInt(&pabyData, m_nIntValue);
     281          30 :             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          18 :             break;
     288             : 
     289           0 :         default:
     290           0 :             break;
     291             :     }
     292             : 
     293        8070 :     CPLAssert(pabyData == *ppabyData + getSize());
     294        8070 :     *ppabyData = pabyData;
     295        8070 : }
     296             : 
     297             : /************************************************************************/
     298             : /*                             read()                                   */
     299             : /************************************************************************/
     300             : 
     301        4406 : bool MVTTileLayerValue::read(const GByte **ppabyData,
     302             :                              const GByte *pabyDataLimit)
     303             : {
     304        4406 :     const GByte *pabyData = *ppabyData;
     305             : 
     306             :     try
     307             :     {
     308        4406 :         unsigned int nKey = 0;
     309        4406 :         if (pabyData < pabyDataLimit)
     310             :         {
     311        4406 :             READ_FIELD_KEY(nKey);
     312             : 
     313        4406 :             if (nKey == MAKE_KEY(knVALUE_STRING, WT_DATA))
     314             :             {
     315        2614 :                 char *pszValue = nullptr;
     316        2614 :                 READ_TEXT(pabyData, pabyDataLimit, pszValue);
     317             :                 // cppcheck-suppress nullPointer
     318        2614 :                 setStringValue(pszValue);
     319        2614 :                 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        4406 :         *ppabyData = pabyData;
     355        4406 :         return true;
     356             :     }
     357           0 :     catch (const GPBException &)
     358             :     {
     359           0 :         return false;
     360             :     }
     361             : }
     362             : 
     363             : /************************************************************************/
     364             : /*                           MVTTileLayer()                             */
     365             : /************************************************************************/
     366             : 
     367        7190 : MVTTileLayerFeature::MVTTileLayerFeature()
     368             : {
     369        7187 : }
     370             : 
     371             : /************************************************************************/
     372             : /*                             setOwner()                               */
     373             : /************************************************************************/
     374             : 
     375        7169 : void MVTTileLayerFeature::setOwner(MVTTileLayer *poOwner)
     376             : {
     377        7169 :     CPLAssert(!m_poOwner);
     378        7169 :     m_poOwner = poOwner;
     379        7169 :     m_poOwner->invalidateCachedSize();
     380        7170 : }
     381             : 
     382             : /************************************************************************/
     383             : /*                       invalidateCachedSize()                         */
     384             : /************************************************************************/
     385             : 
     386       52901 : void MVTTileLayerFeature::invalidateCachedSize()
     387             : {
     388       52901 :     m_bCachedSize = false;
     389       52901 :     m_nCachedSize = 0;
     390       52901 :     if (m_poOwner)
     391       40865 :         m_poOwner->invalidateCachedSize();
     392       52870 : }
     393             : 
     394             : /************************************************************************/
     395             : /*                        GetPackedArraySize()                          */
     396             : /************************************************************************/
     397             : 
     398        9850 : static size_t GetPackedArraySize(const std::vector<GUInt32> &anVals)
     399             : {
     400        9850 :     size_t nPackedSize = 0;
     401       70018 :     for (const auto &nVal : anVals)
     402             :     {
     403       60201 :         nPackedSize += GetVarUIntSize(nVal);
     404             :     }
     405        9863 :     return nPackedSize;
     406             : }
     407             : 
     408             : /************************************************************************/
     409             : /*                            getSize()                                 */
     410             : /************************************************************************/
     411             : 
     412        9273 : size_t MVTTileLayerFeature::getSize() const
     413             : {
     414        9273 :     if (m_bCachedSize)
     415        6178 :         return m_nCachedSize;
     416        3095 :     m_bCachedSize = true;
     417        3095 :     m_nCachedSize = 0;
     418        3095 :     if (m_bHasId)
     419         106 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nId);
     420        3095 :     if (!m_anTags.empty())
     421             :     {
     422        1838 :         size_t nPackedSize = GetPackedArraySize(m_anTags);
     423        1838 :         m_nCachedSize += knSIZE_KEY;
     424        1838 :         m_nCachedSize += GetVarUIntSize(nPackedSize);
     425        1839 :         m_nCachedSize += nPackedSize;
     426             :     }
     427        3091 :     if (m_bHasType)
     428        3088 :         m_nCachedSize += knSIZE_KEY + 1;  // fixed size for m_eType
     429        3091 :     if (!m_anGeometry.empty())
     430             :     {
     431        3089 :         size_t nPackedSize = GetPackedArraySize(m_anGeometry);
     432        3093 :         m_nCachedSize += knSIZE_KEY;
     433        3093 :         m_nCachedSize += GetVarUIntSize(nPackedSize);
     434        3095 :         m_nCachedSize += nPackedSize;
     435             :     }
     436        3096 :     return m_nCachedSize;
     437             : }
     438             : 
     439             : /************************************************************************/
     440             : /*                        WriteUIntPackedArray()                        */
     441             : /************************************************************************/
     442             : 
     443        4924 : static void WriteUIntPackedArray(GByte **ppabyData, int nKey,
     444             :                                  const std::vector<GUInt32> &anVals)
     445             : {
     446        4924 :     GByte *pabyData = *ppabyData;
     447        4924 :     const size_t nPackedSize = GetPackedArraySize(anVals);
     448        4933 :     WriteVarUIntSingleByte(&pabyData, nKey);
     449        4930 :     WriteVarUInt(&pabyData, nPackedSize);
     450       35034 :     for (const auto &nVal : anVals)
     451             :     {
     452       30110 :         WriteVarUInt(&pabyData, nVal);
     453             :     }
     454        4936 :     *ppabyData = pabyData;
     455        4936 : }
     456             : 
     457             : /************************************************************************/
     458             : /*                             write()                                  */
     459             : /************************************************************************/
     460             : 
     461        3088 : void MVTTileLayerFeature::write(GByte **ppabyData) const
     462             : {
     463        3088 :     GByte *pabyData = *ppabyData;
     464             : 
     465        3088 :     if (m_bHasId)
     466             :     {
     467         106 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knFEATURE_ID, WT_VARINT));
     468         106 :         WriteVarUInt(&pabyData, m_nId);
     469             :     }
     470        3088 :     if (!m_anTags.empty())
     471             :     {
     472        1837 :         WriteUIntPackedArray(&pabyData, MAKE_KEY(knFEATURE_TAGS, WT_DATA),
     473        1837 :                              m_anTags);
     474             :     }
     475        3092 :     if (m_bHasType)
     476             :     {
     477        3092 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knFEATURE_TYPE, WT_VARINT));
     478        3090 :         WriteVarUIntSingleByte(&pabyData, static_cast<GUIntBig>(m_eType));
     479             :     }
     480        3090 :     if (!m_anGeometry.empty())
     481             :     {
     482        3091 :         WriteUIntPackedArray(&pabyData, MAKE_KEY(knFEATURE_GEOMETRY, WT_DATA),
     483        3091 :                              m_anGeometry);
     484             :     }
     485             : 
     486        3092 :     CPLAssert(pabyData == *ppabyData + getSize());
     487        3091 :     *ppabyData = pabyData;
     488        3091 : }
     489             : 
     490             : /************************************************************************/
     491             : /*                             read()                                   */
     492             : /************************************************************************/
     493             : 
     494        1592 : bool MVTTileLayerFeature::read(const GByte **ppabyData,
     495             :                                const GByte *pabyDataLimit)
     496             : {
     497        1592 :     const GByte *pabyData = *ppabyData;
     498             : 
     499             :     try
     500             :     {
     501        1592 :         unsigned int nKey = 0;
     502        5781 :         while (pabyData < pabyDataLimit)
     503             :         {
     504        4189 :             READ_FIELD_KEY(nKey);
     505        4189 :             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        4136 :             else if (nKey == MAKE_KEY(knFEATURE_TAGS, WT_DATA))
     512             :             {
     513         952 :                 unsigned int nTagsSize = 0;
     514         952 :                 READ_SIZE(pabyData, pabyDataLimit, nTagsSize);
     515         952 :                 const GByte *pabyDataTagsEnd = pabyData + nTagsSize;
     516        9764 :                 while (pabyData < pabyDataTagsEnd)
     517             :                 {
     518        8812 :                     unsigned int nTag = 0;
     519        8812 :                     READ_VARUINT32(pabyData, pabyDataTagsEnd, nTag);
     520        8812 :                     addTag(nTag);
     521             :                 }
     522         952 :                 pabyData = pabyDataTagsEnd;
     523             :             }
     524        3184 :             else if (nKey == MAKE_KEY(knFEATURE_TYPE, WT_VARINT))
     525             :             {
     526        1592 :                 unsigned int nType = 0;
     527        1592 :                 READ_VARUINT32(pabyData, pabyDataLimit, nType);
     528        1592 :                 if (nType <= knGEOM_TYPE_POLYGON)
     529        1592 :                     setType(static_cast<GeomType>(nType));
     530             :             }
     531        1592 :             else if (nKey == MAKE_KEY(knFEATURE_GEOMETRY, WT_DATA))
     532             :             {
     533        1592 :                 unsigned int nGeometrySize = 0;
     534        1592 :                 READ_SIZE(pabyData, pabyDataLimit, nGeometrySize);
     535        1592 :                 const GByte *pabyDataGeometryEnd = pabyData + nGeometrySize;
     536        8394 :                 while (pabyData < pabyDataGeometryEnd)
     537             :                 {
     538        6802 :                     unsigned int nGeometry = 0;
     539        6802 :                     READ_VARUINT32(pabyData, pabyDataGeometryEnd, nGeometry);
     540        6802 :                     addGeometry(nGeometry);
     541             :                 }
     542        1592 :                 pabyData = pabyDataGeometryEnd;
     543             :             }
     544             :             else
     545             :             {
     546           0 :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     547             :             }
     548             :         }
     549        1592 :         *ppabyData = pabyData;
     550        1592 :         return true;
     551             :     }
     552           0 :     catch (const GPBException &)
     553             :     {
     554           0 :         return false;
     555             :     }
     556             : }
     557             : 
     558             : /************************************************************************/
     559             : /*                           MVTTileLayer()                             */
     560             : /************************************************************************/
     561             : 
     562        6946 : MVTTileLayer::MVTTileLayer()
     563             : {
     564        6937 : }
     565             : 
     566             : /************************************************************************/
     567             : /*                             setOwner()                               */
     568             : /************************************************************************/
     569             : 
     570        1347 : void MVTTileLayer::setOwner(MVTTile *poOwner)
     571             : {
     572        1347 :     CPLAssert(!m_poOwner);
     573        1347 :     m_poOwner = poOwner;
     574        1347 :     m_poOwner->invalidateCachedSize();
     575        1347 : }
     576             : 
     577             : /************************************************************************/
     578             : /*                       invalidateCachedSize()                         */
     579             : /************************************************************************/
     580             : 
     581       87242 : void MVTTileLayer::invalidateCachedSize()
     582             : {
     583       87242 :     m_bCachedSize = false;
     584       87242 :     m_nCachedSize = 0;
     585       87242 :     if (m_poOwner)
     586       14529 :         m_poOwner->invalidateCachedSize();
     587       87242 : }
     588             : 
     589             : /************************************************************************/
     590             : /*                          addFeature()                                */
     591             : /************************************************************************/
     592             : 
     593        7171 : size_t MVTTileLayer::addFeature(std::shared_ptr<MVTTileLayerFeature> poFeature)
     594             : {
     595        7171 :     poFeature->setOwner(this);
     596        7171 :     m_apoFeatures.push_back(poFeature);
     597        7171 :     invalidateCachedSize();
     598        7166 :     return m_apoFeatures.size() - 1;
     599             : }
     600             : 
     601             : /************************************************************************/
     602             : /*                            getSize()                                 */
     603             : /************************************************************************/
     604             : 
     605        7073 : size_t MVTTileLayer::getSize() const
     606             : {
     607        7073 :     if (m_bCachedSize)
     608        4201 :         return m_nCachedSize;
     609        2872 :     m_nCachedSize = knSIZE_KEY + GetTextSize(m_osName);
     610        5954 :     for (const auto &poFeature : m_apoFeatures)
     611             :     {
     612        3086 :         const size_t nFeatureSize = poFeature->getSize();
     613        3093 :         m_nCachedSize +=
     614        3097 :             knSIZE_KEY + GetVarUIntSize(nFeatureSize) + nFeatureSize;
     615             :     }
     616       10811 :     for (const auto &osKey : m_aosKeys)
     617             :     {
     618        7945 :         m_nCachedSize += knSIZE_KEY + GetTextSize(osKey);
     619             :     }
     620       10926 :     for (const auto &oValue : m_aoValues)
     621             :     {
     622        8065 :         const size_t nValueSize = oValue.getSize();
     623        8067 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(nValueSize) + nValueSize;
     624             :     }
     625        2860 :     if (m_bHasExtent)
     626             :     {
     627        1353 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nExtent);
     628             :     }
     629        2860 :     m_nCachedSize += knSIZE_KEY + GetVarUIntSize(m_nVersion);
     630        2858 :     m_bCachedSize = true;
     631        2858 :     return m_nCachedSize;
     632             : }
     633             : 
     634             : /************************************************************************/
     635             : /*                             write()                                  */
     636             : /************************************************************************/
     637             : 
     638        2853 : void MVTTileLayer::write(GByte **ppabyData) const
     639             : {
     640        2853 :     GByte *pabyData = *ppabyData;
     641             : 
     642        2853 :     WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_NAME, WT_DATA));
     643        2853 :     WriteText(&pabyData, m_osName);
     644             : 
     645        5944 :     for (const auto &poFeature : m_apoFeatures)
     646             :     {
     647        3086 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_FEATURES, WT_DATA));
     648        3089 :         WriteVarUInt(&pabyData, poFeature->getSize());
     649        3085 :         poFeature->write(&pabyData);
     650             :     }
     651             : 
     652       10812 :     for (const auto &osKey : m_aosKeys)
     653             :     {
     654        7946 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_KEYS, WT_DATA));
     655        7946 :         WriteText(&pabyData, osKey);
     656             :     }
     657             : 
     658       10932 :     for (const auto &oValue : m_aoValues)
     659             :     {
     660        8070 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_VALUES, WT_DATA));
     661        8068 :         WriteVarUInt(&pabyData, oValue.getSize());
     662        8072 :         oValue.write(&pabyData);
     663             :     }
     664             : 
     665        2858 :     if (m_bHasExtent)
     666             :     {
     667        1347 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_EXTENT, WT_VARINT));
     668        1347 :         WriteVarUInt(&pabyData, m_nExtent);
     669             :     }
     670             : 
     671        2858 :     WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER_VERSION, WT_VARINT));
     672        2857 :     WriteVarUInt(&pabyData, m_nVersion);
     673             : 
     674        2853 :     CPLAssert(pabyData == *ppabyData + getSize());
     675        2853 :     *ppabyData = pabyData;
     676        2853 : }
     677             : 
     678             : /************************************************************************/
     679             : /*                             write()                                  */
     680             : /************************************************************************/
     681             : 
     682        1515 : void MVTTileLayer::write(GByte *pabyData) const
     683             : {
     684        1515 :     write(&pabyData);
     685        1505 : }
     686             : 
     687             : /************************************************************************/
     688             : /*                             write()                                  */
     689             : /************************************************************************/
     690             : 
     691        1510 : std::string MVTTileLayer::write() const
     692             : {
     693        1510 :     std::string buffer;
     694        1510 :     size_t nSize = getSize();
     695        1509 :     buffer.resize(nSize);
     696        1511 :     write(reinterpret_cast<GByte *>(&buffer[0]));
     697        1503 :     return buffer;
     698             : }
     699             : 
     700             : /************************************************************************/
     701             : /*                             read()                                   */
     702             : /************************************************************************/
     703             : 
     704        1592 : bool MVTTileLayer::read(const GByte **ppabyData, const GByte *pabyDataLimit)
     705             : {
     706        1592 :     const GByte *pabyData = *ppabyData;
     707             : 
     708             :     try
     709             :     {
     710        1592 :         unsigned int nKey = 0;
     711       15180 :         while (pabyData < pabyDataLimit)
     712             :         {
     713       13588 :             READ_FIELD_KEY(nKey);
     714       13588 :             if (nKey == MAKE_KEY(knLAYER_NAME, WT_DATA))
     715             :             {
     716        1592 :                 char *pszLayerName = nullptr;
     717        1592 :                 READ_TEXT(pabyData, pabyDataLimit, pszLayerName);
     718             :                 // cppcheck-suppress nullPointer
     719        1592 :                 setName(pszLayerName);
     720        1592 :                 CPLFree(pszLayerName);
     721             :             }
     722       11996 :             else if (nKey == MAKE_KEY(knLAYER_FEATURES, WT_DATA))
     723             :             {
     724        1592 :                 unsigned int nFeatureLength = 0;
     725        1592 :                 READ_SIZE(pabyData, pabyDataLimit, nFeatureLength);
     726        1592 :                 const GByte *pabyDataFeatureEnd = pabyData + nFeatureLength;
     727             :                 std::shared_ptr<MVTTileLayerFeature> poFeature(
     728        1592 :                     new MVTTileLayerFeature());
     729        1592 :                 addFeature(poFeature);
     730        1592 :                 if (!poFeature->read(&pabyData, pabyDataFeatureEnd))
     731           0 :                     return false;
     732        1592 :                 pabyData = pabyDataFeatureEnd;
     733             :             }
     734       10404 :             else if (nKey == MAKE_KEY(knLAYER_KEYS, WT_DATA))
     735             :             {
     736        4406 :                 char *pszKey = nullptr;
     737        4406 :                 READ_TEXT(pabyData, pabyDataLimit, pszKey);
     738             :                 // cppcheck-suppress nullPointer
     739        4406 :                 addKey(pszKey);
     740        4406 :                 CPLFree(pszKey);
     741             :             }
     742        5998 :             else if (nKey == MAKE_KEY(knLAYER_VALUES, WT_DATA))
     743             :             {
     744        4406 :                 unsigned int nValueLength = 0;
     745        4406 :                 READ_SIZE(pabyData, pabyDataLimit, nValueLength);
     746        4406 :                 const GByte *pabyDataValueEnd = pabyData + nValueLength;
     747        4406 :                 MVTTileLayerValue oValue;
     748        4406 :                 if (!oValue.read(&pabyData, pabyDataValueEnd))
     749           0 :                     return false;
     750        4406 :                 addValue(oValue);
     751        4406 :                 pabyData = pabyDataValueEnd;
     752             :             }
     753        1592 :             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        1592 :             else if (nKey == MAKE_KEY(knLAYER_VERSION, WT_VARINT))
     760             :             {
     761        1592 :                 unsigned int nVersion = 0;
     762        1592 :                 READ_VARUINT32(pabyData, pabyDataLimit, nVersion);
     763        1592 :                 setVersion(nVersion);
     764             :             }
     765             :             else
     766             :             {
     767           0 :                 SKIP_UNKNOWN_FIELD(pabyData, pabyDataLimit, FALSE);
     768             :             }
     769             :         }
     770        1592 :         *ppabyData = pabyData;
     771        1592 :         return true;
     772             :     }
     773           0 :     catch (const GPBException &)
     774             :     {
     775           0 :         return false;
     776             :     }
     777             : }
     778             : 
     779             : /************************************************************************/
     780             : /*                             read()                                   */
     781             : /************************************************************************/
     782             : 
     783        1592 : bool MVTTileLayer::read(const GByte *pabyData, const GByte *pabyEnd)
     784             : {
     785        1592 :     return read(&pabyData, pabyEnd);
     786             : }
     787             : 
     788             : /************************************************************************/
     789             : /*                             MVTTile()                                */
     790             : /************************************************************************/
     791             : 
     792         893 : MVTTile::MVTTile()
     793             : {
     794         893 : }
     795             : 
     796             : /************************************************************************/
     797             : /*                            addLayer()                                */
     798             : /************************************************************************/
     799             : 
     800        1347 : void MVTTile::addLayer(std::shared_ptr<MVTTileLayer> poLayer)
     801             : {
     802        1347 :     poLayer->setOwner(this);
     803        1347 :     invalidateCachedSize();
     804        1347 :     m_apoLayers.push_back(poLayer);
     805        1347 : }
     806             : 
     807             : /************************************************************************/
     808             : /*                            getSize()                                 */
     809             : /************************************************************************/
     810             : 
     811        1831 : size_t MVTTile::getSize() const
     812             : {
     813        1831 :     if (m_bCachedSize)
     814         919 :         return m_nCachedSize;
     815         912 :     m_nCachedSize = 0;
     816        2265 :     for (const auto &poLayer : m_apoLayers)
     817             :     {
     818        1353 :         const size_t nLayerSize = poLayer->getSize();
     819        1353 :         m_nCachedSize += knSIZE_KEY + GetVarUIntSize(nLayerSize) + nLayerSize;
     820             :     }
     821         912 :     m_bCachedSize = true;
     822         912 :     return m_nCachedSize;
     823             : }
     824             : 
     825             : /************************************************************************/
     826             : /*                             write()                                  */
     827             : /************************************************************************/
     828             : 
     829         906 : void MVTTile::write(GByte **ppabyData) const
     830             : {
     831         906 :     GByte *pabyData = *ppabyData;
     832             : 
     833        2253 :     for (const auto &poLayer : m_apoLayers)
     834             :     {
     835        1347 :         WriteVarUIntSingleByte(&pabyData, MAKE_KEY(knLAYER, WT_DATA));
     836        1347 :         WriteVarUInt(&pabyData, poLayer->getSize());
     837        1347 :         poLayer->write(&pabyData);
     838             :     }
     839             : 
     840         906 :     CPLAssert(pabyData == *ppabyData + getSize());
     841         906 :     *ppabyData = pabyData;
     842         906 : }
     843             : 
     844             : /************************************************************************/
     845             : /*                             write()                                  */
     846             : /************************************************************************/
     847             : 
     848         906 : void MVTTile::write(GByte *pabyData) const
     849             : {
     850         906 :     write(&pabyData);
     851         906 : }
     852             : 
     853             : /************************************************************************/
     854             : /*                             write()                                  */
     855             : /************************************************************************/
     856             : 
     857         906 : std::string MVTTile::write() const
     858             : {
     859         906 :     std::string buffer;
     860         906 :     size_t nSize = getSize();
     861         906 :     if (nSize)
     862             :     {
     863         906 :         buffer.resize(nSize);
     864         906 :         write(reinterpret_cast<GByte *>(&buffer[0]));
     865             :     }
     866         906 :     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