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