38 if ( !tile.ParseFromArray( rawTileData.constData(), rawTileData.count() ) )
43 mLayerNameToIndex.clear();
44 for (
int layerNum = 0; layerNum < tile.layers_size(); layerNum++ )
46 const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum );
47 QString layerName = layer.name().c_str();
48 mLayerNameToIndex[layerName] = layerNum;
55 QStringList layerNames;
56 for (
int layerNum = 0; layerNum < tile.layers_size(); layerNum++ )
58 const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum );
59 QString layerName = layer.name().c_str();
60 layerNames << layerName;
67 if ( !mLayerNameToIndex.contains( layerName ) )
70 const ::vector_tile::Tile_Layer &layer = tile.layers( mLayerNameToIndex[layerName] );
71 QStringList fieldNames;
72 for (
int i = 0; i < layer.keys_size(); ++i )
74 QString fieldName = layer.keys( i ).c_str();
75 fieldNames << fieldName;
84 int numTiles =
static_cast<int>( pow( 2, mTileID.
zoomLevel() ) );
85 double z0xMin = -20037508.3427892, z0yMin = -20037508.3427892;
86 double z0xMax = 20037508.3427892, z0yMax = 20037508.3427892;
87 double tileDX = ( z0xMax - z0xMin ) / numTiles;
88 double tileDY = ( z0yMax - z0yMin ) / numTiles;
89 double tileXMin = z0xMin + mTileID.
column() * tileDX;
90 double tileYMax = z0yMax - mTileID.
row() * tileDY;
92 for (
int layerNum = 0; layerNum < tile.layers_size(); layerNum++ )
94 const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum );
96 const QString layerName = layer.name().c_str();
97 if ( layerSubset && !layerSubset->contains( QString() ) && !layerSubset->contains( layerName ) )
101 QgsFields layerFields = perLayerFields[layerName];
104 QHash<int, int> tagKeyIndexToFieldIndex;
105 for (
int i = 0; i < layer.keys_size(); ++i )
107 int fieldIndex = layerFields.
indexOf( layer.keys( i ).c_str() );
108 if ( fieldIndex != -1 )
109 tagKeyIndexToFieldIndex.insert( i, fieldIndex );
113 for (
int featureNum = 0; featureNum < layer.features_size(); featureNum++ )
115 const ::vector_tile::Tile_Feature &feature = layer.features( featureNum );
118 if ( feature.has_id() )
126 fid |= ( layerNum & 0xff ) << 24;
137 for (
int tagNum = 0; tagNum + 1 < feature.tags_size(); tagNum += 2 )
139 int keyIndex =
static_cast<int>( feature.tags( tagNum ) );
140 int fieldIndex = tagKeyIndexToFieldIndex.value( keyIndex, -1 );
141 if ( fieldIndex == -1 )
144 int valueIndex =
static_cast<int>( feature.tags( tagNum + 1 ) );
145 if ( valueIndex >= layer.values_size() )
147 QgsDebugMsg( QStringLiteral(
"Invalid value index for attribute" ) );
150 const ::vector_tile::Tile_Value &value = layer.values( valueIndex );
152 if ( value.has_string_value() )
153 f.
setAttribute( fieldIndex, QString::fromStdString( value.string_value() ) );
154 else if ( value.has_float_value() )
155 f.
setAttribute( fieldIndex,
static_cast<double>( value.float_value() ) );
156 else if ( value.has_double_value() )
158 else if ( value.has_int_value() )
159 f.
setAttribute( fieldIndex,
static_cast<int>( value.int_value() ) );
160 else if ( value.has_uint_value() )
161 f.
setAttribute( fieldIndex,
static_cast<int>( value.uint_value() ) );
162 else if ( value.has_sint_value() )
163 f.
setAttribute( fieldIndex,
static_cast<int>( value.sint_value() ) );
164 else if ( value.has_bool_value() )
165 f.
setAttribute( fieldIndex,
static_cast<bool>( value.bool_value() ) );
168 QgsDebugMsg( QStringLiteral(
"Unexpected attribute value" ) );
176 int extent =
static_cast<int>( layer.extent() );
177 int cursorx = 0, cursory = 0;
179 QVector<QgsPoint *> outputPoints;
180 QVector<QgsLineString *> outputLinestrings;
181 QVector<QgsPolygon *> outputPolygons;
182 QVector<QgsPoint> tmpPoints;
184 for (
int i = 0; i < feature.geometry_size(); i ++ )
186 unsigned g = feature.geometry( i );
187 unsigned cmdId = g & 0x7;
188 unsigned cmdCount = g >> 3;
191 if ( i +
static_cast<int>( cmdCount ) * 2 >= feature.geometry_size() )
193 QgsDebugMsg( QStringLiteral(
"Malformed geometry: invalid cmdCount" ) );
197 if ( feature.type() == vector_tile::Tile_GeomType_POINT )
198 outputPoints.reserve( outputPoints.size() + cmdCount );
200 tmpPoints.reserve( tmpPoints.size() + cmdCount );
202 for (
unsigned j = 0; j < cmdCount; j++ )
204 unsigned v = feature.geometry( i + 1 );
205 unsigned w = feature.geometry( i + 2 );
206 int dx = ( ( v >> 1 ) ^ ( -( v & 1 ) ) );
207 int dy = ( ( w >> 1 ) ^ ( -( w & 1 ) ) );
210 double px = tileXMin + tileDX * double( cursorx ) / double( extent );
211 double py = tileYMax - tileDY * double( cursory ) / double( extent );
213 if ( feature.type() == vector_tile::Tile_GeomType_POINT )
215 outputPoints.append(
new QgsPoint( px, py ) );
217 else if ( feature.type() == vector_tile::Tile_GeomType_LINESTRING )
219 if ( tmpPoints.size() > 0 )
224 tmpPoints.append(
QgsPoint( px, py ) );
226 else if ( feature.type() == vector_tile::Tile_GeomType_POLYGON )
228 tmpPoints.append(
QgsPoint( px, py ) );
233 else if ( cmdId == 2 )
235 if ( i +
static_cast<int>( cmdCount ) * 2 >= feature.geometry_size() )
237 QgsDebugMsg( QStringLiteral(
"Malformed geometry: invalid cmdCount" ) );
240 tmpPoints.reserve( tmpPoints.size() + cmdCount );
241 for (
unsigned j = 0; j < cmdCount; j++ )
243 unsigned v = feature.geometry( i + 1 );
244 unsigned w = feature.geometry( i + 2 );
245 int dx = ( ( v >> 1 ) ^ ( -( v & 1 ) ) );
246 int dy = ( ( w >> 1 ) ^ ( -( w & 1 ) ) );
249 double px = tileXMin + tileDX * double( cursorx ) / double( extent );
250 double py = tileYMax - tileDY * double( cursory ) / double( extent );
252 tmpPoints.push_back(
QgsPoint( px, py ) );
256 else if ( cmdId == 7 )
258 if ( feature.type() == vector_tile::Tile_GeomType_POLYGON )
260 tmpPoints.append( tmpPoints.first() );
262 std::unique_ptr<QgsLineString> ring(
new QgsLineString( tmpPoints ) );
270 outputPolygons.append( p );
275 if ( outputPolygons.count() != 0 )
277 outputPolygons[outputPolygons.count() - 1]->addInteriorRing( ring.release() );
281 QgsDebugMsg( QStringLiteral(
"Malformed geometry: first ring of a polygon is interior ring" ) );
289 QgsDebugMsg( QStringLiteral(
"Unexpected command ID: %1" ).arg( cmdId ) );
294 if ( feature.type() == vector_tile::Tile_GeomType_POINT )
296 geomType = QStringLiteral(
"Point" );
297 if ( outputPoints.count() == 1 )
302 mp->
reserve( outputPoints.count() );
303 for (
int k = 0; k < outputPoints.count(); ++k )
308 else if ( feature.type() == vector_tile::Tile_GeomType_LINESTRING )
310 geomType = QStringLiteral(
"LineString" );
315 if ( outputLinestrings.count() == 1 )
320 mls->
reserve( outputLinestrings.size() );
321 for (
int k = 0; k < outputLinestrings.count(); ++k )
326 else if ( feature.type() == vector_tile::Tile_GeomType_POLYGON )
328 geomType = QStringLiteral(
"Polygon" );
330 if ( outputPolygons.count() == 1 )
335 mpl->
reserve( outputPolygons.size() );
336 for (
int k = 0; k < outputPolygons.count(); ++k )
342 f.
setAttribute( QStringLiteral(
"_geom_type" ), geomType );