[vector tiles] Fix relative path handling of "url" sources on a different domain

This commit is contained in:
Mathieu Pellerin 2025-09-20 17:43:35 +07:00
parent d72fd93a99
commit ff528b63cc
4 changed files with 35 additions and 13 deletions

View File

@ -112,34 +112,50 @@ QMap<QString, QString> QgsVectorTileUtils::parseStyleSourceUrl( const QString &s
continue;
}
QVariantList tiles;
QString tilesFrom;
if ( sourceData.contains( QStringLiteral( "tiles" ) ) )
{
tiles = sourceData["tiles"].toArray().toVariantList();
tilesFrom = styleUrl;
}
else if ( sourceData.contains( QStringLiteral( "url" ) ) )
{
tiles = parseStyleSourceContentUrl( sourceData.value( QStringLiteral( "url" ) ).toString(), headers, authCfg );
tilesFrom = sourceData.value( QStringLiteral( "url" ) ).toString();
}
else
{
QgsDebugError( QStringLiteral( "Could not read source %1" ).arg( sourceName ) );
}
if ( tiles.count() == 0 )
{
QgsDebugError( QStringLiteral( "Could not read source %1, not tiles found" ).arg( sourceName ) );
}
else
if ( !tiles.isEmpty() )
{
// take a random one from the list
// we might want to save the alternatives for a fallback later
QString tilesString = tiles[rand() % tiles.count()].toString();
QUrl tilesUrl( tilesString );
if ( tilesUrl.isRelative() )
QString tile = tiles[rand() % tiles.count()].toString();
QUrl tileUrl( tile );
if ( tileUrl.isRelative() )
{
QUrl temporaryStyleUrl( styleUrl );
tilesString = QStringLiteral( "%1://%2%3" ).arg( temporaryStyleUrl.scheme(), temporaryStyleUrl.host(), tilesString );
QUrl tilesFromUrl( tilesFrom );
if ( tile.startsWith( "/" ) )
{
tile = QStringLiteral( "%1://%2%3" ).arg( tilesFromUrl.scheme(), tilesFromUrl.host(), tile );
}
else
{
const QString fileName = tilesFromUrl.fileName();
if ( !fileName.isEmpty() && fileName.indexOf( "." ) >= 0 )
{
tilesFrom = tilesFrom.mid( 0, tilesFrom.length() - fileName.length() );
}
tile = QStringLiteral( "%1/%2" ).arg( tilesFrom, tile );
}
}
sources.insert( sourceName, tilesString );
sources.insert( sourceName, tile );
}
else
{
QgsDebugError( QStringLiteral( "Could not read source %1, not tiles found" ).arg( sourceName ) );
}
}
return sources;

View File

@ -72,6 +72,7 @@ void TestQgsVectorTileUtils::test_urlsFromStyle()
QString style1Content = style1File.readAll();
style1File.close();
style1Content.replace( QString( "_TILE_SOURCE_TEST_PATH_" ), "file://" + dataDir + "/vector_tile/styles" );
style1Content.replace( QString( "_TILE_SOURCE_EXTERNE_TEST_PATH_" ), "file://" + dataDir + "/vector_tile/styles_externe" );
QFile fixedStyleFilePath( QDir::tempPath() + QStringLiteral( "/style1.json" ) );
if ( fixedStyleFilePath.open( QFile::WriteOnly | QFile::Truncate ) )
{
@ -81,7 +82,7 @@ void TestQgsVectorTileUtils::test_urlsFromStyle()
fixedStyleFilePath.close();
auto sources = QgsVectorTileUtils::parseStyleSourceUrl( "file://" + fixedStyleFilePath.fileName() );
QCOMPARE( sources.count(), 2 );
QCOMPARE( sources.count(), 3 );
QVERIFY( sources.contains( "base_v1.0.0" ) );
QString sourceUrl = sources.value( "base_v1.0.0" );
sourceUrl.replace( QRegularExpression( "vectortiles[0-9]" ), QStringLiteral( "vectortilesX" ) );
@ -90,6 +91,10 @@ void TestQgsVectorTileUtils::test_urlsFromStyle()
sourceUrl = sources.value( "terrain_v1.0.0" );
sourceUrl.replace( QRegularExpression( "vectortiles[0-9]" ), QStringLiteral( "vectortilesX" ) );
QCOMPARE( sourceUrl, "https://vectortilesX.geo.admin.ch/tiles/ch.swisstopo.relief.vt/v1.0.0/{z}/{x}/{y}.pbf" );
QVERIFY( sources.contains( "terrain_externe_v1.0.0" ) );
sourceUrl = sources.value( "terrain_externe_v1.0.0" );
QCOMPARE( sourceUrl, "file://" + dataDir + "/vector_tile/styles_externe/VectorTileServer/tile/{z}/{y}/{x}.pbf" );
sources = QgsVectorTileUtils::parseStyleSourceUrl( "file://" + dataDir + "/vector_tile/styles/style2.json" );
QCOMPARE( sources.count(), 2 );

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"currentVersion":10.81,"name":"OpenStreetMap_v2","copyrightText":"Map data (c) OpenStreetMap contributors, Microsoft, Facebook, Google, Esri Community Maps contributors, Map layer by Esri","capabilities":"TilesOnly,Tilemap","type":"indexedVector","tileMap":"tilemap","defaultStyles":"resources/styles","tiles":["tile/{z}/{y}/{x}.pbf"],"exportTilesAllowed":true,"initialExtent":{"xmin":-2.0037508342787E7,"ymin":-2.0037508342787E7,"xmax":2.0037508342787E7,"ymax":2.0037508342787E7,"spatialReference":{"wkid":102100,"latestWkid":3857}},"fullExtent":{"xmin":-2.0037508342787E7,"ymin":-2.0037508342787E7,"xmax":2.0037508342787E7,"ymax":2.0037508342787E7,"spatialReference":{"wkid":102100,"latestWkid":3857}},"minScale":0.0,"maxScale":0.0,"tileInfo":{"rows":512,"cols":512,"dpi":96,"format":"pbf","origin":{"x":-2.0037508342787E7,"y":2.0037508342787E7},"spatialReference":{"wkid":102100,"latestWkid":3857},"lods":[{"level":0,"resolution":78271.516964,"scale":2.958287637957775E8},{"level":1,"resolution":39135.75848199995,"scale":1.479143818978885E8},{"level":2,"resolution":19567.87924100005,"scale":7.39571909489445E7},{"level":3,"resolution":9783.93962049995,"scale":3.6978595474472E7},{"level":4,"resolution":4891.96981024998,"scale":1.8489297737236E7},{"level":5,"resolution":2445.98490512499,"scale":9244648.868618},{"level":6,"resolution":1222.992452562495,"scale":4622324.434309},{"level":7,"resolution":611.496226281245,"scale":2311162.2171545},{"level":8,"resolution":305.74811314069,"scale":1155581.1085775},{"level":9,"resolution":152.874056570279,"scale":577790.5542885},{"level":10,"resolution":76.4370282852055,"scale":288895.2771445},{"level":11,"resolution":38.2185141425366,"scale":144447.638572},{"level":12,"resolution":19.1092570712683,"scale":72223.819286},{"level":13,"resolution":9.55462853563415,"scale":36111.909643},{"level":14,"resolution":4.777314267817075,"scale":18055.9548215},{"level":15,"resolution":2.388657133974685,"scale":9027.977411},{"level":16,"resolution":1.19432856698734,"scale":4513.9887055},{"level":17,"resolution":0.597164283427525,"scale":2256.9943525},{"level":18,"resolution":0.2985821417799085,"scale":1128.4971765},{"level":19,"resolution":0.1492910708238085,"scale":564.248588},{"level":20,"resolution":0.07464553541190416,"scale":282.124294},{"level":21,"resolution":0.03732276770595208,"scale":141.062147},{"level":22,"resolution":0.01866138385297604,"scale":70.5310735}]},"maxzoom":22,"minLOD":0,"maxLOD":16,"resourceInfo":{"styleVersion":8,"tileCompression":"gzip","cacheInfo":{"storageInfo":{"packetSize":128,"storageFormat":"compactV2"}}},"serviceItemId":"51a7da19068641f5a9cabb140a486b34","maxExportTilesCount":25000}