42 #include <QRegularExpression>
46 if ( esriFieldType == QLatin1String(
"esriFieldTypeInteger" ) )
47 return QVariant::LongLong;
48 if ( esriFieldType == QLatin1String(
"esriFieldTypeSmallInteger" ) )
50 if ( esriFieldType == QLatin1String(
"esriFieldTypeDouble" ) )
51 return QVariant::Double;
52 if ( esriFieldType == QLatin1String(
"esriFieldTypeSingle" ) )
53 return QVariant::Double;
54 if ( esriFieldType == QLatin1String(
"esriFieldTypeString" ) )
55 return QVariant::String;
56 if ( esriFieldType == QLatin1String(
"esriFieldTypeDate" ) )
57 return QVariant::DateTime;
58 if ( esriFieldType == QLatin1String(
"esriFieldTypeGeometry" ) )
59 return QVariant::Invalid;
60 if ( esriFieldType == QLatin1String(
"esriFieldTypeOID" ) )
61 return QVariant::LongLong;
62 if ( esriFieldType == QLatin1String(
"esriFieldTypeBlob" ) )
63 return QVariant::ByteArray;
64 if ( esriFieldType == QLatin1String(
"esriFieldTypeGlobalID" ) )
65 return QVariant::String;
66 if ( esriFieldType == QLatin1String(
"esriFieldTypeRaster" ) )
67 return QVariant::ByteArray;
68 if ( esriFieldType == QLatin1String(
"esriFieldTypeGUID" ) )
69 return QVariant::String;
70 if ( esriFieldType == QLatin1String(
"esriFieldTypeXML" ) )
71 return QVariant::String;
72 return QVariant::Invalid;
78 if ( esriGeometryType == QLatin1String(
"esriGeometryNull" ) )
80 else if ( esriGeometryType == QLatin1String(
"esriGeometryPoint" ) )
82 else if ( esriGeometryType == QLatin1String(
"esriGeometryMultipoint" ) )
84 else if ( esriGeometryType == QLatin1String(
"esriGeometryPolyline" ) )
86 else if ( esriGeometryType == QLatin1String(
"esriGeometryPolygon" ) )
88 else if ( esriGeometryType == QLatin1String(
"esriGeometryEnvelope" ) )
108 std::unique_ptr< QgsPoint > QgsArcGisRestUtils::convertPoint(
const QVariantList &coordList,
QgsWkbTypes::Type pointType )
110 int nCoords = coordList.size();
113 bool xok =
false, yok =
false;
114 double x = coordList[0].toDouble( &xok );
115 double y = coordList[1].toDouble( &yok );
118 double z = nCoords >= 3 ? coordList[2].toDouble() : 0;
119 double m = nCoords >= 4 ? coordList[3].toDouble() : 0;
120 return std::make_unique< QgsPoint >( pointType, x, y, z, m );
123 std::unique_ptr< QgsCircularString > QgsArcGisRestUtils::convertCircularString(
const QVariantMap &curveData,
QgsWkbTypes::Type pointType,
const QgsPoint &startPoint )
125 const QVariantList coordsList = curveData[QStringLiteral(
"c" )].toList();
126 if ( coordsList.isEmpty() )
128 QVector<QgsPoint> points;
129 points.append( startPoint );
130 for (
const QVariant &coordData : coordsList )
132 std::unique_ptr< QgsPoint > point( convertPoint( coordData.toList(), pointType ) );
137 points.append( *point );
139 std::unique_ptr< QgsCircularString > curve = std::make_unique< QgsCircularString> ();
140 curve->setPoints( points );
144 std::unique_ptr< QgsCompoundCurve > QgsArcGisRestUtils::convertCompoundCurve(
const QVariantList &curvesList,
QgsWkbTypes::Type pointType )
147 std::unique_ptr< QgsCompoundCurve > compoundCurve = std::make_unique< QgsCompoundCurve >();
149 compoundCurve->addCurve( lineString );
150 for (
const QVariant &curveData : curvesList )
152 if ( curveData.type() == QVariant::List )
154 std::unique_ptr< QgsPoint > point( convertPoint( curveData.toList(), pointType ) );
161 else if ( curveData.type() == QVariant::Map )
164 std::unique_ptr< QgsCircularString > circularString( convertCircularString( curveData.toMap(), pointType, lineString->
endPoint() ) );
165 if ( !circularString )
171 if ( compoundCurve->curveAt( compoundCurve->nCurves() - 1 )->nCoordinates() < 2 )
172 compoundCurve->removeCurve( compoundCurve->nCurves() - 1 );
174 const QgsPoint endPointCircularString = circularString->endPoint();
175 compoundCurve->addCurve( circularString.release() );
179 compoundCurve->addCurve( lineString );
180 lineString->
addVertex( endPointCircularString );
183 return compoundCurve;
186 std::unique_ptr< QgsPoint > QgsArcGisRestUtils::convertGeometryPoint(
const QVariantMap &geometryData,
QgsWkbTypes::Type pointType )
189 bool xok =
false, yok =
false;
190 double x = geometryData[QStringLiteral(
"x" )].toDouble( &xok );
191 double y = geometryData[QStringLiteral(
"y" )].toDouble( &yok );
194 double z = geometryData[QStringLiteral(
"z" )].toDouble();
195 double m = geometryData[QStringLiteral(
"m" )].toDouble();
196 return std::make_unique< QgsPoint >( pointType, x, y, z, m );
199 std::unique_ptr< QgsMultiPoint > QgsArcGisRestUtils::convertMultiPoint(
const QVariantMap &geometryData,
QgsWkbTypes::Type pointType )
202 const QVariantList coordsList = geometryData[QStringLiteral(
"points" )].toList();
204 std::unique_ptr< QgsMultiPoint > multiPoint = std::make_unique< QgsMultiPoint >();
205 multiPoint->reserve( coordsList.size() );
206 for (
const QVariant &coordData : coordsList )
208 const QVariantList coordList = coordData.toList();
209 std::unique_ptr< QgsPoint > p = convertPoint( coordList, pointType );
214 multiPoint->addGeometry( p.release() );
219 std::unique_ptr< QgsPoint > p = convertGeometryPoint( geometryData, pointType );
221 multiPoint->addGeometry( p.release() );
223 if ( multiPoint->numGeometries() == 0 )
231 std::unique_ptr< QgsMultiCurve > QgsArcGisRestUtils::convertGeometryPolyline(
const QVariantMap &geometryData,
QgsWkbTypes::Type pointType )
234 QVariantList pathsList;
235 if ( geometryData[QStringLiteral(
"paths" )].isValid() )
236 pathsList = geometryData[QStringLiteral(
"paths" )].toList();
237 else if ( geometryData[QStringLiteral(
"curvePaths" )].isValid() )
238 pathsList = geometryData[QStringLiteral(
"curvePaths" )].toList();
239 if ( pathsList.isEmpty() )
241 std::unique_ptr< QgsMultiCurve > multiCurve = std::make_unique< QgsMultiCurve >();
242 multiCurve->reserve( pathsList.size() );
243 for (
const QVariant &pathData : std::as_const( pathsList ) )
245 std::unique_ptr< QgsCompoundCurve > curve = convertCompoundCurve( pathData.toList(), pointType );
250 multiCurve->addGeometry( curve.release() );
255 std::unique_ptr< QgsMultiSurface > QgsArcGisRestUtils::convertGeometryPolygon(
const QVariantMap &geometryData,
QgsWkbTypes::Type pointType )
258 QVariantList ringsList;
259 if ( geometryData[QStringLiteral(
"rings" )].isValid() )
260 ringsList = geometryData[QStringLiteral(
"rings" )].toList();
261 else if ( geometryData[QStringLiteral(
"ringPaths" )].isValid() )
262 ringsList = geometryData[QStringLiteral(
"ringPaths" )].toList();
263 if ( ringsList.isEmpty() )
266 QList< QgsCompoundCurve * > curves;
267 for (
int i = 0, n = ringsList.size(); i < n; ++i )
269 std::unique_ptr< QgsCompoundCurve > curve = convertCompoundCurve( ringsList[i].toList(), pointType );
274 curves.append( curve.release() );
276 if ( curves.count() == 0 )
279 std::sort( curves.begin(), curves.end(), [](
const QgsCompoundCurve * a,
const QgsCompoundCurve * b )->bool{ double a_area = 0.0; double b_area = 0.0; a->sumUpArea( a_area ); b->sumUpArea( b_area ); return std::abs( a_area ) > std::abs( b_area ); } );
280 std::unique_ptr< QgsMultiSurface > result = std::make_unique< QgsMultiSurface >();
281 result->reserve( curves.size() );
282 while ( !curves.isEmpty() )
288 engine->prepareGeometry();
290 QMutableListIterator< QgsCompoundCurve * > it( curves );
291 while ( it.hasNext() )
298 if ( engine->contains( &point ) )
303 engine->prepareGeometry();
307 result->addGeometry( newPolygon );
309 if ( result->numGeometries() == 0 )
315 std::unique_ptr< QgsPolygon > QgsArcGisRestUtils::convertEnvelope(
const QVariantMap &geometryData )
318 bool xminOk =
false, yminOk =
false, xmaxOk =
false, ymaxOk =
false;
319 double xmin = geometryData[QStringLiteral(
"xmin" )].toDouble( &xminOk );
320 double ymin = geometryData[QStringLiteral(
"ymin" )].toDouble( &yminOk );
321 double xmax = geometryData[QStringLiteral(
"xmax" )].toDouble( &xmaxOk );
322 double ymax = geometryData[QStringLiteral(
"ymax" )].toDouble( &ymaxOk );
323 if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk )
325 std::unique_ptr< QgsLineString > ext = std::make_unique< QgsLineString> ();
326 ext->addVertex(
QgsPoint( xmin, ymin ) );
327 ext->addVertex(
QgsPoint( xmax, ymin ) );
328 ext->addVertex(
QgsPoint( xmax, ymax ) );
329 ext->addVertex(
QgsPoint( xmin, ymax ) );
330 ext->addVertex(
QgsPoint( xmin, ymin ) );
331 std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
332 poly->setExteriorRing( ext.release() );
345 if ( esriGeometryType == QLatin1String(
"esriGeometryNull" ) )
347 else if ( esriGeometryType == QLatin1String(
"esriGeometryPoint" ) )
348 return convertGeometryPoint( geometryData, pointType ).release();
349 else if ( esriGeometryType == QLatin1String(
"esriGeometryMultipoint" ) )
350 return convertMultiPoint( geometryData, pointType ).release();
351 else if ( esriGeometryType == QLatin1String(
"esriGeometryPolyline" ) )
352 return convertGeometryPolyline( geometryData, pointType ).release();
353 else if ( esriGeometryType == QLatin1String(
"esriGeometryPolygon" ) )
354 return convertGeometryPolygon( geometryData, pointType ).release();
355 else if ( esriGeometryType == QLatin1String(
"esriGeometryEnvelope" ) )
356 return convertEnvelope( geometryData ).release();
379 QString spatialReference = spatialReferenceMap[QStringLiteral(
"latestWkid" )].toString();
380 if ( spatialReference.isEmpty() )
381 spatialReference = spatialReferenceMap[QStringLiteral(
"wkid" )].toString();
384 if ( !spatialReference.isEmpty() )
393 else if ( !spatialReferenceMap[QStringLiteral(
"wkt" )].toString().isEmpty() )
396 crs.
createFromWkt( spatialReferenceMap[QStringLiteral(
"wkt" )].toString() );
411 const QString type = symbolData.value( QStringLiteral(
"type" ) ).toString();
412 if ( type == QLatin1String(
"esriSMS" ) )
415 return parseEsriMarkerSymbolJson( symbolData ).release();
417 else if ( type == QLatin1String(
"esriSLS" ) )
420 return parseEsriLineSymbolJson( symbolData ).release();
422 else if ( type == QLatin1String(
"esriSFS" ) )
425 return parseEsriFillSymbolJson( symbolData ).release();
427 else if ( type == QLatin1String(
"esriPFS" ) )
429 return parseEsriPictureFillSymbolJson( symbolData ).release();
431 else if ( type == QLatin1String(
"esriPMS" ) )
434 return parseEsriPictureMarkerSymbolJson( symbolData ).release();
436 else if ( type == QLatin1String(
"esriTS" ) )
444 std::unique_ptr<QgsLineSymbol> QgsArcGisRestUtils::parseEsriLineSymbolJson(
const QVariantMap &symbolData )
446 QColor lineColor =
convertColor( symbolData.value( QStringLiteral(
"color" ) ) );
447 if ( !lineColor.isValid() )
451 double widthInPoints = symbolData.value( QStringLiteral(
"width" ) ).toDouble( &ok );
456 Qt::PenStyle penStyle =
convertLineStyle( symbolData.value( QStringLiteral(
"style" ) ).toString() );
457 std::unique_ptr< QgsSimpleLineSymbolLayer > lineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( lineColor, widthInPoints, penStyle );
459 layers.append( lineLayer.release() );
461 std::unique_ptr< QgsLineSymbol > symbol = std::make_unique< QgsLineSymbol >( layers );
465 std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriFillSymbolJson(
const QVariantMap &symbolData )
467 QColor fillColor =
convertColor( symbolData.value( QStringLiteral(
"color" ) ) );
468 Qt::BrushStyle brushStyle =
convertFillStyle( symbolData.value( QStringLiteral(
"style" ) ).toString() );
470 const QVariantMap outlineData = symbolData.value( QStringLiteral(
"outline" ) ).toMap();
471 QColor lineColor =
convertColor( outlineData.value( QStringLiteral(
"color" ) ) );
472 Qt::PenStyle penStyle =
convertLineStyle( outlineData.value( QStringLiteral(
"style" ) ).toString() );
474 double penWidthInPoints = outlineData.value( QStringLiteral(
"width" ) ).toDouble( &ok );
477 std::unique_ptr< QgsSimpleFillSymbolLayer > fillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( fillColor, brushStyle, lineColor, penStyle, penWidthInPoints );
479 layers.append( fillLayer.release() );
481 std::unique_ptr< QgsFillSymbol > symbol = std::make_unique< QgsFillSymbol >( layers );
485 std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriPictureFillSymbolJson(
const QVariantMap &symbolData )
489 double widthInPixels = symbolData.value( QStringLiteral(
"width" ) ).toInt( &ok );
493 const double xScale = symbolData.value( QStringLiteral(
"xscale" ) ).toDouble( &ok );
495 widthInPixels *= xScale;
497 const double angleCCW = symbolData.value( QStringLiteral(
"angle" ) ).toDouble( &ok );
502 const double xOffset = symbolData.value( QStringLiteral(
"xoffset" ) ).toDouble();
503 const double yOffset = symbolData.value( QStringLiteral(
"yoffset" ) ).toDouble();
505 QString symbolPath( symbolData.value( QStringLiteral(
"imageData" ) ).toString() );
506 symbolPath.prepend( QLatin1String(
"base64:" ) );
509 std::unique_ptr< QgsRasterFillSymbolLayer > fillLayer = std::make_unique< QgsRasterFillSymbolLayer >( symbolPath );
510 fillLayer->setWidth( widthInPixels );
511 fillLayer->setAngle( angleCW );
513 fillLayer->setOffset( QPointF( xOffset, yOffset ) );
515 layers.append( fillLayer.release() );
517 const QVariantMap outlineData = symbolData.value( QStringLiteral(
"outline" ) ).toMap();
518 QColor lineColor =
convertColor( outlineData.value( QStringLiteral(
"color" ) ) );
519 Qt::PenStyle penStyle =
convertLineStyle( outlineData.value( QStringLiteral(
"style" ) ).toString() );
520 double penWidthInPoints = outlineData.value( QStringLiteral(
"width" ) ).toDouble( &ok );
522 std::unique_ptr< QgsSimpleLineSymbolLayer > lineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( lineColor, penWidthInPoints, penStyle );
524 layers.append( lineLayer.release() );
526 std::unique_ptr< QgsFillSymbol > symbol = std::make_unique< QgsFillSymbol >( layers );
530 Qgis::MarkerShape QgsArcGisRestUtils::parseEsriMarkerShape(
const QString &style )
532 if ( style == QLatin1String(
"esriSMSCircle" ) )
534 else if ( style == QLatin1String(
"esriSMSCross" ) )
536 else if ( style == QLatin1String(
"esriSMSDiamond" ) )
538 else if ( style == QLatin1String(
"esriSMSSquare" ) )
540 else if ( style == QLatin1String(
"esriSMSX" ) )
542 else if ( style == QLatin1String(
"esriSMSTriangle" ) )
548 std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriMarkerSymbolJson(
const QVariantMap &symbolData )
550 QColor fillColor =
convertColor( symbolData.value( QStringLiteral(
"color" ) ) );
552 const double sizeInPoints = symbolData.value( QStringLiteral(
"size" ) ).toDouble( &ok );
555 const double angleCCW = symbolData.value( QStringLiteral(
"angle" ) ).toDouble( &ok );
560 Qgis::MarkerShape shape = parseEsriMarkerShape( symbolData.value( QStringLiteral(
"style" ) ).toString() );
562 const double xOffset = symbolData.value( QStringLiteral(
"xoffset" ) ).toDouble();
563 const double yOffset = symbolData.value( QStringLiteral(
"yoffset" ) ).toDouble();
565 const QVariantMap outlineData = symbolData.value( QStringLiteral(
"outline" ) ).toMap();
566 QColor lineColor =
convertColor( outlineData.value( QStringLiteral(
"color" ) ) );
567 Qt::PenStyle penStyle =
convertLineStyle( outlineData.value( QStringLiteral(
"style" ) ).toString() );
568 double penWidthInPoints = outlineData.value( QStringLiteral(
"width" ) ).toDouble( &ok );
571 std::unique_ptr< QgsSimpleMarkerSymbolLayer > markerLayer = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, sizeInPoints, angleCW,
Qgis::ScaleMethod::ScaleArea, fillColor, lineColor );
574 markerLayer->setStrokeStyle( penStyle );
575 markerLayer->setStrokeWidth( penWidthInPoints );
576 markerLayer->setOffset( QPointF( xOffset, yOffset ) );
578 layers.append( markerLayer.release() );
580 std::unique_ptr< QgsMarkerSymbol > symbol = std::make_unique< QgsMarkerSymbol >( layers );
584 std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriPictureMarkerSymbolJson(
const QVariantMap &symbolData )
587 const double widthInPixels = symbolData.value( QStringLiteral(
"width" ) ).toInt( &ok );
590 const double heightInPixels = symbolData.value( QStringLiteral(
"height" ) ).toInt( &ok );
594 const double angleCCW = symbolData.value( QStringLiteral(
"angle" ) ).toDouble( &ok );
599 const double xOffset = symbolData.value( QStringLiteral(
"xoffset" ) ).toDouble();
600 const double yOffset = symbolData.value( QStringLiteral(
"yoffset" ) ).toDouble();
604 QString symbolPath( symbolData.value( QStringLiteral(
"imageData" ) ).toString() );
605 symbolPath.prepend( QLatin1String(
"base64:" ) );
608 std::unique_ptr< QgsRasterMarkerSymbolLayer > markerLayer = std::make_unique< QgsRasterMarkerSymbolLayer >( symbolPath, widthInPixels, angleCW,
Qgis::ScaleMethod::ScaleArea );
612 if ( !
qgsDoubleNear(
static_cast< double >( heightInPixels ) / widthInPixels, markerLayer->defaultAspectRatio() ) )
613 markerLayer->setFixedAspectRatio(
static_cast< double >( heightInPixels ) / widthInPixels );
615 markerLayer->setOffset( QPointF( xOffset, yOffset ) );
617 layers.append( markerLayer.release() );
619 std::unique_ptr< QgsMarkerSymbol > symbol = std::make_unique< QgsMarkerSymbol >( layers );
625 if ( labelingData.empty() )
632 for (
const QVariant &lbl : labelingData )
634 const QVariantMap labeling = lbl.toMap();
639 const QString placement = labeling.value( QStringLiteral(
"labelPlacement" ) ).toString();
640 if ( placement == QLatin1String(
"esriServerPointLabelPlacementAboveCenter" ) )
645 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementBelowCenter" ) )
650 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementCenterCenter" ) )
655 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementAboveLeft" ) )
660 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementBelowLeft" ) )
665 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementCenterLeft" ) )
670 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementAboveRight" ) )
675 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementBelowRight" ) )
680 else if ( placement == QLatin1String(
"esriServerPointLabelPlacementCenterRight" ) )
685 else if ( placement == QLatin1String(
"esriServerLinePlacementAboveAfter" ) ||
686 placement == QLatin1String(
"esriServerLinePlacementAboveStart" ) ||
687 placement == QLatin1String(
"esriServerLinePlacementAboveAlong" ) )
692 else if ( placement == QLatin1String(
"esriServerLinePlacementBelowAfter" ) ||
693 placement == QLatin1String(
"esriServerLinePlacementBelowStart" ) ||
694 placement == QLatin1String(
"esriServerLinePlacementBelowAlong" ) )
699 else if ( placement == QLatin1String(
"esriServerLinePlacementCenterAfter" ) ||
700 placement == QLatin1String(
"esriServerLinePlacementCenterStart" ) ||
701 placement == QLatin1String(
"esriServerLinePlacementCenterAlong" ) )
706 else if ( placement == QLatin1String(
"esriServerPolygonPlacementAlwaysHorizontal" ) )
711 const double minScale = labeling.value( QStringLiteral(
"minScale" ) ).toDouble();
712 const double maxScale = labeling.value( QStringLiteral(
"maxScale" ) ).toDouble();
714 QVariantMap symbol = labeling.value( QStringLiteral(
"symbol" ) ).toMap();
716 const double haloSize = symbol.value( QStringLiteral(
"haloSize" ) ).toDouble();
727 const QString fontFamily = symbol.value( QStringLiteral(
"font" ) ).toMap().value( QStringLiteral(
"family" ) ).toString();
728 const QString fontStyle = symbol.value( QStringLiteral(
"font" ) ).toMap().value( QStringLiteral(
"style" ) ).toString();
729 const QString fontWeight = symbol.value( QStringLiteral(
"font" ) ).toMap().value( QStringLiteral(
"weight" ) ).toString();
730 const int fontSize = symbol.value( QStringLiteral(
"font" ) ).toMap().value( QStringLiteral(
"size" ) ).toInt();
731 QFont font( fontFamily, fontSize );
732 font.setStyleName( fontStyle );
733 font.setWeight( fontWeight == QLatin1String(
"bold" ) ? QFont::Bold : QFont::Normal );
741 QString where = labeling.value( QStringLiteral(
"where" ) ).toString();
760 const QString type = rendererData.value( QStringLiteral(
"type" ) ).toString();
761 if ( type == QLatin1String(
"simple" ) )
763 const QVariantMap symbolProps = rendererData.value( QStringLiteral(
"symbol" ) ).toMap();
764 std::unique_ptr< QgsSymbol > symbol(
convertSymbol( symbolProps ) );
770 else if ( type == QLatin1String(
"uniqueValue" ) )
772 const QString field1 = rendererData.value( QStringLiteral(
"field1" ) ).toString();
773 const QString field2 = rendererData.value( QStringLiteral(
"field2" ) ).toString();
774 const QString field3 = rendererData.value( QStringLiteral(
"field3" ) ).toString();
776 if ( !field2.isEmpty() || !field3.isEmpty() )
778 const QString delimiter = rendererData.value( QStringLiteral(
"fieldDelimiter" ) ).toString();
779 if ( !field3.isEmpty() )
781 attribute = QStringLiteral(
"concat(\"%1\",'%2',\"%3\",'%4',\"%5\")" ).arg( field1, delimiter, field2, delimiter, field3 );
785 attribute = QStringLiteral(
"concat(\"%1\",'%2',\"%3\")" ).arg( field1, delimiter, field2 );
793 const QVariantList categories = rendererData.value( QStringLiteral(
"uniqueValueInfos" ) ).toList();
795 for (
const QVariant &category : categories )
797 const QVariantMap categoryData = category.toMap();
798 const QString value = categoryData.value( QStringLiteral(
"value" ) ).toString();
799 const QString label = categoryData.value( QStringLiteral(
"label" ) ).toString();
807 std::unique_ptr< QgsSymbol > defaultSymbol(
convertSymbol( rendererData.value( QStringLiteral(
"defaultSymbol" ) ).toMap() ) );
810 categoryList.append(
QgsRendererCategory( QVariant(), defaultSymbol.release(), rendererData.value( QStringLiteral(
"defaultLabel" ) ).toString() ) );
813 if ( categoryList.empty() )
818 else if ( type == QLatin1String(
"classBreaks" ) )
823 else if ( type == QLatin1String(
"heatmap" ) )
828 else if ( type == QLatin1String(
"vectorField" ) )
838 QString expression = string;
841 expression = expression.replace( QRegularExpression(
"(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)(\\s|^)CONCAT(\\s|$)" ), QStringLiteral(
"\\4||\\5" ) );
842 expression = expression.replace( QRegularExpression(
"(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)(\\s|^)NEWLINE(\\s|$)" ), QStringLiteral(
"\\4'\\n'\\5" ) );
845 expression = expression.replace( QRegularExpression(
"\"(.*?(?<!\\\\))\"" ), QStringLiteral(
"'\\1'" ) );
846 expression = expression.replace( QRegularExpression(
"\\\\\"" ), QStringLiteral(
"\"" ) );
849 expression = expression.replace( QRegularExpression(
"\\[([^]]*)\\]" ), QStringLiteral(
"\"\\1\"" ) );
856 const QVariantList colorParts = colorData.toList();
857 if ( colorParts.count() < 4 )
860 int red = colorParts.at( 0 ).toInt();
861 int green = colorParts.at( 1 ).toInt();
862 int blue = colorParts.at( 2 ).toInt();
863 int alpha = colorParts.at( 3 ).toInt();
864 return QColor( red, green, blue, alpha );
869 if ( style == QLatin1String(
"esriSLSSolid" ) )
870 return Qt::SolidLine;
871 else if ( style == QLatin1String(
"esriSLSDash" ) )
873 else if ( style == QLatin1String(
"esriSLSDashDot" ) )
874 return Qt::DashDotLine;
875 else if ( style == QLatin1String(
"esriSLSDashDotDot" ) )
876 return Qt::DashDotDotLine;
877 else if ( style == QLatin1String(
"esriSLSDot" ) )
879 else if ( style == QLatin1String(
"esriSLSNull" ) )
882 return Qt::SolidLine;
887 if ( style == QLatin1String(
"esriSFSBackwardDiagonal" ) )
888 return Qt::BDiagPattern;
889 else if ( style == QLatin1String(
"esriSFSCross" ) )
890 return Qt::CrossPattern;
891 else if ( style == QLatin1String(
"esriSFSDiagonalCross" ) )
892 return Qt::DiagCrossPattern;
893 else if ( style == QLatin1String(
"esriSFSForwardDiagonal" ) )
894 return Qt::FDiagPattern;
895 else if ( style == QLatin1String(
"esriSFSHorizontal" ) )
896 return Qt::HorPattern;
897 else if ( style == QLatin1String(
"esriSFSNull" ) )
899 else if ( style == QLatin1String(
"esriSFSSolid" ) )
900 return Qt::SolidPattern;
901 else if ( style == QLatin1String(
"esriSFSVertical" ) )
902 return Qt::VerPattern;
904 return Qt::SolidPattern;
909 if ( value.isNull() )
912 QDateTime dt = QDateTime::fromMSecsSinceEpoch( value.toLongLong( &ok ) );
915 QgsDebugMsg( QStringLiteral(
"Invalid value %1 for datetime" ).arg( value.toString() ) );
@ ScaleArea
Calculate scale by the area.
MarkerShape
Marker shapes.
@ Cross2
Rotated cross (lines only), 'x' shape.
@ Cross
Cross (lines only)
Abstract base class for all geometries.
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
static QgsCoordinateReferenceSystem convertSpatialReference(const QVariantMap &spatialReferenceMap)
Converts a spatial reference JSON definition to a QgsCoordinateReferenceSystem value.
static QDateTime convertDateTime(const QVariant &value)
Converts a date time value to a QDateTime.
static QString convertLabelingExpression(const QString &string)
Converts an ESRI labeling expression to a QGIS expression string.
static QgsSymbol * convertSymbol(const QVariantMap &definition)
Converts a symbol JSON definition to a QgsSymbol.
static QgsAbstractGeometry * convertGeometry(const QVariantMap &geometry, const QString &esriGeometryType, bool hasM, bool hasZ, QgsCoordinateReferenceSystem *crs=nullptr)
Converts an ESRI REST geometry JSON definition to a QgsAbstractGeometry.
static Qt::PenStyle convertLineStyle(const QString &style)
Converts an ESRI line style to a Qt pen style.
static QgsFeatureRenderer * convertRenderer(const QVariantMap &rendererData)
Converts renderer JSON data to an equivalent QgsFeatureRenderer.
static Qt::BrushStyle convertFillStyle(const QString &style)
Converts an ESRI fill style to a Qt brush style.
static QVariant::Type convertFieldType(const QString &type)
Converts an ESRI REST field type to a QVariant type.
static QgsWkbTypes::Type convertGeometryType(const QString &type)
Converts an ESRI REST geometry type to a WKB type.
static QgsAbstractVectorLayerLabeling * convertLabeling(const QVariantList &data)
Converts labeling JSON data to an equivalent QGIS vector labeling.
static QColor convertColor(const QVariant &data)
Converts ESRI JSON color data to a QColor object.
Compound curve geometry type.
QgsPoint startPoint() const override SIP_HOLDGIL
Returns the starting point of the curve.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool createFromWkt(const QString &wkt)
Sets this CRS using a WKT definition.
bool createFromString(const QString &definition)
Set up this CRS from a string definition.
Curve polygon geometry type.
virtual void setExteriorRing(QgsCurve *ring)
Sets the exterior ring of the polygon.
virtual void addInteriorRing(QgsCurve *ring)
Adds an interior ring to the geometry (takes ownership)
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Class for parsing and evaluation of expressions (formerly called "search strings").
bool isValid() const
Checks if this expression is valid.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
void setPlacementFlags(QgsLabeling::LinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
Line string geometry type, with support for z-dimension and m-values.
QgsPoint endPoint() const override SIP_HOLDGIL
Returns the end point of the curve.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
Contains settings for how a map layer will be labeled.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
QuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
QString fieldName
Name of field (or an expression) to use for label text.
Point geometry type, with support for z-dimension and m-values.
A rectangle specified with double values.
bool intersects(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle intersects with other rectangle.
Represents an individual category (class) from a QgsCategorizedSymbolRenderer.
A child rule for QgsRuleBasedLabeling.
void setActive(bool state)
Sets if this rule is active.
void appendChild(QgsRuleBasedLabeling::Rule *rule)
add child rule, take ownership, sets this as parent
Rule based labeling for a vector layer.
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Abstract base class for all rendered symbols.
Container for settings relating to a text buffer.
void setColor(const QColor &color)
Sets the color for the buffer.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the buffer size.
void setSize(double size)
Sets the size of the buffer.
Container for all settings relating to text rendering.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
@ RenderPoints
Points (e.g., for font sizes)
Type
The WKB type describes the number of dimensions a geometry has.
static Type zmType(Type type, bool hasZ, bool hasM) SIP_HOLDGIL
Returns the modified input geometry type according to hasZ / hasM.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QList< QgsRendererCategory > QgsCategoryList
QList< QgsSymbolLayer * > QgsSymbolLayerList
const QgsCoordinateReferenceSystem & crs