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();
 
  377   QString spatialReference = spatialReferenceMap[QStringLiteral( 
"latestWkid" )].toString();
 
  378   if ( spatialReference.isEmpty() )
 
  379     spatialReference = spatialReferenceMap[QStringLiteral( 
"wkid" )].toString();
 
  380   if ( spatialReference.isEmpty() )
 
  381     spatialReference = spatialReferenceMap[QStringLiteral( 
"wkt" )].toString();
 
  383     spatialReference = QStringLiteral( 
"EPSG:%1" ).arg( spatialReference );
 
  396   const QString type = symbolData.value( QStringLiteral( 
"type" ) ).toString();
 
  397   if ( type == QLatin1String( 
"esriSMS" ) )
 
  400     return parseEsriMarkerSymbolJson( symbolData ).release();
 
  402   else if ( type == QLatin1String( 
"esriSLS" ) )
 
  405     return parseEsriLineSymbolJson( symbolData ).release();
 
  407   else if ( type == QLatin1String( 
"esriSFS" ) )
 
  410     return parseEsriFillSymbolJson( symbolData ).release();
 
  412   else if ( type == QLatin1String( 
"esriPFS" ) )
 
  414     return parseEsriPictureFillSymbolJson( symbolData ).release();
 
  416   else if ( type == QLatin1String( 
"esriPMS" ) )
 
  419     return parseEsriPictureMarkerSymbolJson( symbolData ).release();
 
  421   else if ( type == QLatin1String( 
"esriTS" ) )
 
  429 std::unique_ptr<QgsLineSymbol> QgsArcGisRestUtils::parseEsriLineSymbolJson( 
const QVariantMap &symbolData )
 
  431   QColor lineColor = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  432   if ( !lineColor.isValid() )
 
  436   double widthInPoints = symbolData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  441   Qt::PenStyle penStyle = 
convertLineStyle( symbolData.value( QStringLiteral( 
"style" ) ).toString() );
 
  442   std::unique_ptr< QgsSimpleLineSymbolLayer > lineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( lineColor, widthInPoints, penStyle );
 
  444   layers.append( lineLayer.release() );
 
  446   std::unique_ptr< QgsLineSymbol > symbol = std::make_unique< QgsLineSymbol >( layers );
 
  450 std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriFillSymbolJson( 
const QVariantMap &symbolData )
 
  452   QColor fillColor = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  453   Qt::BrushStyle brushStyle = 
convertFillStyle( symbolData.value( QStringLiteral( 
"style" ) ).toString() );
 
  455   const QVariantMap outlineData = symbolData.value( QStringLiteral( 
"outline" ) ).toMap();
 
  456   QColor lineColor = 
convertColor( outlineData.value( QStringLiteral( 
"color" ) ) );
 
  457   Qt::PenStyle penStyle = 
convertLineStyle( outlineData.value( QStringLiteral( 
"style" ) ).toString() );
 
  459   double penWidthInPoints = outlineData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  462   std::unique_ptr< QgsSimpleFillSymbolLayer > fillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( fillColor, brushStyle, lineColor, penStyle, penWidthInPoints );
 
  464   layers.append( fillLayer.release() );
 
  466   std::unique_ptr< QgsFillSymbol > symbol = std::make_unique< QgsFillSymbol >( layers );
 
  470 std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriPictureFillSymbolJson( 
const QVariantMap &symbolData )
 
  474   double widthInPixels = symbolData.value( QStringLiteral( 
"width" ) ).toInt( &ok );
 
  478   const double xScale = symbolData.value( QStringLiteral( 
"xscale" ) ).toDouble( &ok );
 
  480     widthInPixels *= xScale;
 
  482   const double angleCCW = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble( &ok );
 
  487   const double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  488   const double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  490   QString symbolPath( symbolData.value( QStringLiteral( 
"imageData" ) ).toString() );
 
  491   symbolPath.prepend( QLatin1String( 
"base64:" ) );
 
  494   std::unique_ptr< QgsRasterFillSymbolLayer > fillLayer = std::make_unique< QgsRasterFillSymbolLayer >( symbolPath );
 
  495   fillLayer->setWidth( widthInPixels );
 
  496   fillLayer->setAngle( angleCW );
 
  498   fillLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  500   layers.append( fillLayer.release() );
 
  502   const QVariantMap outlineData = symbolData.value( QStringLiteral( 
"outline" ) ).toMap();
 
  503   QColor lineColor = 
convertColor( outlineData.value( QStringLiteral( 
"color" ) ) );
 
  504   Qt::PenStyle penStyle = 
convertLineStyle( outlineData.value( QStringLiteral( 
"style" ) ).toString() );
 
  505   double penWidthInPoints = outlineData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  507   std::unique_ptr< QgsSimpleLineSymbolLayer > lineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( lineColor, penWidthInPoints, penStyle );
 
  509   layers.append( lineLayer.release() );
 
  511   std::unique_ptr< QgsFillSymbol > symbol = std::make_unique< QgsFillSymbol >( layers );
 
  517   if ( style == QLatin1String( 
"esriSMSCircle" ) )
 
  519   else if ( style == QLatin1String( 
"esriSMSCross" ) )
 
  521   else if ( style == QLatin1String( 
"esriSMSDiamond" ) )
 
  523   else if ( style == QLatin1String( 
"esriSMSSquare" ) )
 
  525   else if ( style == QLatin1String( 
"esriSMSX" ) )
 
  527   else if ( style == QLatin1String( 
"esriSMSTriangle" ) )
 
  533 std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriMarkerSymbolJson( 
const QVariantMap &symbolData )
 
  535   QColor fillColor = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  537   const double sizeInPoints = symbolData.value( QStringLiteral( 
"size" ) ).toDouble( &ok );
 
  540   const double angleCCW = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble( &ok );
 
  547   const double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  548   const double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  550   const QVariantMap outlineData = symbolData.value( QStringLiteral( 
"outline" ) ).toMap();
 
  551   QColor lineColor = 
convertColor( outlineData.value( QStringLiteral( 
"color" ) ) );
 
  552   Qt::PenStyle penStyle = 
convertLineStyle( outlineData.value( QStringLiteral( 
"style" ) ).toString() );
 
  553   double penWidthInPoints = outlineData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  556   std::unique_ptr< QgsSimpleMarkerSymbolLayer > markerLayer = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, sizeInPoints, angleCW, 
Qgis::ScaleMethod::ScaleArea, fillColor, lineColor );
 
  559   markerLayer->setStrokeStyle( penStyle );
 
  560   markerLayer->setStrokeWidth( penWidthInPoints );
 
  561   markerLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  563   layers.append( markerLayer.release() );
 
  565   std::unique_ptr< QgsMarkerSymbol > symbol = std::make_unique< QgsMarkerSymbol >( layers );
 
  569 std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriPictureMarkerSymbolJson( 
const QVariantMap &symbolData )
 
  572   const double widthInPixels = symbolData.value( QStringLiteral( 
"width" ) ).toInt( &ok );
 
  575   const double heightInPixels = symbolData.value( QStringLiteral( 
"height" ) ).toInt( &ok );
 
  579   const double angleCCW = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble( &ok );
 
  584   const double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  585   const double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  589   QString symbolPath( symbolData.value( QStringLiteral( 
"imageData" ) ).toString() );
 
  590   symbolPath.prepend( QLatin1String( 
"base64:" ) );
 
  593   std::unique_ptr< QgsRasterMarkerSymbolLayer > markerLayer = std::make_unique< QgsRasterMarkerSymbolLayer >( symbolPath, widthInPixels, angleCW, 
Qgis::ScaleMethod::ScaleArea );
 
  597   if ( !
qgsDoubleNear( 
static_cast< double >( heightInPixels ) / widthInPixels, markerLayer->defaultAspectRatio() ) )
 
  598     markerLayer->setFixedAspectRatio( 
static_cast< double >( heightInPixels ) / widthInPixels );
 
  600   markerLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  602   layers.append( markerLayer.release() );
 
  604   std::unique_ptr< QgsMarkerSymbol > symbol = std::make_unique< QgsMarkerSymbol >( layers );
 
  610   if ( labelingData.empty() )
 
  617   for ( 
const QVariant &lbl : labelingData )
 
  619     const QVariantMap labeling = lbl.toMap();
 
  624     const QString placement = labeling.value( QStringLiteral( 
"labelPlacement" ) ).toString();
 
  625     if ( placement == QLatin1String( 
"esriServerPointLabelPlacementAboveCenter" ) )
 
  630     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementBelowCenter" ) )
 
  635     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementCenterCenter" ) )
 
  640     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementAboveLeft" ) )
 
  645     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementBelowLeft" ) )
 
  650     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementCenterLeft" ) )
 
  655     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementAboveRight" ) )
 
  660     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementBelowRight" ) )
 
  665     else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementCenterRight" ) )
 
  670     else if ( placement == QLatin1String( 
"esriServerLinePlacementAboveAfter" ) ||
 
  671               placement == QLatin1String( 
"esriServerLinePlacementAboveStart" ) ||
 
  672               placement == QLatin1String( 
"esriServerLinePlacementAboveAlong" ) )
 
  677     else if ( placement == QLatin1String( 
"esriServerLinePlacementBelowAfter" ) ||
 
  678               placement == QLatin1String( 
"esriServerLinePlacementBelowStart" ) ||
 
  679               placement == QLatin1String( 
"esriServerLinePlacementBelowAlong" ) )
 
  684     else if ( placement == QLatin1String( 
"esriServerLinePlacementCenterAfter" ) ||
 
  685               placement == QLatin1String( 
"esriServerLinePlacementCenterStart" ) ||
 
  686               placement == QLatin1String( 
"esriServerLinePlacementCenterAlong" ) )
 
  691     else if ( placement == QLatin1String( 
"esriServerPolygonPlacementAlwaysHorizontal" ) )
 
  696     const double minScale = labeling.value( QStringLiteral( 
"minScale" ) ).toDouble();
 
  697     const double maxScale = labeling.value( QStringLiteral( 
"maxScale" ) ).toDouble();
 
  699     QVariantMap symbol = labeling.value( QStringLiteral( 
"symbol" ) ).toMap();
 
  701     const double haloSize = symbol.value( QStringLiteral( 
"haloSize" ) ).toDouble();
 
  712     const QString fontFamily = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"family" ) ).toString();
 
  713     const QString fontStyle = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"style" ) ).toString();
 
  714     const QString fontWeight = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"weight" ) ).toString();
 
  715     const int fontSize = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"size" ) ).toInt();
 
  716     QFont font( fontFamily, fontSize );
 
  717     font.setStyleName( fontStyle );
 
  718     font.setWeight( fontWeight == QLatin1String( 
"bold" ) ? QFont::Bold : QFont::Normal );
 
  726     QString where = labeling.value( QStringLiteral( 
"where" ) ).toString();
 
  745   const QString type = rendererData.value( QStringLiteral( 
"type" ) ).toString();
 
  746   if ( type == QLatin1String( 
"simple" ) )
 
  748     const QVariantMap symbolProps = rendererData.value( QStringLiteral( 
"symbol" ) ).toMap();
 
  749     std::unique_ptr< QgsSymbol > symbol( 
convertSymbol( symbolProps ) );
 
  755   else if ( type == QLatin1String( 
"uniqueValue" ) )
 
  757     const QString field1 = rendererData.value( QStringLiteral( 
"field1" ) ).toString();
 
  758     const QString field2 = rendererData.value( QStringLiteral( 
"field2" ) ).toString();
 
  759     const QString field3 = rendererData.value( QStringLiteral( 
"field3" ) ).toString();
 
  761     if ( !field2.isEmpty() || !field3.isEmpty() )
 
  763       const QString delimiter = rendererData.value( QStringLiteral( 
"fieldDelimiter" ) ).toString();
 
  764       if ( !field3.isEmpty() )
 
  766         attribute = QStringLiteral( 
"concat(\"%1\",'%2',\"%3\",'%4',\"%5\")" ).arg( field1, delimiter, field2, delimiter, field3 );
 
  770         attribute = QStringLiteral( 
"concat(\"%1\",'%2',\"%3\")" ).arg( field1, delimiter, field2 );
 
  778     const QVariantList categories = rendererData.value( QStringLiteral( 
"uniqueValueInfos" ) ).toList();
 
  780     for ( 
const QVariant &category : categories )
 
  782       const QVariantMap categoryData = category.toMap();
 
  783       const QString value = categoryData.value( QStringLiteral( 
"value" ) ).toString();
 
  784       const QString label = categoryData.value( QStringLiteral( 
"label" ) ).toString();
 
  792     std::unique_ptr< QgsSymbol > defaultSymbol( 
convertSymbol( rendererData.value( QStringLiteral( 
"defaultSymbol" ) ).toMap() ) );
 
  795       categoryList.append( 
QgsRendererCategory( QVariant(), defaultSymbol.release(), rendererData.value( QStringLiteral( 
"defaultLabel" ) ).toString() ) );
 
  798     if ( categoryList.empty() )
 
  803   else if ( type == QLatin1String( 
"classBreaks" ) )
 
  808   else if ( type == QLatin1String( 
"heatmap" ) )
 
  813   else if ( type == QLatin1String( 
"vectorField" ) )
 
  823   QString expression = string;
 
  826   expression = expression.replace( QRegularExpression( 
"(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)(\\s|^)CONCAT(\\s|$)" ), QStringLiteral( 
"\\4||\\5" ) );
 
  827   expression = expression.replace( QRegularExpression( 
"(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)(\\s|^)NEWLINE(\\s|$)" ), QStringLiteral( 
"\\4'\\n'\\5" ) );
 
  830   expression = expression.replace( QRegularExpression( 
"\"(.*?(?<!\\\\))\"" ), QStringLiteral( 
"'\\1'" ) );
 
  831   expression = expression.replace( QRegularExpression( 
"\\\\\"" ), QStringLiteral( 
"\"" ) );
 
  834   expression = expression.replace( QRegularExpression( 
"\\[([^]]*)\\]" ), QStringLiteral( 
"\"\\1\"" ) );
 
  841   const QVariantList colorParts = colorData.toList();
 
  842   if ( colorParts.count() < 4 )
 
  845   int red = colorParts.at( 0 ).toInt();
 
  846   int green = colorParts.at( 1 ).toInt();
 
  847   int blue = colorParts.at( 2 ).toInt();
 
  848   int alpha = colorParts.at( 3 ).toInt();
 
  849   return QColor( red, green, blue, alpha );
 
  854   if ( style == QLatin1String( 
"esriSLSSolid" ) )
 
  855     return Qt::SolidLine;
 
  856   else if ( style == QLatin1String( 
"esriSLSDash" ) )
 
  858   else if ( style == QLatin1String( 
"esriSLSDashDot" ) )
 
  859     return Qt::DashDotLine;
 
  860   else if ( style == QLatin1String( 
"esriSLSDashDotDot" ) )
 
  861     return Qt::DashDotDotLine;
 
  862   else if ( style == QLatin1String( 
"esriSLSDot" ) )
 
  864   else if ( style == QLatin1String( 
"esriSLSNull" ) )
 
  867     return Qt::SolidLine;
 
  872   if ( style == QLatin1String( 
"esriSFSBackwardDiagonal" ) )
 
  873     return Qt::BDiagPattern;
 
  874   else if ( style == QLatin1String( 
"esriSFSCross" ) )
 
  875     return Qt::CrossPattern;
 
  876   else if ( style == QLatin1String( 
"esriSFSDiagonalCross" ) )
 
  877     return Qt::DiagCrossPattern;
 
  878   else if ( style == QLatin1String( 
"esriSFSForwardDiagonal" ) )
 
  879     return Qt::FDiagPattern;
 
  880   else if ( style == QLatin1String( 
"esriSFSHorizontal" ) )
 
  881     return Qt::HorPattern;
 
  882   else if ( style == QLatin1String( 
"esriSFSNull" ) )
 
  884   else if ( style == QLatin1String( 
"esriSFSSolid" ) )
 
  885     return Qt::SolidPattern;
 
  886   else if ( style == QLatin1String( 
"esriSFSVertical" ) )
 
  887     return Qt::VerPattern;
 
  889     return Qt::SolidPattern;
 
  894   if ( value.isNull() )
 
  897   QDateTime dt = QDateTime::fromMSecsSinceEpoch( value.toLongLong( &ok ) );
 
  900     QgsDebugMsg( QStringLiteral( 
"Invalid value %1 for datetime" ).arg( value.toString() ) );
 
@ ScaleArea
Calculate scale by the area.
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 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.
Shape
Marker symbol shapes.
@ Cross2
Rotated cross (lines only), "x" shape.
@ Cross
Cross (lines only)
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