Skip to content

Commit 31b82de

Browse files
committed
[FEATURE][AFS] Automatically convert ESRI picture fill symbols
1 parent def29e8 commit 31b82de

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

src/providers/arcgisrest/qgsarcgisrestutils.cpp

+46-2
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,7 @@ std::unique_ptr<QgsSymbol> QgsArcGisRestUtils::parseEsriSymbolJson( const QVaria
571571
}
572572
else if ( type == QLatin1String( "esriPFS" ) )
573573
{
574-
// picture fill - not supported
575-
return nullptr;
574+
return parseEsriPictureFillSymbolJson( symbolData );
576575
}
577576
else if ( type == QLatin1String( "esriPMS" ) )
578577
{
@@ -628,6 +627,51 @@ std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriFillSymbolJson( cons
628627
return symbol;
629628
}
630629

630+
std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriPictureFillSymbolJson( const QVariantMap &symbolData )
631+
{
632+
bool ok = false;
633+
634+
double widthInPixels = symbolData.value( QStringLiteral( "width" ) ).toInt( &ok );
635+
if ( !ok )
636+
return nullptr;
637+
638+
const double xScale = symbolData.value( QStringLiteral( "xscale" ) ).toDouble( &ok );
639+
if ( !qgsDoubleNear( xScale, 0.0 ) )
640+
widthInPixels *= xScale;
641+
642+
const double angleCCW = symbolData.value( QStringLiteral( "angle" ) ).toDouble( &ok );
643+
double angleCW = 0;
644+
if ( ok )
645+
angleCW = -angleCCW;
646+
647+
const double xOffset = symbolData.value( QStringLiteral( "xoffset" ) ).toDouble();
648+
const double yOffset = symbolData.value( QStringLiteral( "yoffset" ) ).toDouble();
649+
650+
QString symbolPath( symbolData.value( QStringLiteral( "imageData" ) ).toString() );
651+
symbolPath.prepend( QLatin1String( "base64:" ) );
652+
653+
QgsSymbolLayerList layers;
654+
std::unique_ptr< QgsRasterFillSymbolLayer > fillLayer = qgis::make_unique< QgsRasterFillSymbolLayer >( symbolPath );
655+
fillLayer->setWidth( widthInPixels );
656+
fillLayer->setAngle( angleCW );
657+
fillLayer->setWidthUnit( QgsUnitTypes::RenderPixels );
658+
fillLayer->setOffset( QPointF( xOffset, yOffset ) );
659+
fillLayer->setOffsetUnit( QgsUnitTypes::RenderPoints );
660+
layers.append( fillLayer.release() );
661+
662+
const QVariantMap outlineData = symbolData.value( QStringLiteral( "outline" ) ).toMap();
663+
QColor lineColor = parseEsriColorJson( outlineData.value( QStringLiteral( "color" ) ) );
664+
Qt::PenStyle penStyle = parseEsriLineStyle( outlineData.value( QStringLiteral( "style" ) ).toString() );
665+
double penWidthInPoints = outlineData.value( QStringLiteral( "width" ) ).toDouble( &ok );
666+
667+
std::unique_ptr< QgsSimpleLineSymbolLayer > lineLayer = qgis::make_unique< QgsSimpleLineSymbolLayer >( lineColor, penWidthInPoints, penStyle );
668+
lineLayer->setWidthUnit( QgsUnitTypes::RenderPoints );
669+
layers.append( lineLayer.release() );
670+
671+
std::unique_ptr< QgsFillSymbol > symbol = qgis::make_unique< QgsFillSymbol >( layers );
672+
return symbol;
673+
}
674+
631675
QgsSimpleMarkerSymbolLayerBase::Shape parseEsriMarkerShape( const QString &style )
632676
{
633677
if ( style == QLatin1String( "esriSMSCircle" ) )

src/providers/arcgisrest/qgsarcgisrestutils.h

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class QgsArcGisRestUtils
5454
static std::unique_ptr< QgsSymbol > parseEsriSymbolJson( const QVariantMap &symbolData );
5555
static std::unique_ptr< QgsLineSymbol > parseEsriLineSymbolJson( const QVariantMap &symbolData );
5656
static std::unique_ptr< QgsFillSymbol > parseEsriFillSymbolJson( const QVariantMap &symbolData );
57+
static std::unique_ptr< QgsFillSymbol > parseEsriPictureFillSymbolJson( const QVariantMap &symbolData );
5758
static std::unique_ptr< QgsMarkerSymbol > parseEsriMarkerSymbolJson( const QVariantMap &symbolData );
5859
static std::unique_ptr< QgsMarkerSymbol > parseEsriPictureMarkerSymbolJson( const QVariantMap &symbolData );
5960
static QgsFeatureRenderer *parseEsriRenderer( const QVariantMap &rendererData );

tests/src/providers/testqgsarcgisrestutils.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class TestQgsArcGisRestUtils : public QObject
4646
void testPictureMarkerSymbol();
4747
void testParseLineSymbol();
4848
void testParseFillSymbol();
49+
void testParsePictureFillSymbol();
4950
void testParseRendererSimple();
5051
void testParseRendererCategorized();
5152

@@ -299,6 +300,46 @@ void TestQgsArcGisRestUtils::testParseFillSymbol()
299300
QCOMPARE( fillLayer->strokeStyle(), Qt::DashDotLine );
300301
}
301302

303+
304+
void TestQgsArcGisRestUtils::testParsePictureFillSymbol()
305+
{
306+
QVariantMap map = jsonStringToMap( "{"
307+
"\"type\": \"esriPFS\","
308+
"\"url\": \"866880A0\","
309+
"\"imageData\": \"abcdef\","
310+
"\"contentType\": \"image/png\","
311+
"\"width\": 20,"
312+
"\"height\": 25,"
313+
"\"angle\": 0,"
314+
"\"outline\": {"
315+
"\"type\": \"esriSLS\","
316+
"\"style\": \"esriSLSDashDot\","
317+
"\"color\": ["
318+
"110,"
319+
"120,"
320+
"130,"
321+
"215"
322+
"],"
323+
"\"width\": 5"
324+
"}"
325+
"}" );
326+
std::unique_ptr<QgsSymbol> symbol = QgsArcGisRestUtils::parseEsriSymbolJson( map );
327+
QgsFillSymbol *fill = dynamic_cast< QgsFillSymbol * >( symbol.get() );
328+
QVERIFY( fill );
329+
QCOMPARE( fill->symbolLayerCount(), 2 );
330+
QgsRasterFillSymbolLayer *fillLayer = dynamic_cast< QgsRasterFillSymbolLayer * >( fill->symbolLayer( 0 ) );
331+
QVERIFY( fillLayer );
332+
QCOMPARE( fillLayer->imageFilePath(), QString( "base64:abcdef" ) );
333+
QCOMPARE( fillLayer->width(), 20.0 );
334+
QCOMPARE( fillLayer->widthUnit(), QgsUnitTypes::RenderPixels );
335+
QgsSimpleLineSymbolLayer *lineLayer = dynamic_cast< QgsSimpleLineSymbolLayer * >( fill->symbolLayer( 1 ) );
336+
QVERIFY( lineLayer );
337+
QCOMPARE( lineLayer->color(), QColor( 110, 120, 130, 215 ) );
338+
QCOMPARE( lineLayer->width(), 5.0 );
339+
QCOMPARE( lineLayer->widthUnit(), QgsUnitTypes::RenderPoints );
340+
QCOMPARE( lineLayer->penStyle(), Qt::DashDotLine );
341+
}
342+
302343
void TestQgsArcGisRestUtils::testParseRendererSimple()
303344
{
304345
QVariantMap map = jsonStringToMap( "{"

0 commit comments

Comments
 (0)