130 const int numTiles =
static_cast<int>( pow( 2, mTileID.zoomLevel() ) );
132 const double z0Width = rootMatrix.
extent().
width();
137 const double tileDX = z0Width / numTiles;
138 const double tileDY = z0Height / numTiles;
139 const double tileXMin = z0xMinimum + mTileID.column() * tileDX;
140 const double tileYMax = z0yMaximum - mTileID.row() * tileDY;
142 QMap<QString, vector_tile::Tile>::const_iterator it = tiles.constBegin();
143 for ( ; it != tiles.constEnd(); ++it )
145 vector_tile::Tile tile = it.value();
147 for (
int layerNum = 0; layerNum < tile.layers_size(); layerNum++ )
149 const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum );
151 const QString layerName = layer.name().c_str();
152 if ( layerSubset && !layerSubset->contains( QString() ) && !layerSubset->contains( layerName ) )
156 QgsFields layerFields = perLayerFields[layerName];
158 const auto allLayerFields = perLayerFields.find( QString() );
159 if ( allLayerFields != perLayerFields.end() )
162 for (
const QgsField &field : allLayerFields.value() )
164 if ( layerFields.
lookupField( field.name() ) == -1 )
166 layerFields.
append( field );
172 QHash<int, int> tagKeyIndexToFieldIndex;
173 for (
int i = 0; i < layer.keys_size(); ++i )
175 const int fieldIndex = layerFields.
indexOf( layer.keys( i ).c_str() );
176 if ( fieldIndex != -1 )
177 tagKeyIndexToFieldIndex.insert( i, fieldIndex );
181 for (
int featureNum = 0; featureNum < layer.features_size(); featureNum++ )
183 const ::vector_tile::Tile_Feature &feature = layer.features( featureNum );
191 fid |= ( layerNum & 0xff ) << 24;
192 fid |= (
static_cast<QgsFeatureId>( mTileID.row() ) & 0xff ) << 32;
193 fid |= (
static_cast<QgsFeatureId>( mTileID.column() ) & 0xff ) << 40;
202 for (
int tagNum = 0; tagNum + 1 < feature.tags_size(); tagNum += 2 )
204 const int keyIndex =
static_cast<int>( feature.tags( tagNum ) );
205 const int fieldIndex = tagKeyIndexToFieldIndex.value( keyIndex, -1 );
206 if ( fieldIndex == -1 )
209 const int valueIndex =
static_cast<int>( feature.tags( tagNum + 1 ) );
210 if ( valueIndex >= layer.values_size() )
215 const ::vector_tile::Tile_Value &value = layer.values( valueIndex );
217 if ( value.has_string_value() )
218 f.
setAttribute( fieldIndex, QString::fromStdString( value.string_value() ) );
219 else if ( value.has_float_value() )
220 f.
setAttribute( fieldIndex,
static_cast<double>( value.float_value() ) );
221 else if ( value.has_double_value() )
223 else if ( value.has_int_value() )
224 f.
setAttribute( fieldIndex,
static_cast<long long>( value.int_value() ) );
225 else if ( value.has_uint_value() )
226 f.
setAttribute( fieldIndex,
static_cast<long long>( value.uint_value() ) );
227 else if ( value.has_sint_value() )
228 f.
setAttribute( fieldIndex,
static_cast<long long>( value.sint_value() ) );
229 else if ( value.has_bool_value() )
230 f.
setAttribute( fieldIndex,
static_cast<bool>( value.bool_value() ) );
241 const int extent =
static_cast<int>( layer.extent() );
242 int cursorx = 0, cursory = 0;
244 QVector<QgsPoint *> outputPoints;
245 QVector<QgsLineString *> outputLinestrings;
246 QVector<QgsPolygon *> outputPolygons;
247 QVector<QgsPoint> tmpPoints;
249 for (
int i = 0; i < feature.geometry_size(); i++ )
251 const unsigned g = feature.geometry( i );
252 const unsigned cmdId = g & 0x7;
253 const int cmdCount =
static_cast<int>( g >> 3 );
256 if ( i +
static_cast<int>( cmdCount ) * 2 >= feature.geometry_size() )
262 if ( feature.type() == vector_tile::Tile_GeomType_POINT )
263 outputPoints.reserve(
static_cast<int>( outputPoints.size() ) + cmdCount );
265 tmpPoints.reserve(
static_cast<int>( tmpPoints.size() ) + cmdCount );
267 for (
int j = 0; j < cmdCount; j++ )
269 const int v =
static_cast<int>( feature.geometry( i + 1 ) );
270 const int w =
static_cast<int>( feature.geometry( i + 2 ) );
271 const int dx = ( ( v >> 1 ) ^ ( -( v & 1 ) ) );
272 const int dy = ( ( w >> 1 ) ^ ( -( w & 1 ) ) );
275 const double px = tileXMin + tileDX * double( cursorx ) / double( extent );
276 const double py = tileYMax - tileDY * double( cursory ) / double( extent );
278 if ( feature.type() == vector_tile::Tile_GeomType_POINT )
280 outputPoints.append(
new QgsPoint( px, py ) );
282 else if ( feature.type() == vector_tile::Tile_GeomType_LINESTRING )
284 if ( tmpPoints.size() > 0 )
289 tmpPoints.append(
QgsPoint( px, py ) );
291 else if ( feature.type() == vector_tile::Tile_GeomType_POLYGON )
293 tmpPoints.append(
QgsPoint( px, py ) );
298 else if ( cmdId == 2 )
300 if ( i +
static_cast<int>( cmdCount ) * 2 >= feature.geometry_size() )
305 tmpPoints.reserve( tmpPoints.size() + cmdCount );
306 for (
int j = 0; j < cmdCount; j++ )
308 const int v =
static_cast<int>( feature.geometry( i + 1 ) );
309 const int w =
static_cast<int>( feature.geometry( i + 2 ) );
310 const int dx = ( v >> 1 ) ^ ( -( v & 1 ) );
311 const int dy = ( w >> 1 ) ^ ( -( w & 1 ) );
314 const double px = tileXMin + tileDX * double( cursorx ) / double( extent );
315 const double py = tileYMax - tileDY * double( cursory ) / double( extent );
317 tmpPoints.push_back(
QgsPoint( px, py ) );
321 else if ( cmdId == 7 )
323 if ( feature.type() == vector_tile::Tile_GeomType_POLYGON )
325 tmpPoints.append( tmpPoints.first() );
327 auto ring = std::make_unique<QgsLineString>( tmpPoints );
335 outputPolygons.append( p );
340 if ( outputPolygons.count() != 0 )
342 outputPolygons[outputPolygons.count() - 1]->addInteriorRing( ring.release() );
346 QgsDebugError( u
"Malformed geometry: first ring of a polygon is interior ring"_s );
353 QgsDebugError( u
"Unexpected command ID: %1"_s.arg( cmdId ) );
358 if ( feature.type() == vector_tile::Tile_GeomType_POINT )
360 geomType = u
"Point"_s;
361 if ( outputPoints.count() == 1 )
366 mp->
reserve( outputPoints.count() );
367 for (
int k = 0; k < outputPoints.count(); ++k )
372 else if ( feature.type() == vector_tile::Tile_GeomType_LINESTRING )
374 geomType = u
"LineString"_s;
379 if ( outputLinestrings.count() == 1 )
384 mls->
reserve( outputLinestrings.size() );
385 for (
int k = 0; k < outputLinestrings.count(); ++k )
390 else if ( feature.type() == vector_tile::Tile_GeomType_POLYGON )
392 geomType = u
"Polygon"_s;
394 if ( outputPolygons.count() == 1 )
399 mpl->
reserve( outputPolygons.size() );
400 for (
int k = 0; k < outputPolygons.count(); ++k )