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 * Permission is hereby granted, free of charge, to any person obtaining a 11 * copy of this software and associated documentation files (the "Software"), 12 * to deal in the Software without restriction, including without limitation 13 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 * and/or sell copies of the Software, and to permit persons to whom the 15 * Software is furnished to do so, subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be included 18 * in all copies or substantial portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 ****************************************************************************/ 28 29 #ifndef MVT_TILE_H 30 #define MVT_TILE_H 31 32 #include "cpl_port.h" 33 34 #include <memory> 35 #include <vector> 36 37 /* See https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto */ 38 constexpr int knLAYER = 3; 39 40 constexpr int knLAYER_NAME = 1; 41 constexpr int knLAYER_FEATURES = 2; 42 constexpr int knLAYER_KEYS = 3; 43 constexpr int knLAYER_VALUES = 4; 44 constexpr int knLAYER_EXTENT = 5; 45 constexpr int knLAYER_VERSION = 15; 46 47 constexpr int knVALUE_STRING = 1; 48 constexpr int knVALUE_FLOAT = 2; 49 constexpr int knVALUE_DOUBLE = 3; 50 constexpr int knVALUE_INT = 4; 51 constexpr int knVALUE_UINT = 5; 52 constexpr int knVALUE_SINT = 6; 53 constexpr int knVALUE_BOOL = 7; 54 55 constexpr int knFEATURE_ID = 1; 56 constexpr int knFEATURE_TAGS = 2; 57 constexpr int knFEATURE_TYPE = 3; 58 constexpr int knFEATURE_GEOMETRY = 4; 59 60 constexpr int knGEOM_TYPE_UNKNOWN = 0; 61 constexpr int knGEOM_TYPE_POINT = 1; 62 constexpr int knGEOM_TYPE_LINESTRING = 2; 63 constexpr int knGEOM_TYPE_POLYGON = 3; 64 65 constexpr int knCMD_MOVETO = 1; 66 constexpr int knCMD_LINETO = 2; 67 constexpr int knCMD_CLOSEPATH = 7; 68 69 constexpr unsigned knDEFAULT_EXTENT = 4096; 70 71 /************************************************************************/ 72 /* MVTTileLayerValue */ 73 /************************************************************************/ 74 75 class MVTTileLayerValue 76 { 77 public: 78 enum class ValueType 79 { 80 NONE, 81 STRING, 82 FLOAT, 83 DOUBLE, 84 INT, 85 UINT, 86 SINT, 87 BOOL, 88 STRING_MAX_8, // optimization for short strings. 89 }; 90 91 private: 92 // Layout optimized for small memory footprint 93 union 94 { 95 float m_fValue; 96 double m_dfValue; 97 GInt64 m_nIntValue; 98 GUInt64 m_nUIntValue; 99 bool m_bBoolValue; 100 char* m_pszValue; 101 char m_achValue[8]; // optimization for short strings 102 }; 103 ValueType m_eType = ValueType::NONE; 104 105 void unset(); 106 107 public: 108 MVTTileLayerValue(); 109 ~MVTTileLayerValue(); 110 MVTTileLayerValue(const MVTTileLayerValue& oOther); 111 MVTTileLayerValue& operator=(const MVTTileLayerValue& oOther); 112 113 bool operator <(const MVTTileLayerValue& rhs) const; 114 getType()115 ValueType getType() const { return m_eType; } isNumeric()116 bool isNumeric() const { return m_eType == ValueType::FLOAT || 117 m_eType == ValueType::DOUBLE || 118 m_eType == ValueType::INT || 119 m_eType == ValueType::UINT || 120 m_eType == ValueType::SINT; } isString()121 bool isString() const { return m_eType == ValueType::STRING || 122 m_eType == ValueType::STRING_MAX_8; } 123 getFloatValue()124 float getFloatValue() const { return m_fValue; } getDoubleValue()125 double getDoubleValue() const { return m_dfValue; } getIntValue()126 GInt64 getIntValue() const { return m_nIntValue; } getUIntValue()127 GUInt64 getUIntValue() const { return m_nUIntValue; } getBoolValue()128 bool getBoolValue() const { return m_bBoolValue; } 129 getNumericValue()130 double getNumericValue() const 131 { if( m_eType == ValueType::FLOAT ) 132 return m_fValue; 133 if( m_eType == ValueType::DOUBLE ) 134 return m_dfValue; 135 if( m_eType == ValueType::INT || m_eType == ValueType::SINT ) 136 return static_cast<double>(m_nIntValue); 137 if( m_eType == ValueType::UINT ) 138 return static_cast<double>(m_nUIntValue); 139 return 0.0; 140 } 141 getStringValue()142 std::string getStringValue() const 143 { if( m_eType == ValueType::STRING ) 144 return m_pszValue; 145 else if( m_eType == ValueType::STRING_MAX_8 ) 146 { 147 char szBuf[8+1]; 148 memcpy(szBuf, m_achValue, 8); 149 szBuf[8] = 0; 150 return szBuf; 151 } 152 return std::string(); 153 } 154 155 void setStringValue(const std::string& osValue); setFloatValue(float fValue)156 void setFloatValue(float fValue) 157 { unset(); m_eType = ValueType::FLOAT; m_fValue = fValue; } setDoubleValue(double dfValue)158 void setDoubleValue(double dfValue) 159 { unset(); m_eType = ValueType::DOUBLE; m_dfValue = dfValue; } setIntValue(GInt64 nVal)160 void setIntValue(GInt64 nVal) 161 { unset(); m_eType = ValueType::INT; m_nIntValue = nVal; } setUIntValue(GUInt64 nVal)162 void setUIntValue(GUInt64 nVal) 163 { unset(); m_eType = ValueType::UINT; m_nUIntValue = nVal; } setSIntValue(GInt64 nVal)164 void setSIntValue(GInt64 nVal) 165 { unset(); m_eType = ValueType::SINT; m_nIntValue = nVal; } setBoolValue(bool bVal)166 void setBoolValue(bool bVal) 167 { unset(); m_eType = ValueType::BOOL; m_bBoolValue = bVal; } 168 169 void setValue(double dfVal); setValue(int nVal)170 void setValue(int nVal) { setValue(static_cast<GInt64>(nVal)); } setValue(GInt64 nVal)171 void setValue(GInt64 nVal) 172 { if (nVal < 0) 173 setSIntValue(nVal); 174 else 175 setUIntValue(nVal); 176 } 177 178 size_t getSize() const; 179 void write(GByte** ppabyData) const; 180 bool read(const GByte** ppabyData, const GByte* pabyEnd); 181 }; 182 183 /************************************************************************/ 184 /* MVTTileLayerFeature */ 185 /************************************************************************/ 186 187 class MVTTileLayer; 188 189 class MVTTileLayerFeature 190 { 191 public: 192 enum class GeomType: char 193 { 194 UNKNOWN = 0, 195 POINT = 1, 196 LINESTRING = 2, 197 POLYGON = 3 198 }; 199 200 private: 201 mutable size_t m_nCachedSize = 0; 202 GUInt64 m_nId = 0; 203 std::vector<GUInt32> m_anTags; 204 std::vector<GUInt32> m_anGeometry; 205 GeomType m_eType = GeomType::UNKNOWN; 206 mutable bool m_bCachedSize = false; 207 bool m_bHasId = false; 208 bool m_bHasType = false; 209 MVTTileLayer* m_poOwner = nullptr; 210 211 public: 212 MVTTileLayerFeature(); 213 void setOwner(MVTTileLayer* poOwner); 214 hasId()215 bool hasId() const { return m_bHasId; } getId()216 GUInt64 getId() const { return m_nId; } getTags()217 const std::vector<GUInt32>& getTags() const { return m_anTags; } hasType()218 bool hasType() const { return m_bHasType; } getType()219 GeomType getType() const { return m_eType; } getGeometryCount()220 GUInt32 getGeometryCount() const 221 { return static_cast<GUInt32>(m_anGeometry.size()); } getGeometry()222 const std::vector<GUInt32>& getGeometry() const { return m_anGeometry; } 223 setId(GUInt64 nId)224 void setId(GUInt64 nId) 225 { m_bHasId = true; 226 m_nId = nId; 227 invalidateCachedSize(); } addTag(GUInt32 nTag)228 void addTag(GUInt32 nTag) 229 { m_anTags.push_back(nTag); 230 invalidateCachedSize(); } setType(GeomType eType)231 void setType(GeomType eType) 232 { m_bHasType = true; 233 m_eType = eType; 234 invalidateCachedSize(); } resizeGeometryArray(GUInt32 nNewSize)235 void resizeGeometryArray(GUInt32 nNewSize) 236 { m_anGeometry.resize(nNewSize); 237 invalidateCachedSize(); } addGeometry(GUInt32 nGeometry)238 void addGeometry(GUInt32 nGeometry) 239 { m_anGeometry.push_back(nGeometry); 240 invalidateCachedSize(); } setGeometry(GUInt32 nIdx,GUInt32 nVal)241 void setGeometry(GUInt32 nIdx, GUInt32 nVal) 242 { m_anGeometry[nIdx] = nVal; 243 invalidateCachedSize(); } setGeometry(const std::vector<GUInt32> & anGeometry)244 void setGeometry(const std::vector<GUInt32>& anGeometry ) 245 { m_anGeometry = anGeometry; 246 invalidateCachedSize(); } 247 248 size_t getSize() const; 249 void write(GByte** ppabyData) const; 250 bool read(const GByte** ppabyData, const GByte* pabyEnd); 251 252 void invalidateCachedSize(); 253 }; 254 255 /************************************************************************/ 256 /* MVTTileLayer */ 257 /************************************************************************/ 258 259 class MVTTile; 260 261 class MVTTileLayer 262 { 263 mutable bool m_bCachedSize = false; 264 mutable size_t m_nCachedSize = 0; 265 GUInt32 m_nVersion = 1; 266 std::string m_osName; 267 std::vector<std::shared_ptr<MVTTileLayerFeature>> m_apoFeatures; 268 std::vector<std::string> m_aosKeys; 269 std::vector<MVTTileLayerValue> m_aoValues; 270 bool m_bHasExtent = false; 271 GUInt32 m_nExtent = 4096; 272 MVTTile* m_poOwner = nullptr; 273 274 public: 275 MVTTileLayer(); 276 void setOwner(MVTTile* poOwner); 277 getVersion()278 GUInt32 getVersion() const { return m_nVersion; } getName()279 const std::string& getName() const { return m_osName; } getFeatures()280 const std::vector<std::shared_ptr<MVTTileLayerFeature>>& getFeatures() 281 const 282 { return m_apoFeatures; } getKeys()283 const std::vector<std::string>& getKeys() const { return m_aosKeys; } getValues()284 const std::vector<MVTTileLayerValue>& getValues() const 285 { return m_aoValues; } getExtent()286 GUInt32 getExtent() const { return m_nExtent; } 287 setVersion(GUInt32 nVersion)288 void setVersion(GUInt32 nVersion) 289 { m_nVersion = nVersion; 290 invalidateCachedSize(); } setName(const std::string & osName)291 void setName(const std::string& osName) 292 { m_osName = osName; 293 invalidateCachedSize(); } 294 size_t addFeature(std::shared_ptr<MVTTileLayerFeature> poFeature); addKey(const std::string & osKey)295 GUInt32 addKey(const std::string& osKey) 296 { 297 m_aosKeys.push_back(osKey); 298 invalidateCachedSize(); 299 return static_cast<GUInt32>(m_aosKeys.size()) - 1; 300 } 301 addValue(const MVTTileLayerValue & oValue)302 GUInt32 addValue(const MVTTileLayerValue& oValue) 303 { 304 m_aoValues.push_back(oValue); 305 invalidateCachedSize(); 306 return static_cast<GUInt32>(m_aoValues.size()) - 1; 307 } 308 setExtent(GUInt32 nExtent)309 void setExtent(GUInt32 nExtent) 310 { 311 m_nExtent = nExtent; 312 m_bHasExtent = true; 313 invalidateCachedSize(); 314 } 315 316 size_t getSize() const; 317 void write(GByte** ppabyData) const; 318 void write(GByte* pabyData) const; 319 std::string write() const; 320 bool read(const GByte** ppabyData, const GByte* pabyEnd); 321 bool read(const GByte* pabyData, const GByte* pabyEnd); 322 323 void invalidateCachedSize(); 324 }; 325 326 /************************************************************************/ 327 /* MVTTile */ 328 /************************************************************************/ 329 330 class MVTTile 331 { 332 std::vector<std::shared_ptr<MVTTileLayer>> m_apoLayers; 333 mutable size_t m_nCachedSize = 0; 334 mutable bool m_bCachedSize = false; 335 336 public: 337 MVTTile(); 338 getLayers()339 const std::vector<std::shared_ptr<MVTTileLayer>>& getLayers() const 340 { return m_apoLayers; } 341 clear()342 void clear() { m_apoLayers.clear(); invalidateCachedSize(); } 343 void addLayer(std::shared_ptr<MVTTileLayer> poLayer); 344 size_t getSize() const; 345 void write(GByte** ppabyData) const; 346 void write(GByte* pabyData) const; 347 std::string write() const; 348 #ifdef ADD_MVT_TILE_READ 349 bool read(const GByte** ppabyData, const GByte* pabyEnd); 350 bool read(const GByte* pabyData, const GByte* pabyEnd); 351 #endif invalidateCachedSize()352 void invalidateCachedSize() { m_bCachedSize = false; m_nCachedSize = 0; } 353 }; 354 355 #endif // MVT_TILE_H 356