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