Skip to content

Commit 543acff

Browse files
committed
[FEATURE][AFS] Automatically convert ESRI picture marker symbols
and use as default style for remote layers with picture marker symbology
1 parent 51b2ce4 commit 543acff

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

src/providers/arcgisrest/qgsarcgisrestutils.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,8 @@ std::unique_ptr<QgsSymbol> QgsArcGisRestUtils::parseEsriSymbolJson( const QVaria
576576
}
577577
else if ( type == QLatin1String( "esriPMS" ) )
578578
{
579-
// picture marker - not supported
580-
return nullptr;
579+
// picture marker
580+
return parseEsriPictureMarkerSymbolJson( symbolData );
581581
}
582582
else if ( type == QLatin1String( "esriTS" ) )
583583
{
@@ -682,6 +682,41 @@ std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriMarkerSymbolJson(
682682
return symbol;
683683
}
684684

685+
std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriPictureMarkerSymbolJson( const QVariantMap &symbolData )
686+
{
687+
bool ok = false;
688+
const double widthInPixels = symbolData.value( QStringLiteral( "width" ) ).toInt( &ok );
689+
if ( !ok )
690+
return nullptr;
691+
const double heightInPixels = symbolData.value( QStringLiteral( "height" ) ).toInt( &ok );
692+
if ( !ok )
693+
return nullptr;
694+
695+
const double angleCCW = symbolData.value( QStringLiteral( "angle" ) ).toDouble( &ok );
696+
double angleCW = 0;
697+
if ( ok )
698+
angleCW = -angleCCW;
699+
700+
const double xOffset = symbolData.value( QStringLiteral( "xoffset" ) ).toDouble();
701+
const double yOffset = symbolData.value( QStringLiteral( "yoffset" ) ).toDouble();
702+
703+
//const QString contentType = symbolData.value( QStringLiteral( "contentType" ) ).toString();
704+
705+
QString symbolPath( symbolData.value( QStringLiteral( "imageData" ) ).toString() );
706+
symbolPath.prepend( QLatin1String( "base64:" ) );
707+
708+
QgsSymbolLayerList layers;
709+
std::unique_ptr< QgsRasterMarkerSymbolLayer > markerLayer = qgis::make_unique< QgsRasterMarkerSymbolLayer >( symbolPath, widthInPixels, angleCW, QgsSymbol::ScaleArea );
710+
markerLayer->setSizeUnit( QgsUnitTypes::RenderPixels );
711+
markerLayer->setFixedAspectRatio( static_cast< double >( widthInPixels ) / heightInPixels );
712+
markerLayer->setOffset( QPointF( xOffset, yOffset ) );
713+
markerLayer->setOffsetUnit( QgsUnitTypes::RenderPoints );
714+
layers.append( markerLayer.release() );
715+
716+
std::unique_ptr< QgsMarkerSymbol > symbol = qgis::make_unique< QgsMarkerSymbol >( layers );
717+
return symbol;
718+
}
719+
685720
QgsFeatureRenderer *QgsArcGisRestUtils::parseEsriRenderer( const QVariantMap &rendererData )
686721
{
687722
const QString type = rendererData.value( QStringLiteral( "type" ) ).toString();

src/providers/arcgisrest/qgsarcgisrestutils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class QgsArcGisRestUtils
5555
static std::unique_ptr< QgsLineSymbol > parseEsriLineSymbolJson( const QVariantMap &symbolData );
5656
static std::unique_ptr< QgsFillSymbol > parseEsriFillSymbolJson( const QVariantMap &symbolData );
5757
static std::unique_ptr< QgsMarkerSymbol > parseEsriMarkerSymbolJson( const QVariantMap &symbolData );
58+
static std::unique_ptr< QgsMarkerSymbol > parseEsriPictureMarkerSymbolJson( const QVariantMap &symbolData );
5859
static QgsFeatureRenderer *parseEsriRenderer( const QVariantMap &rendererData );
5960

6061
static QColor parseEsriColorJson( const QVariant &colorData );

tests/src/providers/testqgsarcgisrestutils.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class TestQgsArcGisRestUtils : public QObject
4343
void testParseEsriLineStyle();
4444
void testParseEsriColorJson();
4545
void testParseMarkerSymbol();
46+
void testPictureMarkerSymbol();
4647
void testParseLineSymbol();
4748
void testParseFillSymbol();
4849
void testParseRendererSimple();
@@ -200,6 +201,38 @@ void TestQgsArcGisRestUtils::testParseMarkerSymbol()
200201
QVERIFY( !symbol );
201202
}
202203

204+
void TestQgsArcGisRestUtils::testPictureMarkerSymbol()
205+
{
206+
QVariantMap map = jsonStringToMap( "{"
207+
"\"type\": \"esriPMS\","
208+
"\"url\": \"471E7E31\","
209+
"\"imageData\": \"abcdef\","
210+
"\"contentType\": \"image/png\","
211+
"\"width\": 20,"
212+
"\"height\": 25,"
213+
"\"angle\": 10,"
214+
"\"xoffset\": 7,"
215+
"\"yoffset\": 17"
216+
"}" );
217+
std::unique_ptr<QgsSymbol> symbol = QgsArcGisRestUtils::parseEsriSymbolJson( map );
218+
QgsMarkerSymbol *marker = dynamic_cast< QgsMarkerSymbol * >( symbol.get() );
219+
QVERIFY( marker );
220+
QCOMPARE( marker->symbolLayerCount(), 1 );
221+
QgsRasterMarkerSymbolLayer *markerLayer = dynamic_cast< QgsRasterMarkerSymbolLayer * >( marker->symbolLayer( 0 ) );
222+
QVERIFY( markerLayer );
223+
QCOMPARE( markerLayer->path(), QStringLiteral( "base64:abcdef" ) );
224+
QCOMPARE( markerLayer->size(), 20.0 );
225+
QCOMPARE( markerLayer->fixedAspectRatio(), 0.8 );
226+
QCOMPARE( markerLayer->sizeUnit(), QgsUnitTypes::RenderPixels );
227+
QCOMPARE( markerLayer->angle(), -10.0 ); // opposite direction to esri spec!
228+
QCOMPARE( markerLayer->offset(), QPointF( 7, 17 ) );
229+
QCOMPARE( markerLayer->offsetUnit(), QgsUnitTypes::RenderPoints );
230+
231+
// invalid json
232+
symbol = QgsArcGisRestUtils::parseEsriPictureMarkerSymbolJson( QVariantMap() );
233+
QVERIFY( !symbol );
234+
}
235+
203236
void TestQgsArcGisRestUtils::testParseLineSymbol()
204237
{
205238
QVariantMap map = jsonStringToMap( "{"

0 commit comments

Comments
 (0)