mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-28 00:17:30 -05:00
Fix calculation of zoom level for vector tiles
Previously the code was calculating the exact zoom level (a double value) and then rounding this to an integer in order to determine which rules should be applied. This appears to violate the vector tile styling specifications, which are designed to "round down" the zoom level, so that styling rules like: - layer zoom range: 12-22 - interpolated expression: case when @zoom_level > 12 and @zoom_level <= 14 then 1 when @zoom_level > 14 and @zoom_level < 18 then 2 when @zoom_level >=18 then 4 end work correctly when the exact zoom level is just less than 12, e.g. 11.8 So now we use floor when converting a zoom level to int so that the styling rules work correctly. Additionally, this adds a new @vector_tile_zoom expression variable which contains the original double value of the calculated tile zoom (not the integer one used for layer visibility). Many mapbox GL styling rules rely on non-integer zoom levels for interpolation, e.g. Case when @vector_tile_zoom >= 11.2 then 4 ... This change allows for smooth interpolation between zoom levels which matches the web map appearance, instead of "jumpy" fixed level interpolation we previously had.
This commit is contained in:
parent
079f340e99
commit
f1c0fe259f
@ -790,6 +790,7 @@ void QgsExpression::initVariableHelp()
|
||||
|
||||
// vector tile layer variables
|
||||
sVariableHelpTexts()->insert( QStringLiteral( "zoom_level" ), QCoreApplication::translate( "variable_help", "Zoom level of the tile that is being rendered (derived from the current map scale). Normally in interval [0, 20]." ) );
|
||||
sVariableHelpTexts()->insert( QStringLiteral( "vector_tile_zoom" ), QCoreApplication::translate( "variable_help", "Exact zoom level of the tile that is being rendered (derived from the current map scale). Normally in interval [0, 20]. Unlike @zoom_level, this variable is a floating point value which can be used to interpolated values between two integer zoom levels." ) );
|
||||
|
||||
sVariableHelpTexts()->insert( QStringLiteral( "row_number" ), QCoreApplication::translate( "variable_help", "Stores the number of the current row." ) );
|
||||
sVariableHelpTexts()->insert( QStringLiteral( "grid_number" ), QCoreApplication::translate( "variable_help", "Current grid annotation value." ) );
|
||||
|
@ -820,11 +820,11 @@ void QgsMapBoxGlStyleConverter::parseSymbolLayer( const QVariantMap &jsonLayer,
|
||||
|
||||
if ( splitFontFamily( bv, fontFamily, fontStyle ) )
|
||||
{
|
||||
familyCaseString += QStringLiteral( "WHEN @zoom_level > %1 AND @zoom_level <= %2 "
|
||||
familyCaseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 AND @vector_tile_zoom <= %2 "
|
||||
"THEN %3 " ).arg( bz.toString(),
|
||||
tz.toString(),
|
||||
QgsExpression::quotedValue( fontFamily ) );
|
||||
styleCaseString += QStringLiteral( "WHEN @zoom_level > %1 AND @zoom_level <= %2 "
|
||||
styleCaseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 AND @vector_tile_zoom <= %2 "
|
||||
"THEN %3 " ).arg( bz.toString(),
|
||||
tz.toString(),
|
||||
QgsExpression::quotedValue( fontStyle ) );
|
||||
@ -1763,7 +1763,7 @@ QgsProperty QgsMapBoxGlStyleConverter::parseInterpolateColorByZoom( const QVaria
|
||||
int tcAlpha;
|
||||
colorAsHslaComponents( topColor, tcHue, tcSat, tcLight, tcAlpha );
|
||||
|
||||
caseString += QStringLiteral( "WHEN @zoom_level >= %1 AND @zoom_level < %2 THEN color_hsla("
|
||||
caseString += QStringLiteral( "WHEN @vector_tile_zoom >= %1 AND @vector_tile_zoom < %2 THEN color_hsla("
|
||||
"%3, %4, %5, %6) " ).arg( bz, tz,
|
||||
interpolateExpression( bz.toDouble(), tz.toDouble(), bcHue, tcHue, base ),
|
||||
interpolateExpression( bz.toDouble(), tz.toDouble(), bcSat, tcSat, base ),
|
||||
@ -1780,7 +1780,7 @@ QgsProperty QgsMapBoxGlStyleConverter::parseInterpolateColorByZoom( const QVaria
|
||||
int tcAlpha;
|
||||
colorAsHslaComponents( topColor, tcHue, tcSat, tcLight, tcAlpha );
|
||||
|
||||
caseString += QStringLiteral( "WHEN @zoom_level >= %1 THEN color_hsla(%2, %3, %4, %5) "
|
||||
caseString += QStringLiteral( "WHEN @vector_tile_zoom >= %1 THEN color_hsla(%2, %3, %4, %5) "
|
||||
"ELSE color_hsla(%2, %3, %4, %5) END" ).arg( tz )
|
||||
.arg( tcHue ).arg( tcSat ).arg( tcLight ).arg( tcAlpha );
|
||||
|
||||
@ -1842,13 +1842,13 @@ QgsProperty QgsMapBoxGlStyleConverter::parseInterpolateOpacityByZoom( const QVar
|
||||
|
||||
QString QgsMapBoxGlStyleConverter::parseOpacityStops( double base, const QVariantList &stops, int maxOpacity )
|
||||
{
|
||||
QString caseString = QStringLiteral( "CASE WHEN @zoom_level < %1 THEN set_color_part(@symbol_color, 'alpha', %2)" )
|
||||
QString caseString = QStringLiteral( "CASE WHEN @vector_tile_zoom < %1 THEN set_color_part(@symbol_color, 'alpha', %2)" )
|
||||
.arg( stops.value( 0 ).toList().value( 0 ).toString() )
|
||||
.arg( stops.value( 0 ).toList().value( 1 ).toDouble() * maxOpacity );
|
||||
|
||||
for ( int i = 0; i < stops.size() - 1; ++i )
|
||||
{
|
||||
caseString += QStringLiteral( " WHEN @zoom_level >= %1 AND @zoom_level < %2 "
|
||||
caseString += QStringLiteral( " WHEN @vector_tile_zoom >= %1 AND @vector_tile_zoom < %2 "
|
||||
"THEN set_color_part(@symbol_color, 'alpha', %3)" )
|
||||
.arg( stops.value( i ).toList().value( 0 ).toString(),
|
||||
stops.value( i + 1 ).toList().value( 0 ).toString(),
|
||||
@ -1858,7 +1858,7 @@ QString QgsMapBoxGlStyleConverter::parseOpacityStops( double base, const QVarian
|
||||
stops.value( i + 1 ).toList().value( 1 ).toDouble() * maxOpacity, base ) );
|
||||
}
|
||||
|
||||
caseString += QStringLiteral( " WHEN @zoom_level >= %1 "
|
||||
caseString += QStringLiteral( " WHEN @vector_tile_zoom >= %1 "
|
||||
"THEN set_color_part(@symbol_color, 'alpha', %2) END" )
|
||||
.arg( stops.last().toList().value( 0 ).toString() )
|
||||
.arg( stops.last().toList().value( 1 ).toDouble() * maxOpacity );
|
||||
@ -1933,8 +1933,8 @@ QString QgsMapBoxGlStyleConverter::parsePointStops( double base, const QVariantL
|
||||
return QString();
|
||||
}
|
||||
|
||||
caseString += QStringLiteral( "WHEN @zoom_level > %1 AND @zoom_level <= %2 "
|
||||
"THEN array(%3,%4) " ).arg( bz.toString(),
|
||||
caseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 AND @vector_tile_zoom <= %2 "
|
||||
"THEN array(%3,%4)" ).arg( bz.toString(),
|
||||
tz.toString(),
|
||||
interpolateExpression( bz.toDouble(), tz.toDouble(), bv.toList().value( 0 ).toDouble(), tv.toList().value( 0 ).toDouble(), base, multiplier ),
|
||||
interpolateExpression( bz.toDouble(), tz.toDouble(), bv.toList().value( 1 ).toDouble(), tv.toList().value( 1 ).toDouble(), base, multiplier ) );
|
||||
@ -1967,7 +1967,7 @@ QString QgsMapBoxGlStyleConverter::parseStops( double base, const QVariantList &
|
||||
return QString();
|
||||
}
|
||||
|
||||
caseString += QStringLiteral( "WHEN @zoom_level > %1 AND @zoom_level <= %2 "
|
||||
caseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 AND @vector_tile_zoom <= %2 "
|
||||
"THEN %3 " ).arg( bz.toString(),
|
||||
tz.toString(),
|
||||
interpolateExpression( bz.toDouble(), tz.toDouble(), bv.toDouble(), tv.toDouble(), base, multiplier ) );
|
||||
@ -1975,7 +1975,7 @@ QString QgsMapBoxGlStyleConverter::parseStops( double base, const QVariantList &
|
||||
|
||||
const QVariant z = stops.last().toList().value( 0 );
|
||||
const QVariant v = stops.last().toList().value( 1 );
|
||||
caseString += QStringLiteral( "WHEN @zoom_level > %1 "
|
||||
caseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 "
|
||||
"THEN %2 END" ).arg( z.toString() ).arg( v.toDouble() * multiplier );
|
||||
return caseString;
|
||||
}
|
||||
@ -2003,7 +2003,7 @@ QString QgsMapBoxGlStyleConverter::parseStringStops( const QVariantList &stops,
|
||||
return QString();
|
||||
}
|
||||
|
||||
caseString += QStringLiteral( "WHEN @zoom_level > %1 AND @zoom_level <= %2 "
|
||||
caseString += QStringLiteral( "WHEN @vector_tile_zoom > %1 AND @vector_tile_zoom <= %2 "
|
||||
"THEN %3 " ).arg( bz.toString(),
|
||||
tz.toString(),
|
||||
QgsExpression::quotedValue( conversionMap.value( bv, bv ) ) );
|
||||
@ -2224,14 +2224,14 @@ QString QgsMapBoxGlStyleConverter::interpolateExpression( double zoomMin, double
|
||||
QString expression;
|
||||
if ( base == 1 )
|
||||
{
|
||||
expression = QStringLiteral( "scale_linear(@zoom_level,%1,%2,%3,%4)" ).arg( zoomMin )
|
||||
expression = QStringLiteral( "scale_linear(@vector_tile_zoom,%1,%2,%3,%4)" ).arg( zoomMin )
|
||||
.arg( zoomMax )
|
||||
.arg( valueMin )
|
||||
.arg( valueMax );
|
||||
}
|
||||
else
|
||||
{
|
||||
expression = QStringLiteral( "scale_exp(@zoom_level,%1,%2,%3,%4,%5)" ).arg( zoomMin )
|
||||
expression = QStringLiteral( "scale_exp(@vector_tile_zoom,%1,%2,%3,%4,%5)" ).arg( zoomMin )
|
||||
.arg( zoomMax )
|
||||
.arg( valueMin )
|
||||
.arg( valueMax )
|
||||
@ -2539,10 +2539,10 @@ QString QgsMapBoxGlStyleConverter::retrieveSpriteAsBase64( const QVariant &value
|
||||
sprite = retrieveSprite( stops.value( 0 ).toList().value( 1 ).toString(), context, spriteSize );
|
||||
spritePath = prepareBase64( sprite );
|
||||
|
||||
spriteProperty = QStringLiteral( "CASE WHEN @zoom_level < %1 THEN '%2'" )
|
||||
spriteProperty = QStringLiteral( "CASE WHEN @vector_tile_zoom < %1 THEN '%2'" )
|
||||
.arg( stops.value( 0 ).toList().value( 0 ).toString() )
|
||||
.arg( spritePath );
|
||||
spriteSizeProperty = QStringLiteral( "CASE WHEN @zoom_level < %1 THEN %2" )
|
||||
spriteSizeProperty = QStringLiteral( "CASE WHEN @vector_tile_zoom < %1 THEN %2" )
|
||||
.arg( stops.value( 0 ).toList().value( 0 ).toString() )
|
||||
.arg( spriteSize.width() );
|
||||
|
||||
@ -2552,12 +2552,12 @@ QString QgsMapBoxGlStyleConverter::retrieveSpriteAsBase64( const QVariant &value
|
||||
sprite = retrieveSprite( stops.value( 0 ).toList().value( 1 ).toString(), context, size );
|
||||
path = prepareBase64( sprite );
|
||||
|
||||
spriteProperty += QStringLiteral( " WHEN @zoom_level >= %1 AND @zoom_level < %2 "
|
||||
spriteProperty += QStringLiteral( " WHEN @vector_tile_zoom >= %1 AND @vector_tile_zoom < %2 "
|
||||
"THEN '%3'" )
|
||||
.arg( stops.value( i ).toList().value( 0 ).toString(),
|
||||
stops.value( i + 1 ).toList().value( 0 ).toString(),
|
||||
path );
|
||||
spriteSizeProperty += QStringLiteral( " WHEN @zoom_level >= %1 AND @zoom_level < %2 "
|
||||
spriteSizeProperty += QStringLiteral( " WHEN @vector_tile_zoom >= %1 AND @vector_tile_zoom < %2 "
|
||||
"THEN %3" )
|
||||
.arg( stops.value( i ).toList().value( 0 ).toString(),
|
||||
stops.value( i + 1 ).toList().value( 0 ).toString() )
|
||||
@ -2566,11 +2566,11 @@ QString QgsMapBoxGlStyleConverter::retrieveSpriteAsBase64( const QVariant &value
|
||||
sprite = retrieveSprite( stops.last().toList().value( 1 ).toString(), context, size );
|
||||
path = prepareBase64( sprite );
|
||||
|
||||
spriteProperty += QStringLiteral( " WHEN @zoom_level >= %1 "
|
||||
spriteProperty += QStringLiteral( " WHEN @vector_tile_zoom >= %1 "
|
||||
"THEN '%2' END" )
|
||||
.arg( stops.last().toList().value( 0 ).toString() )
|
||||
.arg( path );
|
||||
spriteSizeProperty += QStringLiteral( " WHEN @zoom_level >= %1 "
|
||||
spriteSizeProperty += QStringLiteral( " WHEN @vector_tile_zoom >= %1 "
|
||||
"THEN %2 END" )
|
||||
.arg( stops.last().toList().value( 0 ).toString() )
|
||||
.arg( size.width() );
|
||||
|
@ -132,6 +132,7 @@ bool QgsVectorTileLayerRenderer::render()
|
||||
// add @zoom_level variable which can be used in styling
|
||||
QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Tiles" ) ); // will be deleted by popper
|
||||
scope->setVariable( "zoom_level", mTileZoom, true );
|
||||
scope->setVariable( "vector_tile_zoom", QgsVectorTileUtils::scaleToZoom( ctx.rendererScale() ), true );
|
||||
QgsExpressionContextScopePopper popper( ctx.expressionContext(), scope );
|
||||
|
||||
mRenderer->startRender( *renderContext(), mTileZoom, mTileRange );
|
||||
|
@ -60,13 +60,17 @@ QgsFields QgsVectorTileUtils::makeQgisFields( QSet<QString> flds )
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom )
|
||||
double QgsVectorTileUtils::scaleToZoom( double mapScale )
|
||||
{
|
||||
double s0 = 559082264.0287178; // scale denominator at zoom level 0 of GoogleCRS84Quad
|
||||
double tileZoom2 = log( s0 / mapScale ) / log( 2 );
|
||||
tileZoom2 -= 1; // TODO: it seems that map scale is double (is that because of high-dpi screen?)
|
||||
int tileZoom = static_cast<int>( round( tileZoom2 ) );
|
||||
return tileZoom2;
|
||||
}
|
||||
|
||||
int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom )
|
||||
{
|
||||
int tileZoom = static_cast<int>( floor( scaleToZoom( mapScale ) ) );
|
||||
|
||||
if ( tileZoom < sourceMinZoom )
|
||||
tileZoom = sourceMinZoom;
|
||||
|
@ -55,6 +55,14 @@ class CORE_EXPORT QgsVectorTileUtils
|
||||
static QPolygon tilePolygon( QgsTileXYZ id, const QgsCoordinateTransform &ct, const QgsTileMatrix &tm, const QgsMapToPixel &mtp );
|
||||
//! Returns QgsFields instance based on the set of field names
|
||||
static QgsFields makeQgisFields( QSet<QString> flds );
|
||||
|
||||
/**
|
||||
* Finds zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator.
|
||||
*
|
||||
* \since QGIS 3.16
|
||||
*/
|
||||
static double scaleToZoom( double mapScale );
|
||||
|
||||
//! Finds best fitting zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator and allowed zoom level range
|
||||
static int scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom );
|
||||
//! Returns a temporary vector layer for given sub-layer of tile in vector tile layer
|
||||
|
@ -105,6 +105,10 @@ QgsExpressionContext QgsSymbolLayerWidget::createExpressionContext() const
|
||||
{
|
||||
highlights << QStringLiteral( "zoom_level" );
|
||||
}
|
||||
if ( expContext.hasVariable( QStringLiteral( "vector_tile_zoom" ) ) )
|
||||
{
|
||||
highlights << QStringLiteral( "vector_tile_zoom" );
|
||||
}
|
||||
|
||||
expContext.setHighlightedVariables( highlights );
|
||||
|
||||
|
@ -413,6 +413,7 @@ void QgsVectorTileBasicLabelingWidget::editStyleAtIndex( const QModelIndex &prox
|
||||
QList<QgsExpressionContextScope> scopes = context.additionalExpressionContextScopes();
|
||||
QgsExpressionContextScope tileScope;
|
||||
tileScope.setVariable( "zoom_level", zoom, true );
|
||||
tileScope.setVariable( "vector_tile_zoom", QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
|
||||
scopes << tileScope;
|
||||
context.setAdditionalExpressionContextScopes( scopes );
|
||||
}
|
||||
|
@ -416,6 +416,7 @@ void QgsVectorTileBasicRendererWidget::editStyleAtIndex( const QModelIndex &prox
|
||||
QList<QgsExpressionContextScope> scopes = context.additionalExpressionContextScopes();
|
||||
QgsExpressionContextScope tileScope;
|
||||
tileScope.setVariable( "zoom_level", zoom, true );
|
||||
tileScope.setVariable( "vector_tile_zoom", QgsVectorTileUtils::scaleToZoom( mMapCanvas->scale() ), true );
|
||||
scopes << tileScope;
|
||||
context.setAdditionalExpressionContextScopes( scopes );
|
||||
}
|
||||
|
@ -37,11 +37,11 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
|
||||
def testInterpolateExpression(self):
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.interpolateExpression(5, 13, 27, 29, 1),
|
||||
'scale_linear(@zoom_level,5,13,27,29)')
|
||||
'scale_linear(@vector_tile_zoom,5,13,27,29)')
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.interpolateExpression(5, 13, 27, 29, 1.5),
|
||||
'scale_exp(@zoom_level,5,13,27,29,1.5)')
|
||||
'scale_exp(@vector_tile_zoom,5,13,27,29,1.5)')
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.interpolateExpression(5, 13, 27, 29, 1.5),
|
||||
'scale_exp(@zoom_level,5,13,27,29,1.5)')
|
||||
'scale_exp(@vector_tile_zoom,5,13,27,29,1.5)')
|
||||
|
||||
# same values, return nice and simple expression!
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.interpolateExpression(5, 13, 27, 27, 1.5),
|
||||
@ -64,7 +64,7 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
},
|
||||
conversion_context)
|
||||
self.assertEqual(props.expressionString(),
|
||||
'CASE WHEN @zoom_level >= 0 AND @zoom_level < 150 THEN color_hsla(scale_linear(@zoom_level,0,150,59,352), scale_linear(@zoom_level,0,150,81,59), scale_linear(@zoom_level,0,150,70,44), 255) WHEN @zoom_level >= 150 AND @zoom_level < 250 THEN color_hsla(scale_linear(@zoom_level,150,250,352,0), scale_linear(@zoom_level,150,250,59,72), scale_linear(@zoom_level,150,250,44,63), 255) WHEN @zoom_level >= 250 THEN color_hsla(0, 72, 63, 255) ELSE color_hsla(0, 72, 63, 255) END')
|
||||
'CASE WHEN @vector_tile_zoom >= 0 AND @vector_tile_zoom < 150 THEN color_hsla(scale_linear(@vector_tile_zoom,0,150,59,352), scale_linear(@vector_tile_zoom,0,150,81,59), scale_linear(@vector_tile_zoom,0,150,70,44), 255) WHEN @vector_tile_zoom >= 150 AND @vector_tile_zoom < 250 THEN color_hsla(scale_linear(@vector_tile_zoom,150,250,352,0), scale_linear(@vector_tile_zoom,150,250,59,72), scale_linear(@vector_tile_zoom,150,250,44,63), 255) WHEN @vector_tile_zoom >= 250 THEN color_hsla(0, 72, 63, 255) ELSE color_hsla(0, 72, 63, 255) END')
|
||||
self.assertEqual(default_col.name(), '#f1f075')
|
||||
props, default_col = QgsMapBoxGlStyleConverter.parseInterpolateColorByZoom({'base': 2,
|
||||
'stops': [[0, '#f1f075'],
|
||||
@ -73,19 +73,19 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
},
|
||||
conversion_context)
|
||||
self.assertEqual(props.expressionString(),
|
||||
'CASE WHEN @zoom_level >= 0 AND @zoom_level < 150 THEN color_hsla(scale_exp(@zoom_level,0,150,59,352,2), scale_exp(@zoom_level,0,150,81,59,2), scale_exp(@zoom_level,0,150,70,44,2), 255) WHEN @zoom_level >= 150 AND @zoom_level < 250 THEN color_hsla(scale_exp(@zoom_level,150,250,352,0,2), scale_exp(@zoom_level,150,250,59,72,2), scale_exp(@zoom_level,150,250,44,63,2), 255) WHEN @zoom_level >= 250 THEN color_hsla(0, 72, 63, 255) ELSE color_hsla(0, 72, 63, 255) END')
|
||||
'CASE WHEN @vector_tile_zoom >= 0 AND @vector_tile_zoom < 150 THEN color_hsla(scale_exp(@vector_tile_zoom,0,150,59,352,2), scale_exp(@vector_tile_zoom,0,150,81,59,2), scale_exp(@vector_tile_zoom,0,150,70,44,2), 255) WHEN @vector_tile_zoom >= 150 AND @vector_tile_zoom < 250 THEN color_hsla(scale_exp(@vector_tile_zoom,150,250,352,0,2), scale_exp(@vector_tile_zoom,150,250,59,72,2), scale_exp(@vector_tile_zoom,150,250,44,63,2), 255) WHEN @vector_tile_zoom >= 250 THEN color_hsla(0, 72, 63, 255) ELSE color_hsla(0, 72, 63, 255) END')
|
||||
self.assertEqual(default_col.name(), '#f1f075')
|
||||
|
||||
def testParseStops(self):
|
||||
conversion_context = QgsMapBoxGlStyleConversionContext()
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseStops(1, [[1, 10], [2, 20], [5, 100]], 1, conversion_context),
|
||||
'CASE WHEN @zoom_level > 1 AND @zoom_level <= 2 THEN scale_linear(@zoom_level,1,2,10,20) WHEN @zoom_level > 2 AND @zoom_level <= 5 THEN scale_linear(@zoom_level,2,5,20,100) WHEN @zoom_level > 5 THEN 100 END')
|
||||
'CASE WHEN @vector_tile_zoom > 1 AND @vector_tile_zoom <= 2 THEN scale_linear(@vector_tile_zoom,1,2,10,20) WHEN @vector_tile_zoom > 2 AND @vector_tile_zoom <= 5 THEN scale_linear(@vector_tile_zoom,2,5,20,100) WHEN @vector_tile_zoom > 5 THEN 100 END')
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseStops(1.5, [[1, 10], [2, 20], [5, 100]], 1, conversion_context),
|
||||
'CASE WHEN @zoom_level > 1 AND @zoom_level <= 2 THEN scale_exp(@zoom_level,1,2,10,20,1.5) WHEN @zoom_level > 2 AND @zoom_level <= 5 THEN scale_exp(@zoom_level,2,5,20,100,1.5) WHEN @zoom_level > 5 THEN 100 END')
|
||||
'CASE WHEN @vector_tile_zoom > 1 AND @vector_tile_zoom <= 2 THEN scale_exp(@vector_tile_zoom,1,2,10,20,1.5) WHEN @vector_tile_zoom > 2 AND @vector_tile_zoom <= 5 THEN scale_exp(@vector_tile_zoom,2,5,20,100,1.5) WHEN @vector_tile_zoom > 5 THEN 100 END')
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseStops(1, [[1, 10], [2, 20], [5, 100]], 8, conversion_context),
|
||||
'CASE WHEN @zoom_level > 1 AND @zoom_level <= 2 THEN scale_linear(@zoom_level,1,2,10,20) * 8 WHEN @zoom_level > 2 AND @zoom_level <= 5 THEN scale_linear(@zoom_level,2,5,20,100) * 8 WHEN @zoom_level > 5 THEN 800 END')
|
||||
'CASE WHEN @vector_tile_zoom > 1 AND @vector_tile_zoom <= 2 THEN scale_linear(@vector_tile_zoom,1,2,10,20) * 8 WHEN @vector_tile_zoom > 2 AND @vector_tile_zoom <= 5 THEN scale_linear(@vector_tile_zoom,2,5,20,100) * 8 WHEN @vector_tile_zoom > 5 THEN 800 END')
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseStops(1.5, [[1, 10], [2, 20], [5, 100]], 8, conversion_context),
|
||||
'CASE WHEN @zoom_level > 1 AND @zoom_level <= 2 THEN scale_exp(@zoom_level,1,2,10,20,1.5) * 8 WHEN @zoom_level > 2 AND @zoom_level <= 5 THEN scale_exp(@zoom_level,2,5,20,100,1.5) * 8 WHEN @zoom_level > 5 THEN 800 END')
|
||||
'CASE WHEN @vector_tile_zoom > 1 AND @vector_tile_zoom <= 2 THEN scale_exp(@vector_tile_zoom,1,2,10,20,1.5) * 8 WHEN @vector_tile_zoom > 2 AND @vector_tile_zoom <= 5 THEN scale_exp(@vector_tile_zoom,2,5,20,100,1.5) * 8 WHEN @vector_tile_zoom > 5 THEN 800 END')
|
||||
|
||||
def testParseMatchList(self):
|
||||
conversion_context = QgsMapBoxGlStyleConversionContext()
|
||||
@ -154,7 +154,7 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
0.6
|
||||
], QgsMapBoxGlStyleConverter.Numeric, conversion_context, 2.5, 200)
|
||||
self.assertEqual(res.asExpression(),
|
||||
'CASE WHEN @zoom_level > 10 AND @zoom_level <= 15 THEN scale_linear(@zoom_level,10,15,0.1,0.3) * 2.5 WHEN @zoom_level > 15 AND @zoom_level <= 18 THEN scale_linear(@zoom_level,15,18,0.3,0.6) * 2.5 WHEN @zoom_level > 18 THEN 1.5 END')
|
||||
'CASE WHEN @vector_tile_zoom > 10 AND @vector_tile_zoom <= 15 THEN scale_linear(@vector_tile_zoom,10,15,0.1,0.3) * 2.5 WHEN @vector_tile_zoom > 15 AND @vector_tile_zoom <= 18 THEN scale_linear(@vector_tile_zoom,15,18,0.3,0.6) * 2.5 WHEN @vector_tile_zoom > 18 THEN 1.5 END')
|
||||
self.assertEqual(default_number, 0.25)
|
||||
|
||||
def testInterpolateByZoom(self):
|
||||
@ -165,21 +165,21 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
[250, 22]]
|
||||
}, conversion_context)
|
||||
self.assertEqual(prop.expressionString(),
|
||||
'CASE WHEN @zoom_level > 0 AND @zoom_level <= 150 THEN scale_linear(@zoom_level,0,150,11,15) WHEN @zoom_level > 150 AND @zoom_level <= 250 THEN scale_linear(@zoom_level,150,250,15,22) WHEN @zoom_level > 250 THEN 22 END')
|
||||
'CASE WHEN @vector_tile_zoom > 0 AND @vector_tile_zoom <= 150 THEN scale_linear(@vector_tile_zoom,0,150,11,15) WHEN @vector_tile_zoom > 150 AND @vector_tile_zoom <= 250 THEN scale_linear(@vector_tile_zoom,150,250,15,22) WHEN @vector_tile_zoom > 250 THEN 22 END')
|
||||
self.assertEqual(default_val, 11.0)
|
||||
prop, default_val = QgsMapBoxGlStyleConverter.parseInterpolateByZoom({'base': 1,
|
||||
'stops': [[0, 11],
|
||||
[150, 15]]
|
||||
}, conversion_context)
|
||||
self.assertEqual(prop.expressionString(),
|
||||
'scale_linear(@zoom_level,0,150,11,15)')
|
||||
'scale_linear(@vector_tile_zoom,0,150,11,15)')
|
||||
self.assertEqual(default_val, 11.0)
|
||||
prop, default_val = QgsMapBoxGlStyleConverter.parseInterpolateByZoom({'base': 2,
|
||||
'stops': [[0, 11],
|
||||
[150, 15]]
|
||||
}, conversion_context)
|
||||
self.assertEqual(prop.expressionString(),
|
||||
'scale_exp(@zoom_level,0,150,11,15,2)')
|
||||
'scale_exp(@vector_tile_zoom,0,150,11,15,2)')
|
||||
self.assertEqual(default_val, 11.0)
|
||||
|
||||
prop, default_val = QgsMapBoxGlStyleConverter.parseInterpolateByZoom({'base': 2,
|
||||
@ -187,7 +187,7 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
[150, 15]]
|
||||
}, conversion_context, multiplier=5)
|
||||
self.assertEqual(prop.expressionString(),
|
||||
'scale_exp(@zoom_level,0,150,11,15,2) * 5')
|
||||
'scale_exp(@vector_tile_zoom,0,150,11,15,2) * 5')
|
||||
self.assertEqual(default_val, 55.0)
|
||||
|
||||
def testInterpolateOpacityByZoom(self):
|
||||
@ -196,23 +196,23 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
[150, 0.15],
|
||||
[250, 0.2]]
|
||||
}, 255).expressionString(),
|
||||
"CASE WHEN @zoom_level < 0 THEN set_color_part(@symbol_color, 'alpha', 25.5) WHEN @zoom_level >= 0 AND @zoom_level < 150 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,0,150,25.5,38.25)) WHEN @zoom_level >= 150 AND @zoom_level < 250 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,150,250,38.25,51)) WHEN @zoom_level >= 250 THEN set_color_part(@symbol_color, 'alpha', 51) END")
|
||||
"CASE WHEN @vector_tile_zoom < 0 THEN set_color_part(@symbol_color, 'alpha', 25.5) WHEN @vector_tile_zoom >= 0 AND @vector_tile_zoom < 150 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,0,150,25.5,38.25)) WHEN @vector_tile_zoom >= 150 AND @vector_tile_zoom < 250 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,150,250,38.25,51)) WHEN @vector_tile_zoom >= 250 THEN set_color_part(@symbol_color, 'alpha', 51) END")
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseInterpolateOpacityByZoom({'base': 1,
|
||||
'stops': [[0, 0.1],
|
||||
[150, 0.15],
|
||||
[250, 0.2]]
|
||||
}, 100).expressionString(),
|
||||
"CASE WHEN @zoom_level < 0 THEN set_color_part(@symbol_color, 'alpha', 10) WHEN @zoom_level >= 0 AND @zoom_level < 150 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,0,150,10,15)) WHEN @zoom_level >= 150 AND @zoom_level < 250 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,150,250,15,20)) WHEN @zoom_level >= 250 THEN set_color_part(@symbol_color, 'alpha', 20) END")
|
||||
"CASE WHEN @vector_tile_zoom < 0 THEN set_color_part(@symbol_color, 'alpha', 10) WHEN @vector_tile_zoom >= 0 AND @vector_tile_zoom < 150 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,0,150,10,15)) WHEN @vector_tile_zoom >= 150 AND @vector_tile_zoom < 250 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,150,250,15,20)) WHEN @vector_tile_zoom >= 250 THEN set_color_part(@symbol_color, 'alpha', 20) END")
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseInterpolateOpacityByZoom({'base': 1,
|
||||
'stops': [[0, 0.1],
|
||||
[150, 0.15]]
|
||||
}, 255).expressionString(),
|
||||
"set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,0,150,25.5,38.25))")
|
||||
"set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,0,150,25.5,38.25))")
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseInterpolateOpacityByZoom({'base': 2,
|
||||
'stops': [[0, 0.1],
|
||||
[150, 0.15]]
|
||||
}, 255).expressionString(),
|
||||
"set_color_part(@symbol_color, 'alpha', scale_exp(@zoom_level,0,150,25.5,38.25,2))")
|
||||
"set_color_part(@symbol_color, 'alpha', scale_exp(@vector_tile_zoom,0,150,25.5,38.25,2))")
|
||||
self.assertEqual(QgsMapBoxGlStyleConverter.parseInterpolateOpacityByZoom({'base': 2,
|
||||
'stops': [[0, 0.1],
|
||||
[150, 0.1]]
|
||||
@ -233,7 +233,7 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
0.6
|
||||
], QgsMapBoxGlStyleConverter.Opacity, conversion_context, 2)
|
||||
self.assertEqual(prop.expressionString(),
|
||||
"CASE WHEN @zoom_level < 10 THEN set_color_part(@symbol_color, 'alpha', 25.5) WHEN @zoom_level >= 10 AND @zoom_level < 15 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,10,15,25.5,76.5)) WHEN @zoom_level >= 15 AND @zoom_level < 18 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@zoom_level,15,18,76.5,153)) WHEN @zoom_level >= 18 THEN set_color_part(@symbol_color, 'alpha', 153) END")
|
||||
"CASE WHEN @vector_tile_zoom < 10 THEN set_color_part(@symbol_color, 'alpha', 25.5) WHEN @vector_tile_zoom >= 10 AND @vector_tile_zoom < 15 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,10,15,25.5,76.5)) WHEN @vector_tile_zoom >= 15 AND @vector_tile_zoom < 18 THEN set_color_part(@symbol_color, 'alpha', scale_linear(@vector_tile_zoom,15,18,76.5,153)) WHEN @vector_tile_zoom >= 18 THEN set_color_part(@symbol_color, 'alpha', 153) END")
|
||||
|
||||
prop, default_color, default_val = QgsMapBoxGlStyleConverter.parseInterpolateListByZoom([
|
||||
"interpolate",
|
||||
@ -247,7 +247,7 @@ class TestQgsMapBoxGlStyleConverter(unittest.TestCase):
|
||||
0.6
|
||||
], QgsMapBoxGlStyleConverter.Numeric, conversion_context, 2)
|
||||
self.assertEqual(prop.expressionString(),
|
||||
"CASE WHEN @zoom_level > 10 AND @zoom_level <= 15 THEN scale_linear(@zoom_level,10,15,0.1,0.3) * 2 WHEN @zoom_level > 15 AND @zoom_level <= 18 THEN scale_linear(@zoom_level,15,18,0.3,0.6) * 2 WHEN @zoom_level > 18 THEN 1.2 END")
|
||||
"CASE WHEN @vector_tile_zoom > 10 AND @vector_tile_zoom <= 15 THEN scale_linear(@vector_tile_zoom,10,15,0.1,0.3) * 2 WHEN @vector_tile_zoom > 15 AND @vector_tile_zoom <= 18 THEN scale_linear(@vector_tile_zoom,15,18,0.3,0.6) * 2 WHEN @vector_tile_zoom > 18 THEN 1.2 END")
|
||||
self.assertEqual(default_val, 0.2)
|
||||
|
||||
def testParseExpression(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user