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