From e67f21b3914ae07d75de4ec2f73e1398fb67c273 Mon Sep 17 00:00:00 2001 From: Till Frankenbach Date: Wed, 17 Jul 2024 06:56:36 +0200 Subject: [PATCH] Implement converter for esriTS symbols for featureServers --- .../providers/arcgis/qgsarcgisrestutils.cpp | 80 ++++++++++++++++++- .../providers/arcgis/qgsarcgisrestutils.h | 1 + tests/src/core/testqgsarcgisrestutils.cpp | 65 +++++++++++++++ 3 files changed, 144 insertions(+), 2 deletions(-) diff --git a/src/core/providers/arcgis/qgsarcgisrestutils.cpp b/src/core/providers/arcgis/qgsarcgisrestutils.cpp index 1fcea44ce8d7..07b4976f7485 100644 --- a/src/core/providers/arcgis/qgsarcgisrestutils.cpp +++ b/src/core/providers/arcgis/qgsarcgisrestutils.cpp @@ -563,8 +563,7 @@ QgsSymbol *QgsArcGisRestUtils::convertSymbol( const QVariantMap &symbolData ) } else if ( type == QLatin1String( "esriTS" ) ) { - // text symbol - not supported - return nullptr; + return parseEsriTextMarkerSymbolJson( symbolData ).release(); } return nullptr; } @@ -748,6 +747,83 @@ std::unique_ptr QgsArcGisRestUtils::parseEsriPictureMarkerSymbo return symbol; } +std::unique_ptr QgsArcGisRestUtils::parseEsriTextMarkerSymbolJson( const QVariantMap &symbolData ) +{ + QgsSymbolLayerList layers; + + const QString fontFamily = symbolData.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "family" ) ).toString(); + + const QString chr = symbolData.value( QStringLiteral( "text" ) ).toString(); + + const double pointSize = symbolData.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "size" ) ).toDouble(); + + const QColor color = convertColor( symbolData.value( QStringLiteral( "color" ) ) ); + + const double esriAngle = symbolData.value( QStringLiteral( "angle" ) ).toDouble(); + + const double angle = 90.0 - esriAngle; + + std::unique_ptr< QgsFontMarkerSymbolLayer > markerLayer = std::make_unique< QgsFontMarkerSymbolLayer >( fontFamily, chr, pointSize, color, angle ); + + QColor strokeColor = convertColor( symbolData.value( QStringLiteral( "borderLineColor" ) ) ); + markerLayer->setStrokeColor( strokeColor ); + + double borderLineSize = symbolData.value( QStringLiteral( "borderLineSize" ) ).toDouble(); + markerLayer->setStrokeWidth( borderLineSize ); + + const QString fontStyle = symbolData.value( QStringLiteral( "font" ) ).toMap().value( QStringLiteral( "style" ) ).toString(); + markerLayer->setFontStyle( fontStyle ); + + double xOffset = symbolData.value( QStringLiteral( "xoffset" ) ).toDouble(); + double yOffset = symbolData.value( QStringLiteral( "yoffset" ) ).toDouble(); + + markerLayer->setOffset( QPointF( xOffset, yOffset ) ); + markerLayer->setOffsetUnit( Qgis::RenderUnit::Points ); + + markerLayer->setSizeUnit( Qgis::RenderUnit::Points ); + markerLayer->setStrokeWidthUnit( Qgis::RenderUnit::Points ); + + QgsMarkerSymbolLayer::HorizontalAnchorPoint hAlign = QgsMarkerSymbolLayer::HorizontalAnchorPoint::HCenter; + QgsMarkerSymbolLayer::VerticalAnchorPoint vAlign = QgsMarkerSymbolLayer::VerticalAnchorPoint::VCenter; + + QString horizontalAnchorPoint = symbolData.value( QStringLiteral( "horizontalAlignment" ) ).toString(); + QString verticalAnchorPoint = symbolData.value( QStringLiteral( "verticalAlignment" ) ).toString(); + + if ( horizontalAnchorPoint == QString( "center" ) ) + { + hAlign = QgsMarkerSymbolLayer::HorizontalAnchorPoint::HCenter; + } + else if ( horizontalAnchorPoint == QString( "left" ) ) + { + hAlign = QgsMarkerSymbolLayer::HorizontalAnchorPoint::Left; + } + else if ( horizontalAnchorPoint == QString( "right" ) ) + { + hAlign = QgsMarkerSymbolLayer::HorizontalAnchorPoint::Right; + } + + if ( verticalAnchorPoint == QString( "center" ) ) + { + vAlign = QgsMarkerSymbolLayer::VerticalAnchorPoint::VCenter; + } + else if ( verticalAnchorPoint == QString( "top" ) ) + { + vAlign = QgsMarkerSymbolLayer::VerticalAnchorPoint::Top; + } + else if ( verticalAnchorPoint == QString( "bottom" ) ) + { + vAlign = QgsMarkerSymbolLayer::VerticalAnchorPoint::Bottom; + } + + markerLayer->setHorizontalAnchorPoint( hAlign ); + markerLayer->setVerticalAnchorPoint( vAlign ); + + layers.append( markerLayer.release() ); + + std::unique_ptr< QgsMarkerSymbol > symbol = std::make_unique< QgsMarkerSymbol >( layers ); + return symbol; +} + QgsAbstractVectorLayerLabeling *QgsArcGisRestUtils::convertLabeling( const QVariantList &labelingData ) { if ( labelingData.empty() ) diff --git a/src/core/providers/arcgis/qgsarcgisrestutils.h b/src/core/providers/arcgis/qgsarcgisrestutils.h index c5e9aa1c10aa..e016f64a9aed 100644 --- a/src/core/providers/arcgis/qgsarcgisrestutils.h +++ b/src/core/providers/arcgis/qgsarcgisrestutils.h @@ -320,6 +320,7 @@ class CORE_EXPORT QgsArcGisRestUtils static std::unique_ptr< QgsFillSymbol > parseEsriPictureFillSymbolJson( const QVariantMap &symbolData ); static std::unique_ptr< QgsMarkerSymbol > parseEsriMarkerSymbolJson( const QVariantMap &symbolData ); static std::unique_ptr< QgsMarkerSymbol > parseEsriPictureMarkerSymbolJson( const QVariantMap &symbolData ); + static std::unique_ptr< QgsMarkerSymbol > parseEsriTextMarkerSymbolJson( const QVariantMap &symbolData ); static Qgis::MarkerShape parseEsriMarkerShape( const QString &style ); diff --git a/tests/src/core/testqgsarcgisrestutils.cpp b/tests/src/core/testqgsarcgisrestutils.cpp index 7c7cc724d5bc..aff166b9096c 100644 --- a/tests/src/core/testqgsarcgisrestutils.cpp +++ b/tests/src/core/testqgsarcgisrestutils.cpp @@ -253,6 +253,71 @@ void TestQgsArcGisRestUtils::testParseMarkerSymbol() QCOMPARE( markerLayer->strokeWidth(), 5.0 ); QCOMPARE( markerLayer->strokeWidthUnit(), Qgis::RenderUnit::Points ); + // esriTS + const QVariantMap fontMap = jsonStringToMap( "{" + "\"type\": \"esriTS\"," + "\"text\": \"text\"," + "\"color\": [" + "78," + "78," + "78," + "255" + "]," + "\"backgroundColor\": [" + "0," + "0," + "0," + "0" + "]," + "\"borderLineSize\": 2," + "\"borderLineColor\": [" + "255," + "0," + "255," + "255" + "]," + "\"haloSize\": 2," + "\"haloColor\": [" + "0," + "255," + "0," + "255" + "]," + "\"verticalAlignment\": \"bottom\"," + "\"horizontalAlignment\": \"left\"," + "\"rightToLeft\": false," + "\"angle\": 45," + "\"xoffset\": 0," + "\"yoffset\": 0," + "\"kerning\": true," + "\"font\": {" + "\"family\": \"Arial\"," + "\"size\": 12," + "\"style\": \"normal\"," + "\"weight\": \"bold\"," + "\"decoration\": \"none\"" + "}" + "}" ); + + std::unique_ptr fontSymbol( QgsArcGisRestUtils::convertSymbol( fontMap ) ); + QgsMarkerSymbol *fontMarker = dynamic_cast< QgsMarkerSymbol * >( fontSymbol.get() ); + QVERIFY( fontMarker ); + QCOMPARE( fontMarker->symbolLayerCount(), 1 ); + QgsFontMarkerSymbolLayer *fontMarkerLayer = dynamic_cast< QgsFontMarkerSymbolLayer * >( fontMarker->symbolLayer( 0 ) ); + QVERIFY( fontMarkerLayer ); + QCOMPARE( fontMarkerLayer->fontStyle(), QString( "normal" ) ); + QCOMPARE( fontMarkerLayer->fontFamily(), QString( "Arial" ) ); + QCOMPARE( fontMarkerLayer->offset(), QPointF( 0, 0 ) ); + QCOMPARE( fontMarkerLayer->angle(), 45 ); + QCOMPARE( fontMarkerLayer->horizontalAnchorPoint(), QgsMarkerSymbolLayer::HorizontalAnchorPoint::Left ); + QCOMPARE( fontMarkerLayer->verticalAnchorPoint(), QgsMarkerSymbolLayer::VerticalAnchorPoint::Bottom ); + QColor mainColor = fontMarkerLayer->color(); + QCOMPARE( mainColor.name(), QStringLiteral( "#4e4e4e" ) ); + QColor strokeColor = fontMarkerLayer->strokeColor(); + QCOMPARE( strokeColor.name(), QStringLiteral( "#ff00ff" ) ); + QCOMPARE( fontMarkerLayer->strokeWidth(), 2 ); + QCOMPARE( fontMarkerLayer->character(), QString( "text" ) ); + // invalid json symbol = QgsArcGisRestUtils::parseEsriMarkerSymbolJson( QVariantMap() ); QVERIFY( !symbol );