17#include "moc_qgsarcgisrestutils.cpp" 
   49#include <QRegularExpression> 
   61  if ( esriFieldType == QLatin1String( 
"esriFieldTypeInteger" ) )
 
   62    return QMetaType::Type::LongLong;
 
   63  if ( esriFieldType == QLatin1String( 
"esriFieldTypeSmallInteger" ) )
 
   64    return QMetaType::Type::Int;
 
   65  if ( esriFieldType == QLatin1String( 
"esriFieldTypeDouble" ) )
 
   66    return QMetaType::Type::Double;
 
   67  if ( esriFieldType == QLatin1String( 
"esriFieldTypeSingle" ) )
 
   68    return QMetaType::Type::Double;
 
   69  if ( esriFieldType == QLatin1String( 
"esriFieldTypeString" ) )
 
   70    return QMetaType::Type::QString;
 
   71  if ( esriFieldType == QLatin1String( 
"esriFieldTypeDate" ) )
 
   72    return QMetaType::Type::QDateTime;
 
   73  if ( esriFieldType == QLatin1String( 
"esriFieldTypeGeometry" ) )
 
   74    return QMetaType::Type::UnknownType; 
 
   75  if ( esriFieldType == QLatin1String( 
"esriFieldTypeOID" ) )
 
   76    return QMetaType::Type::LongLong;
 
   77  if ( esriFieldType == QLatin1String( 
"esriFieldTypeBlob" ) )
 
   78    return QMetaType::Type::QByteArray;
 
   79  if ( esriFieldType == QLatin1String( 
"esriFieldTypeGlobalID" ) )
 
   80    return QMetaType::Type::QString;
 
   81  if ( esriFieldType == QLatin1String( 
"esriFieldTypeRaster" ) )
 
   82    return QMetaType::Type::QByteArray;
 
   83  if ( esriFieldType == QLatin1String( 
"esriFieldTypeGUID" ) )
 
   84    return QMetaType::Type::QString;
 
   85  if ( esriFieldType == QLatin1String( 
"esriFieldTypeXML" ) )
 
   86    return QMetaType::Type::QString;
 
   87  return QMetaType::Type::UnknownType;
 
 
   93  if ( esriGeometryType == QLatin1String( 
"esriGeometryNull" ) )
 
   95  else if ( esriGeometryType == QLatin1String( 
"esriGeometryPoint" ) )
 
   97  else if ( esriGeometryType == QLatin1String( 
"esriGeometryMultipoint" ) )
 
   99  else if ( esriGeometryType == QLatin1String( 
"esriGeometryPolyline" ) )
 
  101  else if ( esriGeometryType == QLatin1String( 
"esriGeometryPolygon" ) )
 
  103  else if ( esriGeometryType == QLatin1String( 
"esriGeometryEnvelope" ) )
 
 
  123std::unique_ptr< QgsPoint > QgsArcGisRestUtils::convertPoint( 
const QVariantList &coordList, 
Qgis::WkbType pointType )
 
  125  int nCoords = coordList.size();
 
  128  bool xok = 
false, yok = 
false;
 
  129  const double x = coordList[0].toDouble( &xok );
 
  130  const double y = coordList[1].toDouble( &yok );
 
  134  const double z = hasZ && nCoords >= 3 ? coordList[2].toDouble() : std::numeric_limits< double >::quiet_NaN();
 
  137  const double m = 
QgsWkbTypes::hasM( pointType ) && ( ( hasZ && nCoords >= 4 ) || ( !hasZ && nCoords >= 3 ) ) ? coordList[ hasZ ? 3 : 2].toDouble() : std::numeric_limits< double >::quiet_NaN();
 
  138  return std::make_unique< QgsPoint >( pointType, x, y, z, m );
 
  141std::unique_ptr< QgsCircularString > QgsArcGisRestUtils::convertCircularString( 
const QVariantMap &curveData, 
Qgis::WkbType pointType, 
const QgsPoint &startPoint )
 
  143  const QVariantList coordsList = curveData[QStringLiteral( 
"c" )].toList();
 
  144  if ( coordsList.isEmpty() )
 
  146  const int coordsListSize = coordsList.size();
 
  148  QVector<QgsPoint> points;
 
  149  points.reserve( coordsListSize + 1 );
 
  150  points.append( startPoint );
 
  152  for ( 
int i = 0; i < coordsListSize - 1; )
 
  156    std::unique_ptr< QgsPoint > endPoint( convertPoint( coordsList.at( i ).toList(), pointType ) );
 
  160    std::unique_ptr< QgsPoint > interiorPoint( convertPoint( coordsList.at( i ).toList(), pointType ) );
 
  161    if ( !interiorPoint )
 
  164    points << *interiorPoint;
 
  167  auto curve = std::make_unique< QgsCircularString> ();
 
  168  curve->setPoints( points );
 
  172std::unique_ptr< QgsCompoundCurve > QgsArcGisRestUtils::convertCompoundCurve( 
const QVariantList &curvesList, 
Qgis::WkbType pointType )
 
  175  auto compoundCurve = std::make_unique< QgsCompoundCurve >();
 
  177  QVector< double > lineX;
 
  178  QVector< double > lineY;
 
  179  QVector< double > lineZ;
 
  180  QVector< double > lineM;
 
  181  int maxCurveListSize = curvesList.size();
 
  182  lineX.resize( maxCurveListSize );
 
  183  lineY.resize( maxCurveListSize );
 
  187    lineZ.resize( maxCurveListSize );
 
  190    lineM.resize( maxCurveListSize );
 
  192  double *outLineX = lineX.data();
 
  193  double *outLineY = lineY.data();
 
  194  double *outLineZ = lineZ.data();
 
  195  double *outLineM = lineM.data();
 
  196  int actualLineSize = 0;
 
  201  int curveListIndex = 0;
 
  202  for ( 
const QVariant &curveData : curvesList )
 
  204    if ( curveData.userType() == QMetaType::Type::QVariantList )
 
  206      const QVariantList coordList = curveData.toList();
 
  207      const int nCoords = coordList.size();
 
  211      const double x = coordList[0].toDouble( &xok );
 
  212      const double y = coordList[1].toDouble( &yok );
 
  221        *outLineZ++ = nCoords >= 3 ? coordList[2].toDouble() : std::numeric_limits< double >::quiet_NaN();
 
  227        *outLineM++ = ( ( hasZ && nCoords >= 4 ) || ( !hasZ && nCoords >= 3 ) ) ? coordList[ hasZ ? 3 : 2].toDouble() : std::numeric_limits< double >::quiet_NaN();
 
  230    else if ( curveData.userType() == QMetaType::Type::QVariantMap )
 
  234      if ( actualLineSize > 0 )
 
  236        lastLineStringPoint = 
QgsPoint( lineX.at( actualLineSize - 1 ),
 
  237                                        lineY.at( actualLineSize - 1 ),
 
  238                                        hasZ ? lineZ.at( actualLineSize - 1 ) : std::numeric_limits< double >::quiet_NaN(),
 
  239                                        hasM ? lineM.at( actualLineSize - 1 ) : std::numeric_limits< double >::quiet_NaN() );
 
  241      std::unique_ptr< QgsCircularString > circularString( convertCircularString( curveData.toMap(), pointType, lastLineStringPoint ) );
 
  242      if ( !circularString )
 
  247      if ( actualLineSize > 0 )
 
  249        lineX.resize( actualLineSize );
 
  250        lineY.resize( actualLineSize );
 
  252          lineZ.resize( actualLineSize );
 
  254          lineM.resize( actualLineSize );
 
  256        compoundCurve->addCurve( 
new QgsLineString( lineX, lineY, lineZ, lineM ) );
 
  257        lineX.resize( maxCurveListSize - curveListIndex );
 
  258        lineY.resize( maxCurveListSize - curveListIndex );
 
  260          lineZ.resize( maxCurveListSize - curveListIndex );
 
  262          lineM.resize( maxCurveListSize - curveListIndex );
 
  263        outLineX = lineX.data();
 
  264        outLineY = lineY.data();
 
  265        outLineZ = lineZ.data();
 
  266        outLineM = lineM.data();
 
  270      if ( compoundCurve->curveAt( compoundCurve->nCurves() - 1 )->nCoordinates() < 2 )
 
  271        compoundCurve->removeCurve( compoundCurve->nCurves() - 1 );
 
  273      const QgsPoint endPointCircularString = circularString->endPoint();
 
  274      compoundCurve->addCurve( circularString.release() );
 
  278      *outLineX++ = endPointCircularString.
x();
 
  279      *outLineY++ = endPointCircularString.
y();
 
  281        *outLineZ++ = endPointCircularString.
z();
 
  283        *outLineM++ = endPointCircularString.
m();
 
  288  if ( actualLineSize == 1 && compoundCurve->nCurves() > 0 )
 
  290    const QgsCurve *finalCurve = compoundCurve->curveAt( compoundCurve->nCurves() - 1 );
 
  294         && ( !hasZ || 
qgsDoubleNear( finalCurveEndPoint.
z(), lineZ.at( 0 ) ) )
 
  295         && ( !hasM || 
qgsDoubleNear( finalCurveEndPoint.
m(), lineM.at( 0 ) ) ) )
 
  301  if ( actualLineSize > 0 )
 
  303    lineX.resize( actualLineSize );
 
  304    lineY.resize( actualLineSize );
 
  306      lineZ.resize( actualLineSize );
 
  308      lineM.resize( actualLineSize );
 
  309    compoundCurve->addCurve( 
new QgsLineString( lineX, lineY, lineZ, lineM ) );
 
  312  return compoundCurve;
 
  315std::unique_ptr< QgsPoint > QgsArcGisRestUtils::convertGeometryPoint( 
const QVariantMap &geometryData, 
Qgis::WkbType pointType )
 
  318  bool xok = 
false, yok = 
false;
 
  319  double x = geometryData[QStringLiteral( 
"x" )].toDouble( &xok );
 
  320  double y = geometryData[QStringLiteral( 
"y" )].toDouble( &yok );
 
  323  double z = geometryData[QStringLiteral( 
"z" )].toDouble();
 
  324  double m = geometryData[QStringLiteral( 
"m" )].toDouble();
 
  325  return std::make_unique< QgsPoint >( pointType, x, y, z, m );
 
  328std::unique_ptr< QgsMultiPoint > QgsArcGisRestUtils::convertMultiPoint( 
const QVariantMap &geometryData, 
Qgis::WkbType pointType )
 
  331  const QVariantList coordsList = geometryData[QStringLiteral( 
"points" )].toList();
 
  333  auto multiPoint = std::make_unique< QgsMultiPoint >();
 
  334  multiPoint->reserve( coordsList.size() );
 
  335  for ( 
const QVariant &coordData : coordsList )
 
  337    const QVariantList coordList = coordData.toList();
 
  338    std::unique_ptr< QgsPoint > p = convertPoint( coordList, pointType );
 
  343    multiPoint->addGeometry( p.release() );
 
  348  std::unique_ptr< QgsPoint > p = convertGeometryPoint( geometryData, pointType );
 
  350    multiPoint->addGeometry( p.release() );
 
  352  if ( multiPoint->numGeometries() == 0 )
 
  360std::unique_ptr< QgsMultiCurve > QgsArcGisRestUtils::convertGeometryPolyline( 
const QVariantMap &geometryData, 
Qgis::WkbType pointType )
 
  363  QVariantList pathsList;
 
  364  if ( geometryData[QStringLiteral( 
"paths" )].isValid() )
 
  365    pathsList = geometryData[QStringLiteral( 
"paths" )].toList();
 
  366  else if ( geometryData[QStringLiteral( 
"curvePaths" )].isValid() )
 
  367    pathsList = geometryData[QStringLiteral( 
"curvePaths" )].toList();
 
  368  if ( pathsList.isEmpty() )
 
  370  auto multiCurve = std::make_unique< QgsMultiCurve >();
 
  371  multiCurve->reserve( pathsList.size() );
 
  372  for ( 
const QVariant &pathData : std::as_const( pathsList ) )
 
  374    std::unique_ptr< QgsCompoundCurve > curve = convertCompoundCurve( pathData.toList(), pointType );
 
  379    multiCurve->addGeometry( curve.release() );
 
  384std::unique_ptr< QgsMultiSurface > QgsArcGisRestUtils::convertGeometryPolygon( 
const QVariantMap &geometryData, 
Qgis::WkbType pointType )
 
  387  QVariantList ringsList;
 
  388  if ( geometryData[QStringLiteral( 
"rings" )].isValid() )
 
  389    ringsList = geometryData[QStringLiteral( 
"rings" )].toList();
 
  390  else if ( geometryData[QStringLiteral( 
"ringPaths" )].isValid() )
 
  391    ringsList = geometryData[QStringLiteral( 
"ringPaths" )].toList();
 
  392  if ( ringsList.isEmpty() )
 
  395  QList< QgsCompoundCurve * > curves;
 
  396  for ( 
int i = 0, n = ringsList.size(); i < n; ++i )
 
  398    std::unique_ptr< QgsCompoundCurve > curve = convertCompoundCurve( ringsList[i].toList(), pointType );
 
  403    curves.append( curve.release() );
 
  405  if ( curves.count() == 0 )
 
  408  auto result = std::make_unique< QgsMultiSurface >();
 
  409  if ( curves.count() == 1 )
 
  412    auto newPolygon = std::make_unique< QgsCurvePolygon >();
 
  413    newPolygon->setExteriorRing( curves.takeAt( 0 ) );
 
  414    result->addGeometry( newPolygon.release() );
 
  418  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 ); } );
 
  419  result->reserve( curves.size() );
 
  420  while ( !curves.isEmpty() )
 
  426    engine->prepareGeometry();
 
  428    QMutableListIterator< QgsCompoundCurve * > it( curves );
 
  429    while ( it.hasNext() )
 
  436        if ( engine->contains( &point ) )
 
  441          engine->prepareGeometry();
 
  445    result->addGeometry( newPolygon );
 
  447  if ( result->numGeometries() == 0 )
 
  453std::unique_ptr< QgsPolygon > QgsArcGisRestUtils::convertEnvelope( 
const QVariantMap &geometryData )
 
  456  bool xminOk = 
false, yminOk = 
false, xmaxOk = 
false, ymaxOk = 
false;
 
  457  double xmin = geometryData[QStringLiteral( 
"xmin" )].toDouble( &xminOk );
 
  458  double ymin = geometryData[QStringLiteral( 
"ymin" )].toDouble( &yminOk );
 
  459  double xmax = geometryData[QStringLiteral( 
"xmax" )].toDouble( &xmaxOk );
 
  460  double ymax = geometryData[QStringLiteral( 
"ymax" )].toDouble( &ymaxOk );
 
  461  if ( !xminOk || !yminOk || !xmaxOk || !ymaxOk )
 
  463  auto ext = std::make_unique< QgsLineString> ();
 
  464  ext->addVertex( 
QgsPoint( xmin, ymin ) );
 
  465  ext->addVertex( 
QgsPoint( xmax, ymin ) );
 
  466  ext->addVertex( 
QgsPoint( xmax, ymax ) );
 
  467  ext->addVertex( 
QgsPoint( xmin, ymax ) );
 
  468  ext->addVertex( 
QgsPoint( xmin, ymin ) );
 
  469  auto poly = std::make_unique< QgsPolygon >();
 
  470  poly->setExteriorRing( ext.release() );
 
  483  if ( esriGeometryType == QLatin1String( 
"esriGeometryNull" ) )
 
  485  else if ( esriGeometryType == QLatin1String( 
"esriGeometryPoint" ) )
 
  486    return convertGeometryPoint( geometryData, pointType ).release();
 
  487  else if ( esriGeometryType == QLatin1String( 
"esriGeometryMultipoint" ) )
 
  488    return convertMultiPoint( geometryData, pointType ).release();
 
  489  else if ( esriGeometryType == QLatin1String( 
"esriGeometryPolyline" ) )
 
  490    return convertGeometryPolyline( geometryData, pointType ).release();
 
  491  else if ( esriGeometryType == QLatin1String( 
"esriGeometryPolygon" ) )
 
  492    return convertGeometryPolygon( geometryData, pointType ).release();
 
  493  else if ( esriGeometryType == QLatin1String( 
"esriGeometryEnvelope" ) )
 
  494    return convertEnvelope( geometryData ).release();
 
 
  517  QString spatialReference = spatialReferenceMap[QStringLiteral( 
"latestWkid" )].toString();
 
  518  if ( spatialReference.isEmpty() )
 
  519    spatialReference = spatialReferenceMap[QStringLiteral( 
"wkid" )].toString();
 
  522  if ( !spatialReference.isEmpty() )
 
  531  else if ( !spatialReferenceMap[QStringLiteral( 
"wkt" )].toString().isEmpty() )
 
  534    crs.
createFromWkt( spatialReferenceMap[QStringLiteral( 
"wkt" )].toString() );
 
 
  549  const QString type = symbolData.value( QStringLiteral( 
"type" ) ).toString();
 
  550  if ( type == QLatin1String( 
"esriSMS" ) )
 
  553    return parseEsriMarkerSymbolJson( symbolData ).release();
 
  555  else if ( type == QLatin1String( 
"esriSLS" ) )
 
  558    return parseEsriLineSymbolJson( symbolData ).release();
 
  560  else if ( type == QLatin1String( 
"esriSFS" ) )
 
  563    return parseEsriFillSymbolJson( symbolData ).release();
 
  565  else if ( type == QLatin1String( 
"esriPFS" ) )
 
  567    return parseEsriPictureFillSymbolJson( symbolData ).release();
 
  569  else if ( type == QLatin1String( 
"esriPMS" ) )
 
  572    return parseEsriPictureMarkerSymbolJson( symbolData ).release();
 
  574  else if ( type == QLatin1String( 
"esriTS" ) )
 
  576    return parseEsriTextMarkerSymbolJson( symbolData ).release();
 
 
  581std::unique_ptr<QgsLineSymbol> QgsArcGisRestUtils::parseEsriLineSymbolJson( 
const QVariantMap &symbolData )
 
  583  QColor lineColor = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  584  if ( !lineColor.isValid() )
 
  588  double widthInPoints = symbolData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  593  Qt::PenStyle penStyle = 
convertLineStyle( symbolData.value( QStringLiteral( 
"style" ) ).toString() );
 
  594  auto lineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( lineColor, widthInPoints, penStyle );
 
  596  layers.append( lineLayer.release() );
 
  598  auto symbol = std::make_unique< QgsLineSymbol >( layers );
 
  602std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriFillSymbolJson( 
const QVariantMap &symbolData )
 
  604  QColor fillColor = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  605  Qt::BrushStyle brushStyle = 
convertFillStyle( symbolData.value( QStringLiteral( 
"style" ) ).toString() );
 
  607  const QVariantMap outlineData = symbolData.value( QStringLiteral( 
"outline" ) ).toMap();
 
  608  QColor lineColor = 
convertColor( outlineData.value( QStringLiteral( 
"color" ) ) );
 
  609  Qt::PenStyle penStyle = 
convertLineStyle( outlineData.value( QStringLiteral( 
"style" ) ).toString() );
 
  611  double penWidthInPoints = outlineData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  614  auto fillLayer = std::make_unique< QgsSimpleFillSymbolLayer >( fillColor, brushStyle, lineColor, penStyle, penWidthInPoints );
 
  616  layers.append( fillLayer.release() );
 
  618  auto symbol = std::make_unique< QgsFillSymbol >( layers );
 
  622std::unique_ptr<QgsFillSymbol> QgsArcGisRestUtils::parseEsriPictureFillSymbolJson( 
const QVariantMap &symbolData )
 
  626  double widthInPixels = symbolData.value( QStringLiteral( 
"width" ) ).toInt( &ok );
 
  630  const double xScale = symbolData.value( QStringLiteral( 
"xscale" ) ).toDouble( &ok );
 
  632    widthInPixels *= xScale;
 
  634  const double angleCCW = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble( &ok );
 
  639  const double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  640  const double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  642  QString symbolPath( symbolData.value( QStringLiteral( 
"imageData" ) ).toString() );
 
  643  symbolPath.prepend( QLatin1String( 
"base64:" ) );
 
  646  auto fillLayer = std::make_unique< QgsRasterFillSymbolLayer >( symbolPath );
 
  647  fillLayer->setWidth( widthInPixels );
 
  648  fillLayer->setAngle( angleCW );
 
  650  fillLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  652  layers.append( fillLayer.release() );
 
  654  const QVariantMap outlineData = symbolData.value( QStringLiteral( 
"outline" ) ).toMap();
 
  655  QColor lineColor = 
convertColor( outlineData.value( QStringLiteral( 
"color" ) ) );
 
  656  Qt::PenStyle penStyle = 
convertLineStyle( outlineData.value( QStringLiteral( 
"style" ) ).toString() );
 
  657  double penWidthInPoints = outlineData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  659  auto lineLayer = std::make_unique< QgsSimpleLineSymbolLayer >( lineColor, penWidthInPoints, penStyle );
 
  661  layers.append( lineLayer.release() );
 
  663  auto symbol = std::make_unique< QgsFillSymbol >( layers );
 
  667Qgis::MarkerShape QgsArcGisRestUtils::parseEsriMarkerShape( 
const QString &style )
 
  669  if ( style == QLatin1String( 
"esriSMSCircle" ) )
 
  671  else if ( style == QLatin1String( 
"esriSMSCross" ) )
 
  673  else if ( style == QLatin1String( 
"esriSMSDiamond" ) )
 
  675  else if ( style == QLatin1String( 
"esriSMSSquare" ) )
 
  677  else if ( style == QLatin1String( 
"esriSMSX" ) )
 
  679  else if ( style == QLatin1String( 
"esriSMSTriangle" ) )
 
  685std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriMarkerSymbolJson( 
const QVariantMap &symbolData )
 
  687  QColor fillColor = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  689  const double sizeInPoints = symbolData.value( QStringLiteral( 
"size" ) ).toDouble( &ok );
 
  692  const double angleCCW = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble( &ok );
 
  697  Qgis::MarkerShape shape = parseEsriMarkerShape( symbolData.value( QStringLiteral( 
"style" ) ).toString() );
 
  699  const double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  700  const double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  702  const QVariantMap outlineData = symbolData.value( QStringLiteral( 
"outline" ) ).toMap();
 
  703  QColor lineColor = 
convertColor( outlineData.value( QStringLiteral( 
"color" ) ) );
 
  704  Qt::PenStyle penStyle = 
convertLineStyle( outlineData.value( QStringLiteral( 
"style" ) ).toString() );
 
  705  double penWidthInPoints = outlineData.value( QStringLiteral( 
"width" ) ).toDouble( &ok );
 
  708  auto markerLayer = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, sizeInPoints, angleCW, 
Qgis::ScaleMethod::ScaleArea, fillColor, lineColor );
 
  711  markerLayer->setStrokeStyle( penStyle );
 
  712  markerLayer->setStrokeWidth( penWidthInPoints );
 
  713  markerLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  715  layers.append( markerLayer.release() );
 
  717  auto symbol = std::make_unique< QgsMarkerSymbol >( layers );
 
  721std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriPictureMarkerSymbolJson( 
const QVariantMap &symbolData )
 
  724  const double widthInPixels = symbolData.value( QStringLiteral( 
"width" ) ).toInt( &ok );
 
  727  const double heightInPixels = symbolData.value( QStringLiteral( 
"height" ) ).toInt( &ok );
 
  731  const double angleCCW = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble( &ok );
 
  736  const double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  737  const double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  741  QString symbolPath( symbolData.value( QStringLiteral( 
"imageData" ) ).toString() );
 
  742  symbolPath.prepend( QLatin1String( 
"base64:" ) );
 
  749  if ( !
qgsDoubleNear( 
static_cast< double >( heightInPixels ) / widthInPixels, markerLayer->defaultAspectRatio() ) )
 
  750    markerLayer->setFixedAspectRatio( 
static_cast< double >( heightInPixels ) / widthInPixels );
 
  752  markerLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  754  layers.append( markerLayer.release() );
 
  756  auto symbol = std::make_unique< QgsMarkerSymbol >( layers );
 
  760std::unique_ptr<QgsMarkerSymbol> QgsArcGisRestUtils::parseEsriTextMarkerSymbolJson( 
const QVariantMap &symbolData )
 
  764  const QString fontFamily = symbolData.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"family" ) ).toString();
 
  766  const QString chr = symbolData.value( QStringLiteral( 
"text" ) ).toString();
 
  768  const double pointSize = symbolData.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"size" ) ).toDouble();
 
  770  const QColor color = 
convertColor( symbolData.value( QStringLiteral( 
"color" ) ) );
 
  772  const double esriAngle = symbolData.value( QStringLiteral( 
"angle" ) ).toDouble();
 
  774  const double angle = 90.0 - esriAngle;
 
  776  auto markerLayer = std::make_unique< QgsFontMarkerSymbolLayer >( fontFamily, chr, pointSize, color, angle );
 
  778  QColor strokeColor = 
convertColor( symbolData.value( QStringLiteral( 
"borderLineColor" ) ) );
 
  779  markerLayer->setStrokeColor( strokeColor );
 
  781  double borderLineSize = symbolData.value( QStringLiteral( 
"borderLineSize" ) ).toDouble();
 
  782  markerLayer->setStrokeWidth( borderLineSize );
 
  784  const QString fontStyle = symbolData.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"style" ) ).toString();
 
  785  markerLayer->setFontStyle( fontStyle );
 
  787  double xOffset = symbolData.value( QStringLiteral( 
"xoffset" ) ).toDouble();
 
  788  double yOffset = symbolData.value( QStringLiteral( 
"yoffset" ) ).toDouble();
 
  790  markerLayer->setOffset( QPointF( xOffset, yOffset ) );
 
  799  QString horizontalAnchorPoint = symbolData.value( QStringLiteral( 
"horizontalAlignment" ) ).toString();
 
  800  QString verticalAnchorPoint = symbolData.value( QStringLiteral( 
"verticalAlignment" ) ).toString();
 
  802  if ( horizontalAnchorPoint == QString( 
"center" ) )
 
  806  else if ( horizontalAnchorPoint == QString( 
"left" ) )
 
  810  else if ( horizontalAnchorPoint == QString( 
"right" ) )
 
  815  if ( verticalAnchorPoint == QString( 
"center" ) )
 
  819  else if ( verticalAnchorPoint == QString( 
"top" ) )
 
  823  else if ( verticalAnchorPoint == QString( 
"bottom" ) )
 
  828  markerLayer->setHorizontalAnchorPoint( hAlign );
 
  829  markerLayer->setVerticalAnchorPoint( vAlign );
 
  831  layers.append( markerLayer.release() );
 
  833  auto symbol = std::make_unique< QgsMarkerSymbol >( layers );
 
  839  if ( labelingData.empty() )
 
  846  for ( 
const QVariant &lbl : labelingData )
 
  848    const QVariantMap labeling = lbl.toMap();
 
  853    const QString placement = labeling.value( QStringLiteral( 
"labelPlacement" ) ).toString();
 
  854    if ( placement == QLatin1String( 
"esriServerPointLabelPlacementAboveCenter" ) )
 
  859    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementBelowCenter" ) )
 
  864    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementCenterCenter" ) )
 
  869    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementAboveLeft" ) )
 
  874    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementBelowLeft" ) )
 
  879    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementCenterLeft" ) )
 
  884    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementAboveRight" ) )
 
  889    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementBelowRight" ) )
 
  894    else if ( placement == QLatin1String( 
"esriServerPointLabelPlacementCenterRight" ) )
 
  899    else if ( placement == QLatin1String( 
"esriServerLinePlacementAboveAfter" ) ||
 
  900              placement == QLatin1String( 
"esriServerLinePlacementAboveStart" ) ||
 
  901              placement == QLatin1String( 
"esriServerLinePlacementAboveAlong" ) )
 
  906    else if ( placement == QLatin1String( 
"esriServerLinePlacementBelowAfter" ) ||
 
  907              placement == QLatin1String( 
"esriServerLinePlacementBelowStart" ) ||
 
  908              placement == QLatin1String( 
"esriServerLinePlacementBelowAlong" ) )
 
  913    else if ( placement == QLatin1String( 
"esriServerLinePlacementCenterAfter" ) ||
 
  914              placement == QLatin1String( 
"esriServerLinePlacementCenterStart" ) ||
 
  915              placement == QLatin1String( 
"esriServerLinePlacementCenterAlong" ) )
 
  920    else if ( placement == QLatin1String( 
"esriServerPolygonPlacementAlwaysHorizontal" ) )
 
  925    const double minScale = labeling.value( QStringLiteral( 
"minScale" ) ).toDouble();
 
  926    const double maxScale = labeling.value( QStringLiteral( 
"maxScale" ) ).toDouble();
 
  928    QVariantMap symbol = labeling.value( QStringLiteral( 
"symbol" ) ).toMap();
 
  930    const double haloSize = symbol.value( QStringLiteral( 
"haloSize" ) ).toDouble();
 
  941    const QString fontFamily = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"family" ) ).toString();
 
  942    const QString fontStyle = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"style" ) ).toString();
 
  943    const QString fontWeight = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"weight" ) ).toString();
 
  944    const int fontSize = symbol.value( QStringLiteral( 
"font" ) ).toMap().value( QStringLiteral( 
"size" ) ).toInt();
 
  945    QFont font( fontFamily, fontSize );
 
  946    font.setStyleName( fontStyle );
 
  947    font.setWeight( fontWeight == QLatin1String( 
"bold" ) ? QFont::Bold : QFont::Normal );
 
  955    QString where = labeling.value( QStringLiteral( 
"where" ) ).toString();
 
 
  974  const QString type = rendererData.value( QStringLiteral( 
"type" ) ).toString();
 
  975  if ( type == QLatin1String( 
"simple" ) )
 
  977    const QVariantMap symbolProps = rendererData.value( QStringLiteral( 
"symbol" ) ).toMap();
 
  978    std::unique_ptr< QgsSymbol > symbol( 
convertSymbol( symbolProps ) );
 
  984  else if ( type == QLatin1String( 
"uniqueValue" ) )
 
  986    const QString field1 = rendererData.value( QStringLiteral( 
"field1" ) ).toString();
 
  987    const QString field2 = rendererData.value( QStringLiteral( 
"field2" ) ).toString();
 
  988    const QString field3 = rendererData.value( QStringLiteral( 
"field3" ) ).toString();
 
  990    if ( !field2.isEmpty() || !field3.isEmpty() )
 
  992      const QString delimiter = rendererData.value( QStringLiteral( 
"fieldDelimiter" ) ).toString();
 
  993      if ( !field3.isEmpty() )
 
  995        attribute = QStringLiteral( 
"concat(\"%1\",'%2',\"%3\",'%4',\"%5\")" ).arg( field1, delimiter, field2, delimiter, field3 );
 
  999        attribute = QStringLiteral( 
"concat(\"%1\",'%2',\"%3\")" ).arg( field1, delimiter, field2 );
 
 1007    const QVariantList categories = rendererData.value( QStringLiteral( 
"uniqueValueInfos" ) ).toList();
 
 1009    for ( 
const QVariant &category : categories )
 
 1011      const QVariantMap categoryData = category.toMap();
 
 1012      const QString value = categoryData.value( QStringLiteral( 
"value" ) ).toString();
 
 1013      const QString label = categoryData.value( QStringLiteral( 
"label" ) ).toString();
 
 1021    std::unique_ptr< QgsSymbol > defaultSymbol( 
convertSymbol( rendererData.value( QStringLiteral( 
"defaultSymbol" ) ).toMap() ) );
 
 1022    if ( defaultSymbol )
 
 1024      categoryList.append( 
QgsRendererCategory( QVariant(), defaultSymbol.release(), rendererData.value( QStringLiteral( 
"defaultLabel" ) ).toString() ) );
 
 1027    if ( categoryList.empty() )
 
 1032  else if ( type == QLatin1String( 
"classBreaks" ) )
 
 1034    const QString attrName = rendererData.value( QStringLiteral( 
"field" ) ).toString();
 
 1036    const QVariantList classBreakInfos = rendererData.value( QStringLiteral( 
"classBreakInfos" ) ).toList();
 
 1037    const QVariantMap authoringInfo = rendererData.value( QStringLiteral( 
"authoringInfo" ) ).toMap();
 
 1038    QVariantMap symbolData;
 
 1040    QString esriMode = authoringInfo.value( QStringLiteral( 
"classificationMethod" ) ).toString();
 
 1041    if ( esriMode.isEmpty() )
 
 1043      esriMode = rendererData.value( QStringLiteral( 
"classificationMethod" ) ).toString();
 
 1046    if ( !classBreakInfos.isEmpty() )
 
 1048      symbolData = classBreakInfos.at( 0 ).toMap().value( QStringLiteral( 
"symbol" ) ).toMap();
 
 1054    const double transparency = rendererData.value( QStringLiteral( 
"transparency" ) ).toDouble();
 
 1055    const double opacity = ( 100.0 - transparency ) / 100.0;
 
 1056    symbol->setOpacity( opacity );
 
 1058    const QVariantList visualVariablesData = rendererData.value( QStringLiteral( 
"visualVariables" ) ).toList();
 
 1060    for ( 
const QVariant &visualVariable : visualVariablesData )
 
 1062      const QVariantMap visualVariableData = visualVariable.toMap();
 
 1063      const QString variableType = visualVariableData.value( QStringLiteral( 
"type" ) ).toString();
 
 1064      if ( variableType == QLatin1String( 
"sizeInfo" ) )
 
 1068      else if ( variableType == QLatin1String( 
"colorInfo" ) )
 
 1070        const QVariantList stops = visualVariableData.value( QStringLiteral( 
"stops" ) ).toList();
 
 1071        if ( stops.size() < 2 )
 
 1076        const double minValue = stops.front().toMap().value( QStringLiteral( 
"value" ) ).toDouble( &ok );
 
 1079        const QColor minColor = 
convertColor( stops.front().toMap().value( QStringLiteral( 
"color" ) ) );
 
 1081        const double maxValue = stops.back().toMap().value( QStringLiteral( 
"value" ) ).toDouble( &ok );
 
 1084        const QColor maxColor = 
convertColor( stops.back().toMap().value( QStringLiteral( 
"color" ) ) );
 
 1087        for ( 
int i = 1; i < stops.size() - 1; ++i )
 
 1089          const QVariantMap stopData = stops.at( i ).toMap();
 
 1090          const double breakpoint = stopData.value( QStringLiteral( 
"value" ) ).toDouble();
 
 1091          const double scaledBreakpoint = ( breakpoint - minValue ) / ( maxValue - minValue );
 
 1092          const QColor fillColor = 
convertColor( stopData.value( QStringLiteral( 
"color" ) ) );
 
 1094          gradientStops.append( 
QgsGradientStop( scaledBreakpoint, fillColor ) );
 
 1097        auto colorRamp = std::make_unique< QgsGradientColorRamp >(
 
 1098                           minColor, maxColor, 
false, gradientStops
 
 1105        for ( 
int layer = 0; layer < symbol->symbolLayerCount(); ++layer )
 
 1110        auto singleSymbolRenderer = std::make_unique< QgsSingleSymbolRenderer >( symbol.release() );
 
 1112        return singleSymbolRenderer.release();
 
 1116        QgsDebugError( QStringLiteral( 
"ESRI visualVariable type %1 is not currently supported" ).arg( variableType ) );
 
 1120    double lastValue = rendererData.value( QStringLiteral( 
"minValue" ) ).toDouble();
 
 1122    auto graduatedRenderer = std::make_unique< QgsGraduatedSymbolRenderer >( attrName );
 
 1124    graduatedRenderer->setSourceSymbol( symbol.release() );
 
 1126    if ( esriMode == QLatin1String( 
"esriClassifyDefinedInterval" ) )
 
 1129      graduatedRenderer->setClassificationMethod( method );
 
 1131    else if ( esriMode == QLatin1String( 
"esriClassifyEqualInterval" ) )
 
 1134      graduatedRenderer->setClassificationMethod( method );
 
 1136    else if ( esriMode == QLatin1String( 
"esriClassifyGeometricalInterval" ) )
 
 1139      graduatedRenderer->setClassificationMethod( method );
 
 1141    else if ( esriMode == QLatin1String( 
"esriClassifyManual" ) )
 
 1144      graduatedRenderer->setClassificationMethod( method );
 
 1146    else if ( esriMode == QLatin1String( 
"esriClassifyNaturalBreaks" ) )
 
 1149      graduatedRenderer->setClassificationMethod( method );
 
 1151    else if ( esriMode == QLatin1String( 
"esriClassifyQuantile" ) )
 
 1154      graduatedRenderer->setClassificationMethod( method );
 
 1156    else if ( esriMode == QLatin1String( 
"esriClassifyStandardDeviation" ) )
 
 1159      graduatedRenderer->setClassificationMethod( method );
 
 1161    else if ( !esriMode.isEmpty() )
 
 1163      QgsDebugError( QStringLiteral( 
"ESRI classification mode %1 is not currently supported" ).arg( esriMode ) );
 
 1166    for ( 
const QVariant &classBreakInfo : classBreakInfos )
 
 1168      const QVariantMap symbolData = classBreakInfo.toMap().value( QStringLiteral( 
"symbol" ) ).toMap();
 
 1170      double classMaxValue = classBreakInfo.toMap().value( QStringLiteral( 
"classMaxValue" ) ).toDouble();
 
 1171      const QString label = classBreakInfo.toMap().value( QStringLiteral( 
"label" ) ).toString();
 
 1180      lastValue = classMaxValue;
 
 1181      graduatedRenderer->addClass( range );
 
 1184    return graduatedRenderer.release();
 
 1186  else if ( type == QLatin1String( 
"heatmap" ) )
 
 1191  else if ( type == QLatin1String( 
"vectorField" ) )
 
 
 1201  QString expression = string;
 
 1204  const thread_local QRegularExpression rx1 = QRegularExpression( QStringLiteral( 
"(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)(\\s|^)CONCAT(\\s|$)" ) );
 
 1205  expression = expression.replace( rx1, QStringLiteral( 
"\\4||\\5" ) );
 
 1207  const thread_local QRegularExpression rx2 = QRegularExpression( QStringLiteral( 
"(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)(\\s|^)NEWLINE(\\s|$)" ) );
 
 1208  expression = expression.replace( rx2, QStringLiteral( 
"\\4'\\n'\\5" ) );
 
 1211  const thread_local QRegularExpression rx3 = QRegularExpression( QStringLiteral( 
"\"(.*?(?<!\\\\))\"" ) );
 
 1212  expression = expression.replace( rx3, QStringLiteral( 
"'\\1'" ) );
 
 1213  const thread_local QRegularExpression rx4 = QRegularExpression( QStringLiteral( 
"\\\\\"" ) );
 
 1214  expression = expression.replace( rx4, QStringLiteral( 
"\"" ) );
 
 1217  const thread_local QRegularExpression rx5 = QRegularExpression( QStringLiteral( 
"\\[([^]]*)\\]" ) );
 
 1218  expression = expression.replace( rx5, QStringLiteral( 
"\"\\1\"" ) );
 
 
 1225  const QVariantList colorParts = colorData.toList();
 
 1226  if ( colorParts.count() < 4 )
 
 1229  int red = colorParts.at( 0 ).toInt();
 
 1230  int green = colorParts.at( 1 ).toInt();
 
 1231  int blue = colorParts.at( 2 ).toInt();
 
 1232  int alpha = colorParts.at( 3 ).toInt();
 
 1233  return QColor( red, green, blue, alpha );
 
 
 1238  if ( style == QLatin1String( 
"esriSLSSolid" ) )
 
 1239    return Qt::SolidLine;
 
 1240  else if ( style == QLatin1String( 
"esriSLSDash" ) )
 
 1241    return Qt::DashLine;
 
 1242  else if ( style == QLatin1String( 
"esriSLSDashDot" ) )
 
 1243    return Qt::DashDotLine;
 
 1244  else if ( style == QLatin1String( 
"esriSLSDashDotDot" ) )
 
 1245    return Qt::DashDotDotLine;
 
 1246  else if ( style == QLatin1String( 
"esriSLSDot" ) )
 
 1248  else if ( style == QLatin1String( 
"esriSLSNull" ) )
 
 1251    return Qt::SolidLine;
 
 
 1256  if ( style == QLatin1String( 
"esriSFSBackwardDiagonal" ) )
 
 1257    return Qt::BDiagPattern;
 
 1258  else if ( style == QLatin1String( 
"esriSFSCross" ) )
 
 1259    return Qt::CrossPattern;
 
 1260  else if ( style == QLatin1String( 
"esriSFSDiagonalCross" ) )
 
 1261    return Qt::DiagCrossPattern;
 
 1262  else if ( style == QLatin1String( 
"esriSFSForwardDiagonal" ) )
 
 1263    return Qt::FDiagPattern;
 
 1264  else if ( style == QLatin1String( 
"esriSFSHorizontal" ) )
 
 1265    return Qt::HorPattern;
 
 1266  else if ( style == QLatin1String( 
"esriSFSNull" ) )
 
 1268  else if ( style == QLatin1String( 
"esriSFSSolid" ) )
 
 1269    return Qt::SolidPattern;
 
 1270  else if ( style == QLatin1String( 
"esriSFSVertical" ) )
 
 1271    return Qt::VerPattern;
 
 1273    return Qt::SolidPattern;
 
 
 1281  QDateTime dt = QDateTime::fromMSecsSinceEpoch( value.toLongLong( &ok ) );
 
 1284    QgsDebugError( QStringLiteral( 
"Invalid value %1 for datetime" ).arg( value.toString() ) );
 
 
 1296  const QVariantMap coords = value.toMap();
 
 1301  const double xmin = coords.value( QStringLiteral( 
"xmin" ) ).toDouble( &ok );
 
 1304  const double ymin = coords.value( QStringLiteral( 
"ymin" ) ).toDouble( &ok );
 
 1307  const double xmax = coords.value( QStringLiteral( 
"xmax" ) ).toDouble( &ok );
 
 1310  const double ymax = coords.value( QStringLiteral( 
"ymax" ) ).toDouble( &ok );
 
 
 1322    return QVariantMap();
 
 1329      return QVariantMap();
 
 1332      res = pointToJson( qgsgeometry_cast< const QgsPoint * >( geom ) );
 
 1336      res = lineStringToJson( qgsgeometry_cast< const QgsLineString * >( geom ) );
 
 1341      res = curveToJson( qgsgeometry_cast< const QgsCurve * >( geom ) );
 
 1345      res = polygonToJson( qgsgeometry_cast< const QgsPolygon * >( geom ) );
 
 1349      res = multiPointToJson( qgsgeometry_cast< const QgsMultiPoint * >( geom ) );
 
 1353      res = multiLineStringToJson( qgsgeometry_cast< const QgsMultiLineString * >( geom ) );
 
 1357      res = multiCurveToJson( qgsgeometry_cast< const QgsMultiCurve * >( geom ) );
 
 1361      res = multiPolygonToJson( qgsgeometry_cast< const QgsMultiPolygon * >( geom ) );
 
 1365      res = curvePolygonToJson( qgsgeometry_cast< const QgsCurvePolygon * >( geom ) );
 
 1369      res = multiSurfaceToJson( qgsgeometry_cast< const QgsMultiSurface * >( geom ) );
 
 1373      return QVariantMap(); 
 
 1376      return QVariantMap(); 
 
 1379      return QVariantMap(); 
 
 1386    res.insert( QStringLiteral( 
"spatialReference" ), 
crsToJson( 
crs ) );
 
 
 1392QVariantMap QgsArcGisRestUtils::pointToJson( 
const QgsPoint *point )
 
 1396    data[QStringLiteral( 
"x" )] = QStringLiteral( 
"NaN" );
 
 1399    data[QStringLiteral( 
"x" )] = point->
x();
 
 1400    data[QStringLiteral( 
"y" )] = point->
y();
 
 1402    if ( point->
is3D() )
 
 1403      data[QStringLiteral( 
"z" )] = !std::isnan( point->
z() ) ? QVariant( point->
z() ) :  QVariant( QStringLiteral( 
"NaN" ) );
 
 1406      data[QStringLiteral( 
"m" )] = !std::isnan( point->
m() ) ? QVariant( point->
m() ) :  QVariant( QStringLiteral( 
"NaN" ) );
 
 1411QVariantMap QgsArcGisRestUtils::multiPointToJson( 
const QgsMultiPoint *multiPoint )
 
 1414  const bool hasZ = multiPoint->
is3D();
 
 1415  const bool hasM = multiPoint->
isMeasure();
 
 1416  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1417  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1419  QVariantList pointsList;
 
 1421  pointsList.reserve( size );
 
 1423  QVariantList pointList;
 
 1424  for ( 
int i = 0; i < size; ++i )
 
 1429    pointList.append( point->
x() );
 
 1430    pointList.append( point->
y() );
 
 1432      pointList.append( point->
z() );
 
 1433    if ( hasM && !std::isnan( point->
m() ) )
 
 1434      pointList.append( point->
m() );
 
 1436    pointsList.push_back( pointList );
 
 1439  data[QStringLiteral( 
"points" )] = pointsList;
 
 1443QVariantList QgsArcGisRestUtils::lineStringToJsonPath( 
const QgsLineString *line )
 
 1445  const bool hasZ = line->
is3D();
 
 1448  QVariantList pointsList;
 
 1450  pointsList.reserve( size );
 
 1452  QVariantList pointList;
 
 1453  const double *xData = line->
xData();
 
 1454  const double *yData = line->
yData();
 
 1455  const double *zData = hasZ ? line->
zData() : 
nullptr;
 
 1456  const double *mData = hasM ? line->
mData() : 
nullptr;
 
 1458  for ( 
int i = 0; i < size; ++i )
 
 1461    pointList.append( *xData++ );
 
 1462    pointList.append( *yData++ );
 
 1465      pointList.append( *zData++ );
 
 1467    if ( hasM && !std::isnan( *mData ) )
 
 1468      pointList.append( *mData );
 
 1472    pointsList.push_back( pointList );
 
 1477QVariantList QgsArcGisRestUtils::curveToJsonCurve( 
const QgsCurve *curve, 
bool includeStart )
 
 1479  const bool hasZ = curve->
is3D();
 
 1482  auto pointToList = [hasZ, hasM]( 
const QgsPoint & point ) -> QVariantList
 
 1484    QVariantList pointList;
 
 1486    pointList.append( point.
x() );
 
 1487    pointList.append( point.
y() );
 
 1490      pointList.append( point.
z() );
 
 1492    if ( hasM && !std::isnan( point.
m() ) )
 
 1493      pointList.append( point.
m() );
 
 1503      QVariantList part = lineStringToJsonPath( qgsgeometry_cast< const QgsLineString *>( curve ) );
 
 1504      if ( !part.isEmpty() && !includeStart )
 
 1512      const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString * >( curve );
 
 1513      if ( includeStart && !circularString->
isEmpty() )
 
 1515        res.push_back( pointToList( circularString->
startPoint() ) );
 
 1518      const int size = circularString->
numPoints();
 
 1519      for ( 
int i = 1; i + 1 < size; i += 2 )
 
 1522        QVariantMap curvePart;
 
 1523        QVariantList curveList;
 
 1524        curveList.push_back( pointToList( circularString->
pointN( i + 1 ) ) );
 
 1526        curveList.push_back( pointToList( circularString->
pointN( i ) ) );
 
 1528        curvePart.insert( QStringLiteral( 
"c" ), curveList );
 
 1529        res.push_back( curvePart );
 
 1536      const QgsCompoundCurve *compoundCurve = qgsgeometry_cast<const QgsCompoundCurve * >( curve );
 
 1538      const int size = compoundCurve->
nCurves();
 
 1539      for ( 
int i = 0; i < size; ++i )
 
 1542        res.append( curveToJsonCurve( subCurve, i == 0 ) );
 
 1553QVariantMap QgsArcGisRestUtils::lineStringToJson( 
const QgsLineString *line )
 
 1556  const bool hasZ = line->
is3D();
 
 1558  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1559  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1561  const QVariantList pointsList = lineStringToJsonPath( line );
 
 1563  QVariantList pointsData = QVariantList();
 
 1564  pointsData.push_back( pointsList );
 
 1565  data[QStringLiteral( 
"paths" )] = pointsData;
 
 1570QVariantMap QgsArcGisRestUtils::curveToJson( 
const QgsCurve *curve )
 
 1573  const bool hasZ = curve->
is3D();
 
 1575  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1576  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1578  const QVariantList curveList = curveToJsonCurve( curve, 
true );
 
 1580  QVariantList curveData = QVariantList();
 
 1581  curveData.push_back( curveList );
 
 1582  data[QStringLiteral( 
"curvePaths" )] = curveData;
 
 1587QVariantMap QgsArcGisRestUtils::multiLineStringToJson( 
const QgsMultiLineString *multiLine )
 
 1590  const bool hasZ = multiLine->
is3D();
 
 1591  const bool hasM = multiLine->
isMeasure();
 
 1592  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1593  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1597  paths.reserve( size );
 
 1598  for ( 
int i = 0; i < size; ++i )
 
 1601    paths.push_back( lineStringToJsonPath( line ) );
 
 1604  data[QStringLiteral( 
"paths" )] = paths;
 
 1608QVariantMap QgsArcGisRestUtils::multiCurveToJson( 
const QgsMultiCurve *multiCurve )
 
 1611  const bool hasZ = multiCurve->
is3D();
 
 1612  const bool hasM = multiCurve->
isMeasure();
 
 1613  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1614  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1618  paths.reserve( size );
 
 1619  for ( 
int i = 0; i < size; ++i )
 
 1622    paths.push_back( curveToJsonCurve( curve, 
true ) );
 
 1625  data[QStringLiteral( 
"curvePaths" )] = paths;
 
 1629QVariantList QgsArcGisRestUtils::polygonToJsonRings( 
const QgsPolygon *polygon )
 
 1633  rings.reserve( numInteriorRings + 1 );
 
 1641        rings.push_back( lineStringToJsonPath( exterior ) );
 
 1646        std::unique_ptr< QgsLineString > reversed( exterior->
reversed() );
 
 1647        rings.push_back( lineStringToJsonPath( reversed.get() ) );
 
 1655  for ( 
int i = 0; i < numInteriorRings; ++i )
 
 1662        rings.push_back( lineStringToJsonPath( ring ) );
 
 1667        std::unique_ptr< QgsLineString > reversed( ring->
reversed() );
 
 1668        rings.push_back( lineStringToJsonPath( reversed.get() ) );
 
 1678QVariantList QgsArcGisRestUtils::curvePolygonToJsonRings( 
const QgsCurvePolygon *polygon )
 
 1682  rings.reserve( numInteriorRings + 1 );
 
 1684  if ( 
const QgsCurve *exterior = qgsgeometry_cast< const QgsCurve * >( polygon->
exteriorRing() ) )
 
 1690        rings.push_back( curveToJsonCurve( exterior, 
true ) );
 
 1695        std::unique_ptr< QgsCurve > reversed( exterior->
reversed() );
 
 1696        rings.push_back( curveToJsonCurve( reversed.get(), 
true ) );
 
 1704  for ( 
int i = 0; i < numInteriorRings; ++i )
 
 1711        rings.push_back( curveToJsonCurve( ring, 
true ) );
 
 1716        std::unique_ptr< QgsCurve > reversed( ring->
reversed() );
 
 1717        rings.push_back( curveToJsonCurve( reversed.get(), 
true ) );
 
 1727QVariantMap QgsArcGisRestUtils::polygonToJson( 
const QgsPolygon *polygon )
 
 1730  const bool hasZ = polygon->
is3D();
 
 1732  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1733  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1734  data[QStringLiteral( 
"rings" )] = polygonToJsonRings( polygon );
 
 1738QVariantMap QgsArcGisRestUtils::curvePolygonToJson( 
const QgsCurvePolygon *polygon )
 
 1741  const bool hasZ = polygon->
is3D();
 
 1743  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1744  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1745  data[QStringLiteral( 
"curveRings" )] = curvePolygonToJsonRings( polygon );
 
 1749QVariantMap QgsArcGisRestUtils::multiPolygonToJson( 
const QgsMultiPolygon *multiPolygon )
 
 1752  const bool hasZ = multiPolygon->
is3D();
 
 1753  const bool hasM = multiPolygon->
isMeasure();
 
 1754  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1755  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1759  for ( 
int i = 0; i < size; ++i )
 
 1762    rings.append( polygonToJsonRings( polygon ) );
 
 1765  data[QStringLiteral( 
"rings" )] = rings;
 
 1769QVariantMap QgsArcGisRestUtils::multiSurfaceToJson( 
const QgsMultiSurface *multiSurface )
 
 1772  const bool hasZ = multiSurface->
is3D();
 
 1773  const bool hasM = multiSurface->
isMeasure();
 
 1774  data[QStringLiteral( 
"hasM" )] = hasM;
 
 1775  data[QStringLiteral( 
"hasZ" )] = hasZ;
 
 1779  for ( 
int i = 0; i < size; ++i )
 
 1785    rings.append( curvePolygonToJsonRings( polygon ) );
 
 1788  data[QStringLiteral( 
"curveRings" )] = rings;
 
 1799  if ( !authid.isEmpty() )
 
 1801    const thread_local QRegularExpression rxAuthid( QStringLiteral( 
"(\\w+):(\\d+)" ) );
 
 1802    const QRegularExpressionMatch match = rxAuthid.match( authid );
 
 1803    if ( match.hasMatch()
 
 1805           ( match.captured( 1 ).compare( QLatin1String( 
"EPSG" ), Qt::CaseInsensitive ) == 0 )
 
 1806           || ( match.captured( 1 ).compare( QLatin1String( 
"ESRI" ), Qt::CaseInsensitive ) == 0 )
 
 1810      const QString wkid = match.captured( 2 );
 
 1811      res.insert( QStringLiteral( 
"wkid" ), wkid );
 
 
 1830  QVariantMap attributes;
 
 1832  for ( 
const QgsField &field : fields )
 
 1834    QVariant value = feature.
attribute( field.name() );
 
 1835    if ( value.userType() == qMetaTypeId< QgsUnsetAttributeValue >() )
 
 1846  if ( !attributes.isEmpty() )
 
 1848    res.insert( QStringLiteral( 
"attributes" ), attributes );
 
 
 1858  switch ( expectedType )
 
 1860    case QMetaType::Type::QString:
 
 1862      const QString escaped = variant.toString().replace( 
'\\', QLatin1String( 
"\\\\" ) ).replace( 
'"', QLatin1String( 
"\\\"" ) );
 
 1863      return QString( QUrl::toPercentEncoding( escaped, 
"'" ) );
 
 1866    case QMetaType::Type::QDateTime:
 
 1867    case QMetaType::Type::QDate:
 
 1869      switch ( variant.userType() )
 
 1871        case QMetaType::Type::QDateTime:
 
 1872          return variant.toDateTime().toMSecsSinceEpoch();
 
 1874        case QMetaType::Type::QDate:
 
 1876          if ( context.
timeZone().isValid() )
 
 1877            return QDateTime( variant.toDate(), QTime( 0, 0, 0 ), context.
timeZone() ).toMSecsSinceEpoch();
 
 1879            return QDateTime( variant.toDate(), QTime( 0, 0, 0 ) ).toMSecsSinceEpoch();
 
 
 1894  res.insert( QStringLiteral( 
"name" ), field.
name() );
 
 1897  switch ( field.
type() )
 
 1899    case QMetaType::Type::LongLong:
 
 1900      fieldType = QStringLiteral( 
"esriFieldTypeInteger" );
 
 1903    case QMetaType::Type::Int:
 
 1904      fieldType = QStringLiteral( 
"esriFieldTypeSmallInteger" );
 
 1907    case QMetaType::Type::Double:
 
 1908      fieldType = QStringLiteral( 
"esriFieldTypeDouble" );
 
 1911    case QMetaType::Type::QString:
 
 1912      fieldType = QStringLiteral( 
"esriFieldTypeString" );
 
 1915    case QMetaType::Type::QDateTime:
 
 1916    case QMetaType::Type::QDate:
 
 1917      fieldType = QStringLiteral( 
"esriFieldTypeDate" );
 
 1920    case QMetaType::Type::QByteArray:
 
 1921      fieldType = QStringLiteral( 
"esriFieldTypeBlob" );
 
 1926      fieldType = QStringLiteral( 
"esriFieldTypeString" );
 
 1929  res.insert( QStringLiteral( 
"type" ), fieldType );
 
 1931  if ( !field.
alias().isEmpty() )
 
 1932    res.insert( QStringLiteral( 
"alias" ), field.
alias() );
 
 1936  res.insert( QStringLiteral( 
"nullable" ), !notNullable );
 
 1939  res.insert( QStringLiteral( 
"editable" ), 
true );
 
 
 1946  if ( type.compare( QLatin1String( 
"FeatureServer" ), Qt::CaseInsensitive ) == 0 )
 
 1948  else if ( type.compare( QLatin1String( 
"MapServer" ), Qt::CaseInsensitive ) == 0 )
 
 1950  else if ( type.compare( QLatin1String( 
"ImageServer" ), Qt::CaseInsensitive ) == 0 )
 
 1952  else if ( type.compare( QLatin1String( 
"GlobeServer" ), Qt::CaseInsensitive ) == 0 )
 
 1954  else if ( type.compare( QLatin1String( 
"GPServer" ), Qt::CaseInsensitive ) == 0 )
 
 1956  else if ( type.compare( QLatin1String( 
"GeocodeServer" ), Qt::CaseInsensitive ) == 0 )
 
 
@ BelowLine
Labels can be placed below a line feature. Unless MapOrientation is also specified this mode respects...
 
@ MapOrientation
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
 
@ OnLine
Labels can be placed directly over a line feature.
 
@ AboveLine
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
 
@ NoOrientation
Unknown orientation or sentinel value.
 
@ CounterClockwise
Counter-clockwise direction.
 
@ Clockwise
Clockwise direction.
 
@ 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'...
 
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
 
@ ScaleArea
Calculate scale by the area.
 
ArcGisRestServiceType
Available ArcGIS REST service types.
 
@ GeocodeServer
GeocodeServer.
 
@ Unknown
Other unknown/unsupported type.
 
@ GlobeServer
GlobeServer.
 
@ ImageServer
ImageServer.
 
@ FeatureServer
FeatureServer.
 
MarkerShape
Marker shapes.
 
@ Cross2
Rotated cross (lines only), 'x' shape.
 
@ Cross
Cross (lines only)
 
VerticalAnchorPoint
Marker symbol vertical anchor points.
 
@ Bottom
Align to bottom of symbol.
 
@ Center
Align to vertical center of symbol.
 
@ Top
Align to top of symbol.
 
@ Points
Points (e.g., for font sizes)
 
WkbType
The WKB type describes the number of dimensions a geometry has.
 
@ CompoundCurve
CompoundCurve.
 
@ MultiPolygon
MultiPolygon.
 
@ MultiLineString
MultiLineString.
 
@ CircularString
CircularString.
 
@ GeometryCollection
GeometryCollection.
 
@ CurvePolygon
CurvePolygon.
 
@ MultiSurface
MultiSurface.
 
@ Wkt2_2019Simplified
WKT2_2019 with the simplification rule of WKT2_SIMPLIFIED.
 
HorizontalAnchorPoint
Marker symbol horizontal anchor points.
 
@ Center
Align to horizontal center of symbol.
 
@ Right
Align to right side of symbol.
 
@ Left
Align to left side of symbol.
 
Abstract base class for all geometries.
 
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
 
bool isMeasure() const
Returns true if the geometry contains m values.
 
virtual QgsRectangle boundingBox() const
Returns the minimal bounding box for the geometry.
 
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
 
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
 
Abstract base class - its implementations define different approaches to the labeling of a vector lay...
 
Contains the context of a ArcGIS REST service operation.
 
QTimeZone timeZone() const
Returns the time zone for datetime values.
 
QString objectIdFieldName() const
Returns the name of the objectId field.
 
static QVariantMap fieldDefinitionToJson(const QgsField &field)
Converts a field's definition to an ArcGIS REST JSON representation.
 
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 Qgis::WkbType convertGeometryType(const QString &type)
Converts an ESRI REST geometry type to a WKB type.
 
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 QVariantMap geometryToJson(const QgsGeometry &geometry, const QgsArcGisRestContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Converts a geometry to an ArcGIS REST JSON representation.
 
static Qgis::ArcGisRestServiceType serviceTypeFromString(const QString &type)
Converts a string value to a REST service type.
 
static QVariant variantToAttributeValue(const QVariant &variant, QMetaType::Type expectedType, const QgsArcGisRestContext &context)
Converts a variant to a REST attribute value.
 
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 QVariantMap featureToJson(const QgsFeature &feature, const QgsArcGisRestContext &context, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem(), QgsArcGisRestUtils::FeatureToJsonFlags flags=QgsArcGisRestUtils::FeatureToJsonFlags(static_cast< int >(QgsArcGisRestUtils::FeatureToJsonFlag::IncludeGeometry)|static_cast< int >(QgsArcGisRestUtils::FeatureToJsonFlag::IncludeNonObjectIdAttributes)))
Converts a feature to an ArcGIS REST JSON representation.
 
static Qt::PenStyle convertLineStyle(const QString &style)
Converts an ESRI line style to a Qt pen style.
 
@ IncludeGeometry
Whether to include the geometry definition.
 
@ IncludeNonObjectIdAttributes
Whether to include any non-objectId attributes.
 
@ SkipUnsetAttributes
Skip unset attributes.
 
static QgsFeatureRenderer * convertRenderer(const QVariantMap &rendererData)
Converts renderer JSON data to an equivalent QgsFeatureRenderer.
 
static QMetaType::Type convertFieldType(const QString &type)
Converts an ESRI REST field type to a QVariant type.
 
static Qt::BrushStyle convertFillStyle(const QString &style)
Converts an ESRI fill style to a Qt brush style.
 
static QVariantMap crsToJson(const QgsCoordinateReferenceSystem &crs)
Converts a crs to an ArcGIS REST JSON representation.
 
QFlags< FeatureToJsonFlag > FeatureToJsonFlags
Flags which control the behavior of converting features to JSON.
 
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.
 
static QgsRectangle convertRectangle(const QVariant &value)
Converts a rectangle value to a QgsRectangle.
 
A feature renderer which represents features using a list of renderer categories.
 
Circular string geometry type.
 
QgsPoint startPoint() const override
Returns the starting point of the curve.
 
bool isEmpty() const override
Returns true if the geometry is empty.
 
int numPoints() const override
Returns the number of points in the curve.
 
QgsPoint pointN(int i) const
Returns the point at index i within the circular string.
 
A dummy implementation class method which does not compute any breaks.
 
A classification method which uses equal width intervals.
 
Implementation of a fixed interval classification.
 
A classification method for natural breaks, based on Jenks method.
 
A classification method which creates classes based on quantiles.
 
A classification method which classifies based on standard deviation of values.
 
Compound curve geometry type.
 
QgsCompoundCurve * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
 
int nCurves() const
Returns the number of curves in the geometry.
 
const QgsCurve * curveAt(int i) const
Returns the curve at the specified index.
 
QgsPoint startPoint() const override
Returns the starting point of the curve.
 
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.
 
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
 
Curve polygon geometry type.
 
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
 
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
 
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
 
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)
 
Abstract base class for curved geometry type.
 
Qgis::AngularDirection orientation() const
Returns the curve's orientation, e.g.
 
virtual QgsCurve * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
 
virtual QgsPoint endPoint() const =0
Returns the end point of the curve.
 
Handles parsing and evaluation of expressions (formerly called "search strings").
 
bool isValid() const
Checks if this expression is valid.
 
Abstract base class for all 2D vector feature renderers.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
bool hasGeometry() const
Returns true if the feature has an associated geometry.
 
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
 
@ ConstraintNotNull
Field may not be null.
 
Encapsulate a field in an attribute table or data source.
 
QgsFieldConstraints constraints
 
Container of fields for a vector layer.
 
int numGeometries() const
Returns the number of geometries within the collection.
 
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
 
A geometry is the spatial representation of a feature.
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
 
Represents a color stop within a QgsGradientColorRamp color ramp.
 
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
 
void setQuadrant(Qgis::LabelQuadrantPosition quadrant)
Sets the quadrant in which to offset labels from the point.
 
Line string geometry type, with support for z-dimension and m-values.
 
const double * yData() const
Returns a const pointer to the y vertex data.
 
const double * xData() const
Returns a const pointer to the x vertex data.
 
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values.
 
int numPoints() const override
Returns the number of points in the curve.
 
QgsLineString * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
 
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values.
 
Multi curve geometry collection.
 
QgsCurve * curveN(int index)
Returns the curve with the specified index.
 
Multi line string geometry collection.
 
QgsLineString * lineStringN(int index)
Returns the line string with the specified index.
 
Multi point geometry collection.
 
QgsPoint * pointN(int index)
Returns the point with the specified index.
 
Multi polygon geometry collection.
 
QgsPolygon * polygonN(int index)
Returns the polygon with the specified index.
 
Multi surface geometry collection.
 
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.
 
Qgis::LabelPlacement placement
Label placement mode.
 
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
 
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
 
QString fieldName
Name of field (or an expression) to use for label text.
 
const QgsLabelPointSettings & pointSettings() const
Returns the label point settings, which contain settings related to how the label engine places and f...
 
Point geometry type, with support for z-dimension and m-values.
 
void clear() override
Clears the geometry, ie reset it to a null geometry.
 
bool isEmpty() const override
Returns true if the geometry is empty.
 
A store for object properties.
 
void setTransformer(QgsPropertyTransformer *transformer)
Sets an optional transformer to use for manipulating the calculated values for the property.
 
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
 
A rectangle specified with double values.
 
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
 
Represents an individual category (class) from a QgsCategorizedSymbolRenderer.
 
Represents a value range for a QgsGraduatedSymbolRenderer.
 
void setUpperValue(double upperValue)
Sets the upper bound of the range.
 
void setSymbol(QgsSymbol *s)
Sets the symbol used for the range.
 
void setLabel(const QString &label)
Sets the label used for the range.
 
void setLowerValue(double lowerValue)
Sets the lower bound of the range.
 
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.
 
A feature renderer which renders all features with the same symbol.
 
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 setSizeUnit(Qgis::RenderUnit unit)
Sets the units used for the buffer size.
 
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
 
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 setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the size of rendered text.
 
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
 
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
 
static Qgis::WkbType zmType(Qgis::WkbType type, bool hasZ, bool hasM)
Returns the modified input geometry type according to hasZ / hasM.
 
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
 
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
 
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
 
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
 
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< QgsGradientStop > QgsGradientStopsList
List of gradient stops.
 
#define QgsDebugError(str)
 
QList< QgsSymbolLayer * > QgsSymbolLayerList
 
const QgsCoordinateReferenceSystem & crs