Skip to content
Permalink
Browse files

[vectortiles] Be tolerant, and allow rendering polygon features

using a line style

Some services use line styles for polygon symbology in order to
specify that the polygons should be rendered using their outlines
in a line style
  • Loading branch information
nyalldawson committed Aug 31, 2020
1 parent fc01144 commit 4cd40ab59264da09e8edcdcd43b60c7e44158e43
@@ -24,7 +24,6 @@
#include "qgssymbollayerutils.h"
#include "qgsvectortileutils.h"


QgsVectorTileBasicRendererStyle::QgsVectorTileBasicRendererStyle( const QString &stName, const QString &laName, QgsWkbTypes::GeometryType geomType )
: mStyleName( stName )
, mLayerName( laName )
@@ -171,8 +170,19 @@ void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &ti
if ( filterExpression.isValid() && !filterExpression.evaluate( &context.expressionContext() ).toBool() )
continue;

if ( QgsWkbTypes::geometryType( f.geometry().wkbType() ) == layerStyle.geometryType() )
const QgsWkbTypes::GeometryType featureType = QgsWkbTypes::geometryType( f.geometry().wkbType() );
if ( featureType == layerStyle.geometryType() )
{
sym->renderFeature( f, context );
}
else if ( featureType == QgsWkbTypes::PolygonGeometry && layerStyle.geometryType() == QgsWkbTypes::LineGeometry )
{
// be tolerant and permit rendering polygons with a line layer style, as some style definitions use this approach
// to render the polygon borders only
QgsFeature exterior = f;
exterior.setGeometry( QgsGeometry( f.geometry().constGet()->boundary() ) );
sym->renderFeature( exterior, context );
}
}
}
}
@@ -185,8 +195,19 @@ void QgsVectorTileBasicRenderer::renderTile( const QgsVectorTileRendererData &ti
if ( filterExpression.isValid() && !filterExpression.evaluate( &context.expressionContext() ).toBool() )
continue;

if ( QgsWkbTypes::geometryType( f.geometry().wkbType() ) == layerStyle.geometryType() )
const QgsWkbTypes::GeometryType featureType = QgsWkbTypes::geometryType( f.geometry().wkbType() );
if ( featureType == layerStyle.geometryType() )
{
sym->renderFeature( f, context );
}
else if ( featureType == QgsWkbTypes::PolygonGeometry && layerStyle.geometryType() == QgsWkbTypes::LineGeometry )
{
// be tolerant and permit rendering polygons with a line layer style, as some style definitions use this approach
// to render the polygon borders only
QgsFeature exterior = f;
exterior.setGeometry( QgsGeometry( f.geometry().constGet()->boundary() ) );
sym->renderFeature( exterior, context );
}
}
}
sym->stopRender( context );
@@ -26,6 +26,7 @@
#include "qgsvectortilelayer.h"
#include "qgsvectortilebasiclabeling.h"
#include "qgsfontutils.h"
#include "qgslinesymbollayer.h"

/**
* \ingroup UnitTests
@@ -57,6 +58,7 @@ class TestQgsVectorTileLayer : public QObject
void test_render_withClip();
void test_labeling();
void test_relativePaths();
void test_polygonWithLineStyle();
};


@@ -242,6 +244,36 @@ void TestQgsVectorTileLayer::test_relativePaths()
QCOMPARE( layer.decodedSource( srcMbtiles, QString(), contextAbs ), srcMbtiles );
}

void TestQgsVectorTileLayer::test_polygonWithLineStyle()
{
QgsDataSourceUri ds;
ds.setParam( "type", "xyz" );
ds.setParam( "url", QString( "file://%1/{z}-{x}-{y}.pbf" ).arg( mDataDir ) );
ds.setParam( "zmax", "1" );
std::unique_ptr< QgsVectorTileLayer > layer = qgis::make_unique< QgsVectorTileLayer >( ds.encodedUri(), "Vector Tiles Test" );
QVERIFY( layer->isValid() );

mMapSettings->setLayers( QList<QgsMapLayer *>() << layer.get() );

QColor lineStrokeColor = Qt::blue;
double lineStrokeWidth = DEFAULT_LINE_WIDTH * 2;

QgsVectorTileBasicRenderer *rend = new QgsVectorTileBasicRenderer;

QgsSimpleLineSymbolLayer *lineSymbolLayer = new QgsSimpleLineSymbolLayer;
lineSymbolLayer->setColor( lineStrokeColor );
lineSymbolLayer->setWidth( lineStrokeWidth );
QgsLineSymbol *lineSymbol = new QgsLineSymbol( QgsSymbolLayerList() << lineSymbolLayer );

QgsVectorTileBasicRendererStyle st( QStringLiteral( "Polygons" ), QString(), QgsWkbTypes::LineGeometry );
st.setSymbol( lineSymbol );

rend->setStyles( QList<QgsVectorTileBasicRendererStyle>() << st );
layer->setRenderer( rend ); // takes ownership

QVERIFY( imageCheck( "render_test_polygon_with_line_style", layer.get(), layer->extent() ) );
}


QGSTEST_MAIN( TestQgsVectorTileLayer )
#include "testqgsvectortilelayer.moc"
Binary file not shown.

0 comments on commit 4cd40ab

Please sign in to comment.
You can’t perform that action at this time.