Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement converter for esriTS symbols for featureServers #58076

Merged
merged 11 commits into from
Jul 17, 2024
80 changes: 78 additions & 2 deletions src/core/providers/arcgis/qgsarcgisrestutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -748,6 +747,83 @@ std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriPictureMarkerSymbo
return symbol;
}

std::unique_ptr<QgsMarkerSymbol> 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 );
merydian marked this conversation as resolved.
Show resolved Hide resolved
markerLayer->setStrokeWidthUnit( Qgis::RenderUnit::Points );

QgsMarkerSymbolLayer::HorizontalAnchorPoint hAlign;
nyalldawson marked this conversation as resolved.
Show resolved Hide resolved
QgsMarkerSymbolLayer::VerticalAnchorPoint vAlign;
nyalldawson marked this conversation as resolved.
Show resolved Hide resolved

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() )
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/arcgis/qgsarcgisrestutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down
65 changes: 65 additions & 0 deletions tests/src/core/testqgsarcgisrestutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<QgsSymbol> 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 );
Expand Down
Loading