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
|