23#include <nlohmann/json.hpp>
89#include <QTemporaryFile>
91#include <QXmlStreamReader>
93using namespace Qt::StringLiterals;
120 : mContext( context )
122 mProject = mContext.project();
124 mWmsParameters = mContext.parameters();
125 mWmsParameters.dump();
130 removeTemporaryLayers();
136 std::unique_ptr<QgsWmsRestorer> restorer;
137 restorer = std::make_unique<QgsWmsRestorer>( mContext );
140 QList<QgsMapLayer *> layers = mContext.layersToRender();
143 const qreal dpmm = mContext.dotsPerMm();
148 const auto layersToRender = mContext.layersToRender();
149 for (
const auto &layer : std::as_const( layersToRender ) )
152 if ( layer->dataProvider()->name() ==
"wms"_L1 )
156 const auto image { layerNode->getLegendGraphicBlocking() };
157 if ( !image.isNull() )
160 if ( mContext.isValidWidthHeight( image.width(), image.height() ) )
162 const double w = image.width() / dpmm;
163 const double h = image.height() / dpmm;
164 const QSizeF newWmsSize { w, h };
177 if ( !mWmsParameters.bbox().isEmpty() )
181 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
182 configureMapSettings( tmp.get(), mapSettings );
188 context = configureDefaultRenderContext();
192 std::unique_ptr<QImage> image;
193 const QSizeF minSize = renderer.
minimumSize( &context );
194 const QSize size(
static_cast<int>( minSize.width() * dpmm ),
static_cast<int>( minSize.height() * dpmm ) );
195 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
199 image.reset( createImage( size ) );
202 QPainter painter( image.get() );
205 if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
207 if ( painter.renderHints() & QPainter::LosslessImageRendering )
217 return image.release();
223 std::unique_ptr<QgsWmsRestorer> restorer;
224 restorer = std::make_unique<QgsWmsRestorer>( mContext );
227 QList<QgsMapLayer *> layers = mContext.layersToRender();
231 const QSize size( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() );
233 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
237 std::unique_ptr<QImage> image( createImage( size ) );
240 const qreal dpmm = mContext.dotsPerMm();
241 std::unique_ptr<QPainter> painter;
242 painter = std::make_unique<QPainter>( image.get() );
243 painter->setRenderHint( QPainter::Antialiasing,
true );
244 painter->scale( dpmm, dpmm );
255 nodeModel.
drawSymbol( settings, &ctx, size.height() / dpmm );
258 return image.release();
264 std::unique_ptr<QgsWmsRestorer> restorer;
265 restorer = std::make_unique<QgsWmsRestorer>( mContext );
268 QList<QgsMapLayer *> layers = mContext.layersToRender();
284 std::unique_ptr<QgsWmsRestorer> restorer;
285 restorer = std::make_unique<QgsWmsRestorer>( mContext );
288 QList<QgsMapLayer *> layers = mContext.layersToRender();
297 QJsonObject jsonSymbol {
legendNode.exportSymbolToJson( settings, renderContext ) };
304 if ( vLayer->renderer() )
308 const QString ruleExp { vLayer->renderer()->legendKeyToExpression( ruleKey, vLayer, ok ) };
311 jsonSymbol[u
"rule"_s] = ruleExp;
320 void QgsRenderer::runHitTest(
const QgsMapSettings &mapSettings, HitTest &hitTest )
const
324 for (
const QString &
id : mapSettings.
layerIds() )
341 runHitTestLayer( vl, usedSymbols, context );
345 void QgsRenderer::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context )
const
347 std::unique_ptr<QgsFeatureRenderer> r( vl->
renderer()->
clone() );
349 r->startRender( context, vl->
fields() );
351 QgsFeatureRequest request( context.
extent() );
353 QgsFeatureIterator fi = vl->
getFeatures( request );
357 if ( moreSymbolsPerFeature )
359 for ( QgsSymbol *s : r->originalSymbolsForFeature( f, context ) )
365 r->stopRender( context );
371 if ( !mContext.isValidWidthHeight() )
377 std::unique_ptr<QgsWmsRestorer> restorer;
378 restorer = std::make_unique<QgsWmsRestorer>( mContext );
383 QList<QgsMapLayer *> layers = mContext.layersToRender();
387 std::unique_ptr<QPainter> painter;
388 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
391 configureMapSettings( image.get(), mapSettings );
398 runHitTest( mapSettings,
symbols );
406 std::unique_ptr<QgsWmsRestorer> restorer;
407 restorer = std::make_unique<QgsWmsRestorer>( mContext );
410 const QString templateName = mWmsParameters.composerTemplate();
411 if ( templateName.isEmpty() )
434 std::unique_ptr<QgsPrintLayout> layout( sourceLayout->
clone() );
438 QStringList atlasPk = mWmsParameters.atlasPk();
439 if ( !atlasPk.isEmpty() )
441 atlas = layout->atlas();
442 if ( !atlas || !atlas->
enabled() )
455 if ( atlasPk.size() == 1 && atlasPk.at( 0 ) ==
"*"_L1 )
459 if ( atlas->
count() > maxAtlasFeatures )
467 if ( pkIndexes.size() == 0 )
469 QgsDebugMsgLevel( u
"Atlas print: layer %1 has no primary key attributes"_s.arg( cLayer->
name() ), 2 );
473 const int pkIndexesSize { std::max<int>( pkIndexes.size(), 1 ) };
475 QStringList pkAttributeNames;
476 for (
int pkIndex : std::as_const( pkIndexes ) )
478 pkAttributeNames.append( cLayer->
fields().
at( pkIndex ).
name() );
481 const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
482 if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() )
488 if ( nAtlasFeatures > maxAtlasFeatures )
492 QString(
"%1 atlas features have been requested, but the project configuration only allows printing %2 atlas features at a time" ).arg( nAtlasFeatures ).arg( maxAtlasFeatures )
496 QString filterString;
497 int currentAtlasPk = 0;
499 for (
int i = 0; i < nAtlasFeatures; ++i )
503 filterString.append(
" OR " );
506 filterString.append(
"( " );
509 if ( pkAttributeNames.isEmpty() )
511 filterString.append( u
"$id = %1"_s.arg( atlasPk.at( currentAtlasPk ) ) );
516 for (
int j = 0; j < pkIndexes.size(); ++j )
520 filterString.append(
" AND " );
527 filterString.append(
" )" );
535 if ( !errorString.isEmpty() )
537 throw QgsException( u
"An error occurred during the Atlas print: %1"_s.arg( errorString ) );
545 QList<QgsMapLayer *> layers = mContext.layersToRender();
549 auto image = std::make_unique<QImage>();
550 configureMapSettings( image.get(), mapSettings );
556 configurePrintLayout( layout.get(), mapSettings, atlas );
560 const QList<QgsMapLayer *> lyrs = mapSettings.
layers();
562#ifdef HAVE_SERVER_PYTHON_PLUGINS
563 mContext.accessControl()->resolveFilterFeatures( lyrs );
567 QHash<const QgsVectorLayer *, QStringList> fltrs;
572 fltrs.insert( vl, dimensionFilter( vl ) );
584 QTemporaryFile tempOutputFile( QDir::tempPath() +
'/' + u
"XXXXXX.%1"_s.arg( extension ) );
585 if ( !tempOutputFile.open() )
587 throw QgsException( u
"Could not open temporary file for the GetPrint request."_s );
595 if ( !mWmsParameters.dpi().isEmpty() )
598 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
600 exportSettings.
dpi = dpi;
613 atlasSvgExport.
exportToSvg( tempOutputFile.fileName(), exportSettings );
619 exporter.
exportToSvg( tempOutputFile.fileName(), exportSettings );
628 double dpi( layout->renderContext().dpi() );
629 if ( !mWmsParameters.dpi().isEmpty() )
632 double _dpi = mWmsParameters.dpi().toDouble( &ok );
636 exportSettings.
dpi = dpi;
642 QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );
647 const QSize imageSize = QSize(
static_cast<int>( width.
length() * dpi / 25.4 ),
static_cast<int>( height.
length() * dpi / 25.4 ) );
649 const QString paramWidth = mWmsParameters.width();
650 const QString paramHeight = mWmsParameters.height();
655 if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
657 exportSettings.
imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
659 else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
661 exportSettings.
imageSize = QSize( paramWidth.toInt(),
static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
663 else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
665 exportSettings.
imageSize = QSize(
static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
673 exportSettings.
pages.append( 0 );
681 atlasPngExport.
exportToImage( tempOutputFile.fileName(), exportSettings );
685 throw QgsServiceException( u
"Bad request"_s, u
"Atlas error: empty atlas."_s, QString(), 400 );
691 exporter.
exportToImage( tempOutputFile.fileName(), exportSettings );
699 if ( !mWmsParameters.dpi().isEmpty() )
702 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
704 exportSettings.
dpi = dpi;
709 exportSettings.
rasterizeWholeImage = layout->customProperty( u
"rasterize"_s,
false ).toBool();
711 QVector<qreal> requestMapScales = mWmsParameters.pdfPredefinedMapScales();
712 if ( requestMapScales.size() > 0 )
721 QStringList exportThemes = mWmsParameters.pdfExportMapThemes();
722 if ( exportThemes.size() > 0 )
726 exportSettings.
writeGeoPdf = mWmsParameters.writeGeospatialPdf();
732 if ( mWmsParameters.pdfLosslessImageCompression() )
736 if ( mWmsParameters.pdfDisableTiledRasterRendering() )
749 exporter.
exportToPdf( tempOutputFile.fileName(), exportSettings );
759 handlePrintErrors( atlas->
layout() );
763 handlePrintErrors( layout.get() );
766 return tempOutputFile.readAll();
773 QList<QgsLayoutItemMap *> maps;
779 for (
const auto &map : std::as_const( maps ) )
785 if ( cMapParams.
mLayers.isEmpty() )
790 if ( !atlas || !map->atlasDriven() )
796 c->removeLayoutItem( map );
805 QgsRectangle r( cMapParams.
mExtent );
813 if ( cMapParams.
mScale > 0 )
815 map->setScale(
static_cast<double>( cMapParams.
mScale ) );
821 map->setMapRotation( cMapParams.
mRotation );
825 if ( !map->keepLayerSet() )
827 QList<QgsMapLayer *> layerSet;
829 for (
const auto &layer : std::as_const( cMapParams.
mLayers ) )
831 if ( mContext.isValidGroup( layer.mNickname ) )
833 QList<QgsMapLayer *> layersFromGroup;
835 const QList<QgsMapLayer *> cLayersFromGroup = mContext.layersFromGroup( layer.mNickname );
836 for ( QgsMapLayer *layerFromGroup : cLayersFromGroup )
838 if ( !layerFromGroup )
843 layersFromGroup.push_front( layerFromGroup );
846 if ( !layersFromGroup.isEmpty() )
848 layerSet.append( layersFromGroup );
853 QgsMapLayer *mlayer = mContext.layer( layer.mNickname );
860 setLayerStyle( mlayer, layer.mStyle );
865 std::reverse( layerSet.begin(), layerSet.end() );
870 QMap<QString, QString> layersStyle;
871 if ( map->followVisibilityPreset() )
881 const QString presetName = map->followVisibilityPresetName();
882 if ( layerSet.isEmpty() )
885 const QgsExpressionContext ex { map->createExpressionContext() };
886 layerSet = map->layersToRender( &ex );
889 map->setFollowVisibilityPreset(
false );
893 for (
const auto &layerMapThemeRecord : std::as_const( mapThemeRecords ) )
895 if ( layerSet.contains( layerMapThemeRecord.layer() ) )
897 layersStyle.insert( layerMapThemeRecord.layer()->id(), layerMapThemeRecord.layer()->styleManager()->style( layerMapThemeRecord.currentStyle ).xmlData() );
903 const QList<QgsMapLayer *> highlights = highlightLayers( cMapParams.
mHighlightLayers );
904 for (
const auto &hl : std::as_const( highlights ) )
906 layerSet.prepend( hl );
909 map->setLayers( layerSet );
910 map->setKeepLayerSet(
true );
914 if ( !layersStyle.isEmpty() )
916 map->setLayerStyleOverrides( layersStyle );
917 map->setKeepLayerStyles(
true );
924 map->grid()->setIntervalX(
static_cast<double>( cMapParams.
mGridX ) );
925 map->grid()->setIntervalY(
static_cast<double>( cMapParams.
mGridY ) );
930 QList<QgsLayoutItemLabel *> labels;
931 c->layoutItems<QgsLayoutItemLabel>( labels );
932 for (
const auto &label : std::as_const( labels ) )
935 const QString labelId = label->id();
936 const QString labelParam = mWmsParameters.layoutParameter( labelId, ok );
941 if ( labelParam.isEmpty() )
945 c->removeItem( label );
950 label->setText( labelParam );
954 QList<QgsLayoutItemHtml *> htmls;
955 c->layoutObjects<QgsLayoutItemHtml>( htmls );
956 for (
const auto &html : std::as_const( htmls ) )
958 if ( html->frameCount() == 0 )
961 QgsLayoutFrame *htmlFrame = html->frame( 0 );
963 const QString htmlId = htmlFrame->
id();
964 const QString htmlValue = mWmsParameters.layoutParameter( htmlId, ok );
974 if ( htmlValue.isEmpty() )
976 c->removeMultiFrame( html );
983 QUrl newUrl( htmlValue );
984 html->setUrl( newUrl );
988 html->setHtml( htmlValue );
995 QList<QgsLayoutItemLegend *> legends;
996 c->layoutItems<QgsLayoutItemLegend>( legends );
997 for (
const auto &legend : std::as_const( legends ) )
999 switch ( legend->syncMode() )
1006 const QgsLayoutItemMap *map = legend->linkedMap();
1015 QgsLegendModel *model = legend->model();
1016 QStringList layerSet;
1017 QList<QgsMapLayer *> mapLayers;
1018 if ( map->
layers().isEmpty() )
1022 mapLayers = mProject->mapLayers(
true ).values();
1026 mapLayers = map->
layers();
1028 const QList<QgsMapLayer *> layerList = mapLayers;
1029 for (
const auto &layer : layerList )
1030 layerSet << layer->id();
1033 QgsLayerTree *root = model->
rootGroup();
1040 for (
const auto &layerId : layerIds )
1042 QgsLayerTreeLayer *nodeLayer = root->
findLayer( layerId );
1047 if ( !layerSet.contains( layerId ) )
1049 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1053 QgsMapLayer *layer = nodeLayer->
layer();
1056 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1074 if ( !mContext.isValidWidthHeight() )
1079 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1085 std::unique_ptr<QgsWmsRestorer> restorer;
1086 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1089 QList<QgsMapLayer *> layers = mContext.layersToRender();
1096 std::unique_ptr<QPainter> painter;
1097 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
1100 configureMapSettings( image.get(), mapSettings );
1106 QPainter *renderedPainter = layersRendering( mapSettings, image.get() );
1107 if ( !renderedPainter )
1112 painter.reset( renderedPainter );
1115 annotationsRendering( painter.get(), mapSettings );
1121 QImage *scaledImage = scaleImage( image.get() );
1123 image.reset( scaledImage );
1126 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1136 QList<QgsMapLayer *> layers = mContext.layersToRender();
1140 const QStringList attributes = mWmsParameters.dxfLayerAttributes();
1141 QList<QgsDxfExport::DxfLayer> dxfLayers;
1153 int layerAttribute = -1;
1154 if ( attributes.size() > layerIdx )
1163 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1165 QString crs = mWmsParameters.crs();
1166 if ( crs.compare( u
"CRS:84"_s, Qt::CaseInsensitive ) == 0 )
1168 crs = u
"EPSG:4326"_s;
1171 else if ( crs.isEmpty() )
1173 crs = u
"EPSG:4326"_s;
1207 auto dxf = std::make_unique<QgsDxfExport>();
1208 dxf->setExtent( mapExtent );
1209 dxf->setDestinationCrs( outputCRS );
1210 dxf->addLayers( dxfLayers );
1211 dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
1212 dxf->setSymbologyExport( mWmsParameters.dxfMode() );
1215 dxf->setSymbologyScale( mWmsParameters.dxfScale() );
1218 dxf->setForce2d( mWmsParameters.isForce2D() );
1220 if ( mWmsParameters.noMText() )
1223 if ( mWmsParameters.exportLinesWithZeroWidth() )
1228 dxf->setFlags( flags );
1237 QList<QgsMapLayer *> layers = mContext.layersToRender();
1241 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1243 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1247 if ( mWmsParameters.pdfExportMetadata() )
1258 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1259 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, u
"PDF"_s,
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1260 if ( mWmsParameters.pdfAppendGeoreference() )
1262 pdf->setSaveWorldFile(
true );
1270 if ( i < 0 || i > mapSettings.
outputSize().width() )
1277 if ( j < 0 || j > mapSettings.
outputSize().height() )
1294 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1300 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1301 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1302 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1303 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1305 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1309 if ( mWmsParameters.j().isEmpty() )
1322 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1325 std::unique_ptr<QgsWmsRestorer> restorer;
1326 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1330 bool mandatoryCrsParam =
true;
1331 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1333 mandatoryCrsParam =
false;
1339 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1344 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1356#ifdef HAVE_SERVER_PYTHON_PLUGINS
1357 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1360 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1365 ba = convertFeatureInfoToText( result );
1367 ba = convertFeatureInfoToHtml( result );
1369 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1371 ba = result.toByteArray();
1376 QImage *QgsRenderer::createImage(
const QSize &size )
const
1378 std::unique_ptr<QImage> image;
1386 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1391 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1396 if ( image->isNull() )
1398 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1401 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1402 image->setDotsPerMeterX( dpm );
1403 image->setDotsPerMeterY( dpm );
1405 return image.release();
1408 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1412 throw QgsException( u
"configureMapSettings: no paint device"_s );
1415 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1418 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1421 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1422 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1427 QString crs = mWmsParameters.crs();
1428 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1430 crs = QString(
"EPSG:4326" );
1433 else if ( crs.isEmpty() && !mandatoryCrsParam )
1435 crs = QString(
"EPSG:4326" );
1438 QgsCoordinateReferenceSystem outputCRS;
1445 QgsWmsParameter parameter;
1447 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1458 throw QgsBadRequestException( code, parameter );
1468 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1476 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1482 bool transparent = mWmsParameters.transparentAsBool();
1483 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1490 else if ( backgroundColor.isValid() )
1496 QgsExpressionContext context = mProject->createExpressionContext();
1513 if ( mContext.settings().logProfile() )
1523 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1524 if ( !timeString.isEmpty() )
1526 bool isValidTemporalRange {
true };
1529 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1540 catch (
const QgsServerApiBadRequestException &ex )
1542 isValidTemporalRange =
false;
1547 if ( isValidTemporalRange )
1556 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1562 QgsDistanceArea distanceArea = QgsDistanceArea();
1563 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1569 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1571 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1573 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1575 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1577 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1579 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1581 int featureCount = mWmsParameters.featureCountAsInt();
1582 if ( featureCount < 1 )
1587 int i = mWmsParameters.iAsInt();
1588 int j = mWmsParameters.jAsInt();
1589 if ( xyDefined && !ijDefined )
1591 i = mWmsParameters.xAsInt();
1592 j = mWmsParameters.yAsInt();
1594 int width = mWmsParameters.widthAsInt();
1595 int height = mWmsParameters.heightAsInt();
1596 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1598 i *= ( outputImage->width() /
static_cast<double>( width ) );
1599 j *= ( outputImage->height() /
static_cast<double>( height ) );
1603 std::unique_ptr<QgsRectangle> featuresRect;
1604 std::unique_ptr<QgsGeometry> filterGeom;
1605 std::unique_ptr<QgsPointXY> infoPoint;
1607 if ( i != -1 && j != -1 )
1609 infoPoint = std::make_unique<QgsPointXY>();
1610 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1612 else if ( filtersDefined )
1614 featuresRect = std::make_unique<QgsRectangle>();
1617 if ( filterGeomDefined )
1619 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1622 QDomDocument result;
1623 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1624 result.appendChild( header );
1626 QDomElement getFeatureInfoElement;
1630 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1631 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1632 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1633 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1634 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1635 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1636 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1637 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1638 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, u
"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://qgis.org/gml"_s );
1643 if ( featureInfoElemName.isEmpty() )
1645 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1648 if ( featureInfoElemNs.isEmpty() )
1650 getFeatureInfoElement = result.createElement( featureInfoElemName );
1654 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1658 if ( !featureInfoSchema.isEmpty() )
1660 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1661 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1664 result.appendChild( getFeatureInfoElement );
1674 for (
const QString &queryLayer : queryLayers )
1676 bool validLayer =
false;
1677 bool queryableLayer =
true;
1678 for ( QgsMapLayer *layer : std::as_const( layers ) )
1680 if ( queryLayer == mContext.layerNickname( *layer ) )
1684 if ( !queryableLayer )
1689 QDomElement layerElement;
1692 layerElement = getFeatureInfoElement;
1696 layerElement = result.createElement( u
"Layer"_s );
1697 QString layerName = queryLayer;
1700 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1701 if ( layerAliasIt != layerAliasMap.constEnd() )
1703 layerName = layerAliasIt.value();
1706 layerElement.setAttribute( u
"name"_s, layerName );
1707 const QString layerTitle = layer->serverProperties()->title();
1708 if ( !layerTitle.isEmpty() )
1710 layerElement.setAttribute( u
"title"_s, layerTitle );
1714 layerElement.setAttribute( u
"title"_s, layerName );
1716 getFeatureInfoElement.appendChild( layerElement );
1719 layerElement.setAttribute( u
"id"_s, layer->id() );
1725 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1728 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1734 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1750 layerElement = result.createElement( u
"gml:featureMember"_s );
1751 getFeatureInfoElement.appendChild( layerElement );
1753 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1757 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1765 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1769 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1772 param.mValue = queryLayer;
1775 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1778 param.mValue = queryLayer;
1780 bool hasGroupAndQueryable {
false };
1781 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1784 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1785 for (
const QString &ql : constNicks )
1787 if ( mContext.layerGroups().contains( ql ) )
1789 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1790 for (
const QgsMapLayer *ml : constLayers )
1792 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1798 hasGroupAndQueryable =
true;
1807 if ( !hasGroupAndQueryable )
1814 if ( featuresRect && !featuresRect->isNull() )
1818 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1819 QDomElement boxElem;
1820 int gmlVersion = mWmsParameters.infoFormatVersion();
1821 if ( gmlVersion < 3 )
1833 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1835 bBoxElem.appendChild( boxElem );
1836 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1840 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1842 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1843 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1844 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1845 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1846 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1852 convertFeatureInfoToSia2045( result );
1858 bool QgsRenderer::featureInfoFromVectorLayer(
1859 QgsVectorLayer *layer,
1860 const QgsPointXY *infoPoint,
1862 QDomDocument &infoDocument,
1863 QDomElement &layerElement,
1864 const QgsMapSettings &mapSettings,
1865 QgsRenderContext &renderContext,
1866 const QString &version,
1867 QgsRectangle *featureBBox,
1868 QgsGeometry *filterGeom
1876 QgsFeatureRequest fReq;
1879 std::unique_ptr<QgsGeometry> layerFilterGeom;
1882 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1887 QgsRectangle mapRect = mapSettings.
extent();
1891 QgsRectangle searchRect;
1896 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1898 else if ( layerFilterGeom )
1900 searchRect = layerFilterGeom->boundingBox();
1902 else if ( !mWmsParameters.bbox().isEmpty() )
1904 searchRect = layerRect;
1910 QgsAttributes featureAttributes;
1911 int featureCounter = 0;
1913 const QgsFields fields = layer->
fields();
1930 if ( layerFilterGeom )
1932 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1936 mFeatureFilter.filterFeatures( layer, fReq );
1939#ifdef HAVE_SERVER_PYTHON_PLUGINS
1941 mContext.accessControl()->filterFeatures( layer, fReq );
1944 QStringList attributes;
1945 for (
const QgsField &field : fields )
1947 attributes.append( field.name() );
1949 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1953 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1957 r2->startRender( renderContext, layer->
fields() );
1960 bool featureBBoxInitialized =
false;
1969 if ( featureCounter > nFeatures )
1984 bool render = r2->willRenderFeature( feature, renderContext );
1997 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
2000 featureBBoxInitialized =
true;
2009 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
2018 int gmlVersion = mWmsParameters.infoFormatVersion();
2019 QString typeName = mContext.layerNickname( *layer );
2020 QDomElement elem = createFeatureGML(
2029#ifdef HAVE_SERVER_PYTHON_PLUGINS
2034 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2035 featureMemberElem.appendChild( elem );
2036 layerElement.appendChild( featureMemberElem );
2041 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2043 layerElement.appendChild( featureElement );
2049 writeAttributesTabLayout(
2057#ifdef HAVE_SERVER_PYTHON_PLUGINS
2065 for (
int i = 0; i < featureAttributes.count(); ++i )
2067 writeVectorLayerAttribute(
2075#ifdef HAVE_SERVER_PYTHON_PLUGINS
2087 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2088 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2092 featureElement.appendChild( maptipElem );
2096 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2098 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2099 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2102 displayExpression.
prepare( &context );
2103 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2104 featureElement.appendChild( displayElem );
2110 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2111 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2116 featureElement.appendChild( bBoxElem );
2122 QgsGeometry geom = feature.
geometry();
2125 if ( layer->
crs() != outputCrs )
2127 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2132 if ( segmentizeWktGeometry )
2134 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2139 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2140 geom.
set( segmentizedGeom );
2144 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2145 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2146 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2147 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2148 featureElement.appendChild( geometryElement );
2155 r2->stopRender( renderContext );
2161 void QgsRenderer::writeAttributesTabGroup(
2162 const QgsAttributeEditorElement *group,
2163 QgsVectorLayer *layer,
2164 const QgsFields &fields,
2165 QgsAttributes &featureAttributes,
2167 QDomElement &parentElem,
2168 QgsRenderContext &renderContext,
2169 QStringList *attributes
2172 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2175 QString groupName = container->
name();
2176 QDomElement nameElem;
2178 if ( !groupName.isEmpty() )
2180 nameElem = doc.createElement( groupName );
2181 parentElem.appendChild( nameElem );
2184 const QList<QgsAttributeEditorElement *> children = container->
children();
2185 for (
const QgsAttributeEditorElement *child : children )
2189 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2193 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2199 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2207 void QgsRenderer::writeAttributesTabLayout(
2208 QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2212 if ( !editorContainer )
2217 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2220 void QgsRenderer::writeVectorLayerAttribute(
2221 int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2224#ifndef HAVE_SERVER_PYTHON_PLUGINS
2225 Q_UNUSED( attributes );
2238#ifdef HAVE_SERVER_PYTHON_PLUGINS
2240 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2247 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2248 attributeElement.setAttribute( u
"name"_s, attributeName );
2251 featureElem.appendChild( attributeElement );
2254 bool QgsRenderer::featureInfoFromMeshLayer(
2255 QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2259 Q_UNUSED( mapSettings )
2268 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2270 QList<QgsMeshDatasetIndex> datasetIndexList;
2279 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2281 if ( activeScalarGroup >= 0 )
2283 QgsMeshDatasetIndex indice;
2285 datasetIndexList.append( indice );
2288 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2291 for (
int groupIndex : allGroup )
2293 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2299 if ( activeScalarGroup >= 0 )
2301 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2304 for (
int groupIndex : allGroup )
2306 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2309 datasetIndexList.append( groupIndex );
2316 double scalarDoubleValue = 0.0;
2318 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2320 if ( !index.isValid() )
2324 QMap<QString, QString> derivedAttributes;
2326 QMap<QString, QString> attribute;
2330 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2331 scalarDoubleValue = scalarValue.
scalar();
2332 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2337 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2338 const double vectorX = vectorValue.
x();
2339 const double vectorY = vectorValue.
y();
2340 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2342 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2346 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2347 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2348 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2355 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2356 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2358 const QString resultName = groupMeta.
name();
2360 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2361 attributeElement.setAttribute( u
"name"_s, resultName );
2366 value = QString::number( scalarDoubleValue );
2369 attributeElement.setAttribute( u
"value"_s, value );
2370 layerElement.appendChild( attributeElement );
2374 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2375 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2378 value = range.
begin().toString( dateFormat );
2382 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2384 attributeElementTime.setAttribute( u
"value"_s, value );
2385 layerElement.appendChild( attributeElementTime );
2391 bool QgsRenderer::featureInfoFromRasterLayer(
2392 QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2413 QgsRasterIdentifyResult identifyResult;
2416 const QgsRectangle extent { mapSettings.
extent() };
2420 throw QgsBadRequestException(
2431 if ( !identifyResult.
isValid() )
2434 QMap<int, QVariant> attributes = identifyResult.
results();
2440 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2441 int gmlVersion = mWmsParameters.infoFormatVersion();
2442 QString typeName = mContext.layerNickname( *layer );
2448 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2450 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2451 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2454 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2455 layerElement.appendChild( elem );
2459 const auto values = identifyResult.
results();
2460 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2462 QVariant value = it.value();
2463 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2469 if ( value.userType() == QMetaType::Type::QString )
2477 for (
const QgsFeatureStore &featureStore : featureStoreList )
2480 for (
const QgsFeature &feature : storeFeatures )
2482 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2483 layerElement.appendChild( elem );
2493 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2495 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2496 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2501 value = QString::number( it.value().toDouble() );
2504 attributeElement.setAttribute( u
"value"_s, value );
2505 layerElement.appendChild( attributeElement );
2510 const auto values = identifyResult.
results();
2511 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2513 QVariant value = it.value();
2514 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2520 if ( value.userType() == QMetaType::Type::QString )
2527 for (
const QgsFeatureStore &featureStore : featureStoreList )
2530 for (
const QgsFeature &feature : storeFeatures )
2532 for (
const auto &fld : feature.
fields() )
2534 const auto val { feature.
attribute( fld.name() ) };
2535 if ( val.isValid() )
2537 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2538 attributeElement.setAttribute( u
"name"_s, fld.name() );
2539 attributeElement.setAttribute( u
"value"_s, val.toString() );
2540 layerElement.appendChild( attributeElement );
2551 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2552 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2555 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2558 layerElement.appendChild( maptipElem );
2564 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2567 if ( filter.contains(
";"_L1 ) )
2572 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2573 groupStringList( tokens, u
"'"_s );
2574 groupStringList( tokens, u
"\""_s );
2576 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2579 if ( tokenIt->compare(
','_L1 ) == 0
2580 || tokenIt->compare(
'('_L1 ) == 0
2581 || tokenIt->compare(
')'_L1 ) == 0
2582 || tokenIt->compare(
'='_L1 ) == 0
2583 || tokenIt->compare(
"!="_L1 ) == 0
2584 || tokenIt->compare(
'<'_L1 ) == 0
2585 || tokenIt->compare(
"<="_L1 ) == 0
2586 || tokenIt->compare(
'>'_L1 ) == 0
2587 || tokenIt->compare(
">="_L1 ) == 0
2588 || tokenIt->compare(
'%'_L1 ) == 0
2589 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2590 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2591 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2592 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2593 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2594 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2595 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2596 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2597 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2598 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2599 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2606 ( void ) tokenIt->toDouble( &isNumeric );
2615 if ( *tokenIt ==
"''"_L1 )
2621 if ( tokenIt->size() > 2
2622 && ( *tokenIt )[0] == QChar(
'\'' )
2623 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2624 && ( *tokenIt )[1] != QChar(
'\'' )
2625 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2631 if ( tokenIt->size() > 2 && ( *tokenIt )[0] == QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' ) && ( *tokenIt )[1] != QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2642 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2645 bool groupActive =
false;
2646 int startGroup = -1;
2647 QString concatString;
2649 for (
int i = 0; i < list.size(); ++i )
2651 QString &str = list[i];
2652 if ( str.startsWith( groupString ) )
2656 concatString.clear();
2661 if ( i != startGroup )
2663 concatString.append(
" " );
2665 concatString.append( str );
2668 if ( str.endsWith( groupString ) )
2671 groupActive =
false;
2673 if ( startGroup != -1 )
2675 list[startGroup] = concatString;
2676 for (
int j = startGroup + 1; j <= endGroup; ++j )
2678 list.removeAt( startGroup + 1 );
2683 concatString.clear();
2689 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2691 QDomDocument SIAInfoDoc;
2692 QDomElement infoDocElement = doc.documentElement();
2693 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2694 SIAInfoDoc.appendChild( SIAInfoDocElement );
2696 QString currentAttributeName;
2697 QString currentAttributeValue;
2698 QDomElement currentAttributeElem;
2699 QString currentLayerName;
2700 QDomElement currentLayerElem;
2701 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2702 for (
int i = 0; i < layerNodeList.size(); ++i )
2704 currentLayerElem = layerNodeList.at( i ).toElement();
2705 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2707 QDomElement currentFeatureElem;
2709 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2710 if ( featureList.isEmpty() )
2713 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2714 QDomElement rasterLayerElem;
2715 if ( !attributeList.isEmpty() )
2717 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2719 for (
int j = 0; j < attributeList.size(); ++j )
2721 currentAttributeElem = attributeList.at( j ).toElement();
2722 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2723 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2724 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2725 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2726 outAttributeElem.appendChild( outAttributeText );
2727 rasterLayerElem.appendChild( outAttributeElem );
2729 if ( !attributeList.isEmpty() )
2731 SIAInfoDocElement.appendChild( rasterLayerElem );
2737 QSet<QString> layerPropertyAttributes;
2738 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2739 if ( !currentLayerId.isEmpty() )
2741 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2744 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2745 if ( !WMSPropertyAttributesString.isEmpty() )
2747 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2748 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2750 layerPropertyAttributes.insert( *propertyIt );
2756 QDomElement propertyRefChild;
2757 for (
int j = 0; j < featureList.size(); ++j )
2759 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2760 currentFeatureElem = featureList.at( j ).toElement();
2761 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2763 for (
int k = 0; k < attributeList.size(); ++k )
2765 currentAttributeElem = attributeList.at( k ).toElement();
2766 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2767 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2768 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2770 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2771 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2772 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2773 identifierElem.appendChild( identifierText );
2774 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2775 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2776 valueElem.appendChild( valueText );
2777 propertyElem.appendChild( identifierElem );
2778 propertyElem.appendChild( valueElem );
2779 if ( propertyRefChild.isNull() )
2781 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2782 propertyRefChild = propertyElem;
2786 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2791 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2792 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2793 SIAAttributeElem.appendChild( SIAAttributeText );
2794 SIAFeatureElem.appendChild( SIAAttributeElem );
2797 SIAInfoDocElement.appendChild( SIAFeatureElem );
2804 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2807 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2810 featureInfoString.append( QStringLiteral( R
"HTML(
2813 <title>Information</title>
2814 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2817 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2824 border: 1px solid black;
2825 border-collapse: collapse;
2846 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2849 for (
int i = 0; i < layerList.size(); ++i )
2851 const QDomElement layerElem = layerList.at( i ).toElement();
2854 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2855 const QDomElement currentFeatureElement;
2857 if ( !featureNodeList.isEmpty() )
2861 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2862 featureInfoString.append( featureInfoLayerTitleString );
2865 for (
int j = 0; j < featureNodeList.size(); ++j )
2867 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2870 featureInfoString.append( QStringLiteral( R
"HTML(
2875 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2876 for (
int k = 0; k < attributeNodeList.size(); ++k )
2878 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2879 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2880 QString value = attributeElement.attribute( u
"value"_s );
2881 if ( name !=
"maptip"_L1 )
2883 value = value.toHtmlEscaped();
2888 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2893 .arg( name, value );
2895 featureInfoString.append( featureInfoAttributeString );
2897 else if ( name ==
"maptip"_L1 )
2899 featureInfoString.append( QStringLiteral( R
"HTML(
2907 featureInfoString.append( QStringLiteral( R
"HTML(
2914 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2917 if ( !attributeNodeList.isEmpty() )
2921 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2922 featureInfoString.append( featureInfoLayerTitleString );
2924 featureInfoString.append( QStringLiteral( R
"HTML(
2928 for (
int j = 0; j < attributeNodeList.size(); ++j )
2930 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2931 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2932 QString value = attributeElement.attribute( u
"value"_s );
2933 if ( value.isEmpty() )
2935 value = u
"no data"_s;
2937 if ( name !=
"maptip"_L1 )
2939 value = value.toHtmlEscaped();
2944 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2949 .arg( name, value );
2952 featureInfoString.append( featureInfoAttributeString );
2954 else if ( name ==
"maptip"_L1 )
2956 featureInfoString.append( QStringLiteral( R
"HTML(
2964 featureInfoString.append( QStringLiteral( R
"HTML(
2974 featureInfoString.append( QStringLiteral( R
"HTML(
2978 return featureInfoString.toUtf8();
2981 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2983 QString featureInfoString;
2986 featureInfoString.append(
"GetFeatureInfo results\n" );
2987 featureInfoString.append(
"\n" );
2989 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2992 for (
int i = 0; i < layerList.size(); ++i )
2994 QDomElement layerElem = layerList.at( i ).toElement();
2996 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2999 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
3000 QDomElement currentFeatureElement;
3002 if ( !featureNodeList.isEmpty() )
3004 for (
int j = 0; j < featureNodeList.size(); ++j )
3006 QDomElement featureElement = featureNodeList.at( j ).toElement();
3007 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
3010 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
3011 for (
int k = 0; k < attributeNodeList.size(); ++k )
3013 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
3014 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
3020 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
3021 for (
int j = 0; j < attributeNodeList.size(); ++j )
3023 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
3024 QString value = attributeElement.attribute( u
"value"_s );
3025 if ( value.isEmpty() )
3027 value = u
"no data"_s;
3029 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
3033 featureInfoString.append(
"\n" );
3036 return featureInfoString.toUtf8();
3039 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
3041 json jsonCollection {
3042 {
"type",
"FeatureCollection" },
3043 {
"features", json::array() },
3047 const bool withDisplayName = mWmsParameters.withDisplayName();
3049 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
3050 for (
int i = 0; i < layerList.size(); ++i )
3052 const QDomElement layerElem = layerList.at( i ).toElement();
3053 const QString layerName = layerElem.attribute( u
"name"_s );
3055 QgsMapLayer *layer =
nullptr;
3056 for ( QgsMapLayer *l : layers )
3058 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3069 QStringList requestedWmsNames = mContext.acceptableLayersToRender().value( layer );
3070 requestedWmsNames.removeAll( layerName );
3071 QString requestedWmsName;
3072 if ( !requestedWmsNames.isEmpty() )
3074 requestedWmsName = requestedWmsNames.first();
3079 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3084 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3085 if ( featuresNode.isEmpty() )
3088 QMap<QgsFeatureId, QString> fidMap;
3089 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3091 for (
int j = 0; j < featuresNode.size(); ++j )
3093 const QDomElement featureNode = featuresNode.at( j ).toElement();
3094 const QString fid = featureNode.attribute( u
"id"_s );
3097 if ( expression.isEmpty() )
3099 feature = vl->
getFeature( fid.toLongLong() );
3103 QgsFeatureRequest request { QgsExpression( expression ) };
3108 fidMap.insert( feature.
id(), fid );
3113 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3114 for (
int k = 0; k < attrs.count(); k++ )
3116 const QDomElement elm = attrs.at( k ).toElement();
3117 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3119 wkt = elm.attribute(
"value" );
3124 if ( !wkt.isEmpty() )
3132 if ( withDisplayName )
3134 QString displayName;
3135 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3136 for (
int k = 0; k < attrs.count(); k++ )
3138 const QDomElement elm = attrs.at( k ).toElement();
3139 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3141 displayName = elm.attribute(
"value" );
3145 fidDisplayNameMap.insert( feature.
id(), displayName );
3148 features << feature;
3151 if ( !attributes.isEmpty() )
3154 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3155 for (
int k = 0; k < attributesNode.size(); ++k )
3157 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3158 const QString fieldName = attributeElement.attribute( u
"name"_s );
3159 attributes << feature.fieldNameIndex( fieldName );
3164 QgsJsonExporter exporter( vl );
3165 exporter.setAttributeDisplayName(
true );
3166 exporter.setAttributes( attributes );
3167 exporter.setIncludeGeometry( withGeometry );
3171 exporter.setTransformGeometries(
false );
3172 exporter.setDestinationCrs( destCRS );
3174 exporter.setSourceCrs( destCRS );
3178 for (
const auto &feature : std::as_const( features ) )
3180 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3181 QVariantMap extraProperties;
3182 if ( withDisplayName )
3184 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3186 QVariantMap extraMembers;
3190 if ( !requestedWmsName.isEmpty() )
3195 jsonCollection[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id, extraMembers ) );
3200 auto properties = json::object();
3201 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3202 for (
int j = 0; j < attributesNode.size(); ++j )
3204 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3205 const QString name = attrElmt.attribute( u
"name"_s );
3207 QString value = attrElmt.attribute( u
"value"_s );
3208 if ( value.isEmpty() )
3213 properties[name.toStdString()] = value.toStdString();
3216 json jsonFeature = { {
"type",
"Feature" }, {
MEMBERNAME_FEATURETYPE, layerName.toStdString() }, {
"id", layerName.toStdString() }, {
"properties", properties } };
3218 if ( !requestedWmsName.isEmpty() )
3222 jsonCollection[
"features"].push_back( jsonFeature );
3227 return QByteArray::fromStdString( jsonCollection.dump( 2 ) );
3229 return QByteArray::fromStdString( jsonCollection.dump() );
3233 QDomElement QgsRenderer::createFeatureGML(
3234 const QgsFeature *feat, QgsVectorLayer *layer, QDomDocument &doc, QgsCoordinateReferenceSystem &crs,
const QgsMapSettings &mapSettings,
const QString &typeName,
bool withGeom,
int version, QStringList *attributes
3238 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3245 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3247 QgsCoordinateTransform transform;
3248 if ( layer && layer->
crs() != crs )
3253 QgsGeometry geom = feat->
geometry();
3255 QgsExpressionContext expressionContext;
3261 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3275 catch ( QgsCsException &e )
3281 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3282 QDomElement boxElem;
3294 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3296 bbElem.appendChild( boxElem );
3297 typeNameElement.appendChild( bbElem );
3301 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3302 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3303 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3306 const QList<QgsAttributeEditorElement *> children = container->
children();
3307 for (
const QgsAttributeEditorElement *child : children )
3309 switch ( child->type() )
3313 if ( findAttributeInTree( attributeName, child ) )
3321 if ( child->name() == attributeName )
3329 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3330 if ( relationEditor )
3332 const QgsRelation &relation { relationEditor->
relation() };
3336 for (
const auto &idx : std::as_const( referencedFields ) )
3338 const QgsField f { layer->
fields().
at( idx ) };
3339 if ( f.
name() == attributeName )
3348 for (
const auto &idx : std::as_const( referencingFields ) )
3350 const QgsField f { layer->
fields().
at( idx ) };
3351 if ( f.
name() == attributeName )
3368 if ( withGeom && !geom.
isNull() )
3377 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3378 QDomElement gmlElem;
3388 if ( !gmlElem.isNull() )
3392 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3394 geomElem.appendChild( gmlElem );
3395 typeNameElement.appendChild( geomElem );
3400 QgsAttributes featureAttributes = feat->
attributes();
3401 QgsFields fields = feat->
fields();
3402 for (
int i = 0; i < fields.
count(); ++i )
3404 QString attributeName = fields.
at( i ).
name();
3411 if ( attributes && !attributes->contains( attributeName ) )
3416 if ( honorFormConfig )
3419 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3425 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3430 fieldElem.setAttribute(
"xsi:nil"_L1,
"true"_L1 );
3434 QString fieldTextString = featureAttributes.at( i ).toString();
3439 QDomText fieldText = doc.createTextNode( fieldTextString );
3440 fieldElem.appendChild( fieldText );
3442 typeNameElement.appendChild( fieldElem );
3453 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3454 QDomText maptipText = doc.createTextNode( fieldTextString );
3455 fieldElem.appendChild( maptipText );
3456 typeNameElement.appendChild( fieldElem );
3460 return typeNameElement;
3463 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3467 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3469 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3471 value = value.mid( 1, value.size() - 2 );
3476 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3480 return QgsRectangle();
3483 double mapUnitTolerance = 0.0;
3486 if ( !mWmsParameters.polygonTolerance().isEmpty() && mWmsParameters.polygonToleranceAsInt() > 0 )
3492 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3497 if ( !mWmsParameters.lineTolerance().isEmpty() && mWmsParameters.lineToleranceAsInt() > 0 )
3503 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3508 if ( !mWmsParameters.pointTolerance().isEmpty() && mWmsParameters.pointToleranceAsInt() > 0 )
3514 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3521 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3525 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3527 QList<QgsMapLayer *> highlightLayers;
3530 QString crs = mWmsParameters.crs();
3531 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3534 QDomDocument sldDoc;
3538 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3545 std::unique_ptr<QgsFeatureRenderer> renderer;
3546 QDomElement el = sldDoc.documentElement();
3556 QString url = typeName +
"?crs=" + crs;
3557 if ( !param.mLabel.isEmpty() )
3559 url +=
"&field=label:string";
3564 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3571 QgsFeature fet( layer->
fields() );
3572 if ( !param.mLabel.isEmpty() )
3574 fet.setAttribute( 0, param.mLabel );
3577 QgsPalLayerSettings palSettings;
3582 palSettings.
dist = param.mLabelDistance;
3591 switch ( param.mGeom.type() )
3602 QgsPointXY pt = param.mGeom.asPoint();
3604 QVariant x( pt.
x() );
3607 QVariant y( pt.
y() );
3619 QgsGeometry point = param.mGeom.pointOnSurface();
3620 QgsPointXY pt = point.
asPoint();
3624 QVariant x( pt.
x() );
3628 QVariant y( pt.
y() );
3632 QVariant hali(
"Center" );
3636 QVariant vali(
"Half" );
3648 QgsTextFormat textFormat;
3649 QgsTextBufferSettings bufferSettings;
3651 if ( param.mColor.isValid() )
3653 textFormat.
setColor( param.mColor );
3656 if ( param.mSize > 0 )
3658 textFormat.
setSize( param.mSize );
3666 if ( !param.mFont.isEmpty() )
3668 textFormat.
setFont( param.mFont );
3671 if ( param.mBufferColor.isValid() )
3673 bufferSettings.
setColor( param.mBufferColor );
3676 if ( param.mBufferSize > 0 )
3679 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3682 if ( param.mFrameSize > 0 )
3684 QgsTextBackgroundSettings background;
3686 background.
setSize( QSize( param.mFrameSize, param.mFrameSize ) );
3690 background.
setFillColor( param.mFrameBackgroundColor );
3697 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3701 fet.setGeometry( param.mGeom );
3710 highlightLayers.append( layer.release() );
3714 mTemporaryLayers.append( highlightLayers );
3715 return highlightLayers;
3718 void QgsRenderer::removeTemporaryLayers()
3720 qDeleteAll( mTemporaryLayers );
3721 mTemporaryLayers.clear();
3724 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3726 QPainter *painter =
nullptr;
3728 QgsFeatureFilterProviderGroup filters;
3730#ifdef HAVE_SERVER_PYTHON_PLUGINS
3731 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3734 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters, mContext.perLayerTemporalRange() );
3736 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3737 painter = renderJob.takePainter();
3739 logRenderingErrors( renderJob.errors() );
3741 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3743 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3745 QString layerWMSName;
3746 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3749 layerWMSName = mContext.layerNickname( *errorLayer );
3752 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3753 if ( !layerWMSName.isEmpty() )
3755 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3757 throw QgsException( errorMessage );
3763 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3765 if ( opacity >= 0 && opacity <= 255 )
3767 switch ( layer->
type() )
3771 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3776 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3784 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3785 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3786 rasterRenderer->
setOpacity( opacity / 255. );
3792 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3808 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3812 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3813 QStringList expList;
3814 for (
const QgsWmsParametersFilter &filter : filters )
3819 QDomDocument filterXml;
3821 QXmlStreamReader xmlReader( filter.mFilter );
3822 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3823 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3824 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3826 throw QgsBadRequestException(
3828 u
"Filter string rejected. Error %1:%2 : %3. The XML string was: %4"_s.arg( QString::number( result.errorLine ), QString::number( result.errorColumn ), result.errorMessage, filter.mFilter )
3832 QDomElement filterElem = filterXml.firstChildElement();
3837 expList << filterExp->dump();
3843 if ( !testFilterStringSafety( filter.mFilter ) )
3845 throw QgsSecurityException(
3847 "The filter string %1"
3848 " has been rejected because of security reasons."
3849 " Note: Text strings have to be enclosed in single or double quotes."
3850 " A space between each word / special character is mandatory."
3851 " Allowed Keywords and special characters are"
3852 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3853 " Not allowed are semicolons in the filter expression."
3855 .arg( filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' ) )
3859 QString newSubsetString = filter.mFilter;
3862 newSubsetString.prepend(
") AND (" );
3863 newSubsetString.append(
")" );
3864 newSubsetString.prepend( filteredLayer->
subsetString() );
3865 newSubsetString.prepend(
"(" );
3875 expList.append( dimensionFilter( filteredLayer ) );
3879 if ( expList.size() == 1 )
3883 else if ( expList.size() > 1 )
3885 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3887 if ( !exp.isEmpty() )
3889 auto expression = std::make_unique<QgsExpression>( exp );
3893 mFeatureFilter.setFilter( filteredLayer, *expression );
3900 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3902 QStringList expList;
3904 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3905 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3906 if ( wmsDims.isEmpty() )
3911 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3912 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3921 if ( fieldIndex == -1 )
3926 int endFieldIndex = -1;
3927 if ( !dim.endFieldName.isEmpty() )
3929 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3930 if ( endFieldIndex == -1 )
3936 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3946 defValue = dim.referenceValue();
3951 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3952 if ( endFieldIndex != -1 )
3954 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3957 QList<QVariant> values = qgis::setToList( uniqueValues );
3958 std::sort( values.begin(), values.end() );
3961 defValue = values.first();
3965 defValue = values.last();
3969 if ( endFieldIndex == -1 )
3975 QStringList expElems;
3984 expList << expElems.join(
' ' );
3990 QgsField dimField = layer->
fields().
at( fieldIndex );
3992 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3994 QStringList dimExplist;
3996 QStringList dimValues = dimParamValue.split(
',' );
3997 for (
int i = 0; i < dimValues.size(); ++i )
3999 QString dimValue = dimValues[i];
4001 if ( dimValue.size() > 1 )
4003 dimValue = dimValue.trimmed();
4006 if ( dimValue.contains(
'/' ) )
4008 QStringList rangeValues = dimValue.split(
'/' );
4010 if ( rangeValues.size() != 2 )
4015 QVariant rangeMin = QVariant( rangeValues[0] );
4016 QVariant rangeMax = QVariant( rangeValues[1] );
4027 QStringList expElems;
4028 if ( endFieldIndex == -1 )
4063 dimExplist << expElems.join(
' ' );
4067 QVariant dimVariant = QVariant( dimValue );
4073 if ( endFieldIndex == -1 )
4082 QStringList expElems;
4091 dimExplist << expElems.join(
' ' );
4096 if ( dimExplist.size() == 1 )
4098 expList << dimExplist;
4100 else if ( dimExplist.size() > 1 )
4102 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
4109 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4113 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4115 QgsFeatureRequest request;
4119 if ( selectedIds.empty() )
4130 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4132#ifdef HAVE_SERVER_PYTHON_PLUGINS
4139 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4142 QgsRectangle mapExtent = mapSettings.
extent();
4150 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4152 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4153 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4157 renderContext.
setFeedback( mContext.socketFeedback() );
4159 for ( QgsAnnotation *annotation : annotations )
4161 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4163 if ( !annotation || !annotation->isVisible() )
4169 if ( annotation->hasFixedMapPosition() )
4171 QgsPointXY mapPos = annotation->mapPosition();
4172 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4177 mapPos = coordTransform.transform( mapPos );
4179 catch (
const QgsCsException &e )
4185 offsetX = devicePos.
x();
4186 offsetY = devicePos.
y();
4190 const QPointF relativePos = annotation->relativePosition();
4191 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4192 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4195 QgsScopedQPainterState painterState( painter );
4196 painter->translate( offsetX, offsetY );
4197 annotation->render( renderContext );
4201 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4206 QImage *scaledImage =
nullptr;
4207 const int width = mWmsParameters.widthAsInt();
4208 const int height = mWmsParameters.heightAsInt();
4209 if ( width != image->width() || height != image->height() )
4211 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4219 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4220 for ( ; it != errors.constEnd(); ++it )
4222 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4223 if ( !it->layerID.isEmpty() )
4225 msg += QString(
" in layer %1" ).arg( it->layerID );
4231 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4238 QList<QgsLayoutItemMap *> mapList;
4242 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4243 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4245 logRenderingErrors( ( *mapIt )->renderingErrors() );
4248 if ( mContext.settings().ignoreRenderingErrors() )
4253 mapIt = mapList.constBegin();
4254 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4256 if ( !( *mapIt )->renderingErrors().isEmpty() )
4258 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4259 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4266 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4268 for (
auto layer : layers )
4270 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4272 if ( !mContext.layersToRender().contains( layer ) )
4277 if ( mContext.isExternalLayer( param.mNickname ) )
4281 setLayerOpacity( layer, param.mOpacity );
4288 setLayerSld( layer, mContext.sld( *layer ) );
4292 setLayerStyle( layer, mContext.style( *layer ) );
4297 setLayerOpacity( layer, param.mOpacity );
4302 setLayerFilter( layer, param.mFilter );
4307 setLayerAccessControlFilter( layer );
4312 setLayerSelection( layer, param.mSelection );
4315 if ( settings && mContext.updateExtent() )
4317 updateExtent( layer, *settings );
4323 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4327 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4329 if ( style.isEmpty() )
4341 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4346 QString sldStyleName =
"__sld_style";
4347 while ( styles.contains( sldStyleName ) )
4349 sldStyleName.append(
'@' );
4357 QgsLegendSettings QgsRenderer::legendSettings()
4360 QgsLegendSettings settings = mWmsParameters.legendSettings();
4362 if ( !mWmsParameters.bbox().isEmpty() )
4364 QgsMapSettings mapSettings;
4366 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4367 configureMapSettings( tmp.get(), mapSettings );
static QString version()
Version string.
@ MapOrientation
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
@ AboveLine
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
@ Millimeters
Millimeters.
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ VisibleLayers
Synchronize to map layers. The legend will include layers which are included in the linked map only.
@ AllProjectLayers
Synchronize to all project layers.
@ Manual
No automatic synchronization of legend layers. The legend will be manually populated.
@ DragAndDrop
"Drag and drop" layout. Needs to be configured.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ NoFlags
No flags are set.
@ Warning
Warning message.
@ Critical
Critical/error message.
@ Info
Information message.
QFlags< LabelLinePlacementFlag > LabelLinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
@ ShowRuleDetails
If set, the rule expression of a rule based renderer legend item will be added to the JSON.
@ IdentifyValue
Numerical values.
@ IdentifyFeature
WMS GML -> feature.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Use antialiasing while drawing.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
static const double DEFAULT_SEARCH_RADIUS_MM
Identify search radius in mm.
QFlags< LegendJsonRenderFlag > LegendJsonRenderFlags
@ MinValue
Display minimum value of the dimension.
@ AllValues
Display all values of the dimension.
@ MaxValue
Display maximum value of the dimension.
@ ReferenceValue
Display a reference value.
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
RasterIdentifyFormat
Raster identify formats.
@ Feature
WMS GML/JSON -> feature.
@ Value
Numerical pixel value.
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
@ AllowOverlapIfRequired
Avoids overlapping labels when possible, but permit overlaps if labels for features cannot otherwise ...
@ Reverse
Reverse/inverse transform (from destination to source).
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ RecordProfile
Enable run-time profiling while rendering.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ DisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ DrawSelection
Draw selection.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
QList< QgsAnnotation * > annotations() const
Returns a list of all annotations contained in the manager.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QString name() const
Returns the name of this element.
const QgsRelation & relation() const
Gets the id of the relation which shall be embedded.
Exception thrown in case of malformed requests.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Qgis::DistanceUnit mapUnits
bool hasAxisInverted() const
Returns whether the axis order is inverted for the CRS compared to the order east/north (longitude/la...
A server filter to apply a dimension filter to a request.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
@ FlagHairlineWidthExport
Export all lines with minimum width and don't fill polygons.
@ FlagNoMText
Export text as TEXT elements. If not set, text will be exported as MTEXT elements.
Defines a QGIS exception class.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
QString expression() const
Returns the original, unmodified expression string.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
QVariant evaluate()
Evaluate the feature and return the result.
bool isValid() const
Checks if this expression is valid.
A filter filter provider grouping several filter providers.
QgsFeatureFilterProviderGroup & addProvider(const QgsFeatureFilterProvider *provider)
Add another filter provider to the group.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
static std::unique_ptr< QgsFeatureRenderer > loadSld(const QDomNode &node, Qgis::GeometryType geomType, QString &errorMessage)
Create a new renderer according to the information contained in the UserStyle element of a SLD style ...
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
Qgis::FeatureRequestFlags flags() const
Returns the flags which affect how features are fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Qgis::FieldConfigurationFlags configurationFlags
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
static void addCrsInfo(json &value, const QgsCoordinateReferenceSystem &crs, Qgis::GeoJsonProfile profile=Qgis::GeoJsonProfile::Legacy)
Add crs information entry in json object regarding old GeoJSON specification format if it differs fro...
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
void removeChildrenGroupWithoutLayers()
Remove all child group nodes without layers.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
@ RuleKey
Rule key of the node (QString).
virtual QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const
Draws symbol on the left side of the item.
A model representing the layer tree, including layers and groups of layers.
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
QgsLayerTreeModelLegendNode * findLegendNode(const QString &layerId, const QString &ruleKey) const
Searches through the layer tree to find a legend node with a matching layer ID and rule key.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
bool beginRender() override
Called when rendering begins, before iteration commences.
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
bool first()
Seeks to the first feature, returning false if no feature was found.
QgsLayout * layout() override
Returns the layout associated with the iterator.
bool enabled() const
Returns whether the atlas generation is enabled.
int count() const override
Returns the number of features to iterate over.
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
Handles rendering and exports of layouts to various formats.
ExportResult exportToSvg(const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings)
Exports the layout as an SVG to the filePath, using the specified export settings.
ExportResult exportToImage(const QString &filePath, const QgsLayoutExporter::ImageExportSettings &settings)
Exports the layout to the filePath, using the specified export settings.
ExportResult exportToPdf(const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings)
Exports the layout as a PDF to the filePath, using the specified export settings.
@ ManualHtml
HTML content is manually set for the item.
@ Url
Using this mode item fetches its content via a url.
Layout graphical items for displaying a map.
double scale() const
Returns the map scale.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
QString id() const
Returns the item's ID name.
Manages storage of a set of layouts.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
double length() const
Returns the length of the measurement.
int pageCount() const
Returns the number of pages in the collection.
Stores information relating to the current rendering settings for a layout.
void setFeatureFilterProvider(QgsFeatureFilterProvider *featureFilterProvider)
Sets feature filter provider to featureFilterProvider.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
static QVector< double > predefinedScales(const QgsLayout *layout)
Returns a list of predefined scales associated with a layout.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Handles automatic layout and rendering of legends.
QSizeF minimumSize(QgsRenderContext *renderContext=nullptr)
Runs the layout algorithm and returns the minimum size required for the legend.
QJsonObject exportLegendToJson(const QgsRenderContext &context)
Renders the legend in a json object.
Q_DECL_DEPRECATED void drawLegend(QPainter *painter)
Draws the legend with given painter.
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
Q_DECL_DEPRECATED void setMapScale(double scale)
Sets the legend map scale.
Q_DECL_DEPRECATED void setMapUnitsPerPixel(double mapUnitsPerPixel)
Sets the mmPerMapUnit calculated by mapUnitsPerPixel mostly taken from the map settings.
void setJsonRenderFlags(const Qgis::LegendJsonRenderFlags &jsonRenderFlags)
Sets the JSON export flags to jsonRenderFlags.
void setWmsLegendSize(QSizeF s)
Sets the desired size (in millimeters) of WMS legend graphics shown in the legend.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual bool readSld(const QDomNode &node, QString &errorMessage)
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QList< QgsMapRendererJob::Error > Errors
Contains configuration for rendering maps.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setSelectiveMaskingSourceSets(const QVector< QgsSelectiveMaskingSourceSet > &sets)
Sets a list of all selective masking source sets defined for the map.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QColor selectionColor() const
Returns the color that is used for drawing of selected vector features.
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
QString ellipsoid() const
Returns ellipsoid's acronym.
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QList< QgsMapThemeCollection::MapThemeLayerRecord > layerRecords() const
Returns a list of records for all visible layer belonging to the theme.
QgsMapThemeCollection::MapThemeRecord mapThemeState(const QString &name) const
Returns the recorded state of a map theme.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
void updateTriangularMesh(const QgsCoordinateTransform &transform=QgsCoordinateTransform())
Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh.
QgsMeshDatasetIndex staticVectorDatasetIndex(int group=-1) const
Returns the static vector dataset index that is rendered if the temporal properties is not active.
QList< int > enabledDatasetGroupsIndexes() const
Returns the list of indexes of enables dataset groups handled by the layer.
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset metadata.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetIndex datasetIndexAtTime(const QgsDateTimeRange &timeRange, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the time range.
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsMeshDatasetIndex activeScalarDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active scalar group depending on the time range.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshDatasetIndex staticScalarDatasetIndex(int group=-1) const
Returns the static scalar dataset index that is rendered if the temporal properties is not active.
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
static QDomElement rectangleToGMLEnvelope(const QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static QDomElement geometryToGML(const QgsGeometry &geometry, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
static QDomElement rectangleToGMLBox(const QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
Qgis::LabelPlacement placement
Label placement mode.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
int priority
Label priority.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
double dist
Distance from feature to the label.
Property
Data definable properties.
@ PositionX
X-coordinate data defined label position.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top).
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right).
QString fieldName
Name of field (or an expression) to use for label text.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsPrintLayout * clone() const override
Creates a clone of the layout.
Describes the version of a project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsMapThemeCollection * mapThemeCollection
QgsProjectMetadata metadata
QgsCoordinateTransformContext transformContext
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, Qgis::RasterIdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
bool isValid() const
Returns true if valid.
QMap< int, QVariant > results() const
Returns the identify results.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QString bandName(int bandNoInt) const
Returns the name of a band given its number.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
QList< int > referencedFields
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QList< int > referencingFields
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setDistanceArea(const QgsDistanceArea &distanceArea)
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly during rendering to check if rendering should ...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Scoped object for temporary scaling of a QgsRenderContext for millimeter based rendering.
static QgsDateTimeRange parseTemporalDateTimeInterval(const QString &interval)
Parses a datetime interval and returns a QgsDateTimeRange.
Exception base class for server exceptions.
static QString getExpressionFromServerFid(const QString &serverFid, const QgsVectorDataProvider *provider)
Returns the expression feature id based on primary keys.
static QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
static QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
static QString wmsFeatureInfoSchema(const QgsProject &project)
Returns the schema URL for XML GetFeatureInfo request.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static bool wmsHTMLFeatureInfoUseOnlyMaptip(const QgsProject &project)
Returns if only the maptip should be used for HTML feature info response so that the HTML response to...
static QString wmsFeatureInfoDocumentElementNs(const QgsProject &project)
Returns the document element namespace for XML GetFeatureInfo request.
static QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
static bool wmsFeatureInfoSegmentizeWktGeometry(const QgsProject &project)
Returns if the geometry has to be segmentize in GetFeatureInfo request.
static bool wmsFeatureInfoUseAttributeFormSettings(const QgsProject &project)
Returns if feature form settings should be considered for the format of the feature info response.
static QHash< QString, QString > wmsFeatureInfoLayerAliasMap(const QgsProject &project)
Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
static bool wmsFeatureInfoAddWktGeometry(const QgsProject &project)
Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
static double wmsDefaultMapUnitsPerMm(const QgsProject &project)
Returns the default number of map units per millimeters in case of the scale is not given.
static QString wmsFeatureInfoDocumentElement(const QgsProject &project)
Returns the document element name for XML GetFeatureInfo request.
static int wmsMaxAtlasFeatures(const QgsProject &project)
Returns the maximum number of atlas features which can be printed in a request.
static constexpr const char * TIME_DIMENSION_NAME
const QList< QgsServerWmsDimensionProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
@ Hidden
Hide task from GUI.
bool isActive() const
Returns true if the temporal property is active.
void setIsActive(bool active)
Sets whether the temporal property is active.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
bool isInstant() const
Returns true if the range consists only of a single instant.
void setStrokeColor(const QColor &color)
Sets the color used for outlining the background shape.
@ ShapeRectangle
Rectangle.
void setFillColor(const QColor &color)
Sets the color used for filing the background shape.
void setType(ShapeType type)
Sets the type of background shape to draw (e.g., square, ellipse, SVG).
void setEnabled(bool enabled)
Sets whether the text background will be drawn.
void setSize(QSizeF size)
Sets the size of the background shape.
void setStrokeWidth(double width)
Sets the width of the shape's stroke (stroke).
void setColor(const QColor &color)
Sets the color for the buffer.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
void setSize(double size)
Sets the size of the buffer.
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 setBackground(const QgsTextBackgroundSettings &backgroundSettings)
Sets the text's background settings.q.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Represents a vector layer which manages a vector based dataset.
void setLabeling(QgsAbstractVectorLayerLabeling *labeling)
Sets labeling configuration.
Q_INVOKABLE QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider,...
void setLabelsEnabled(bool enabled)
Sets whether labels should be enabled for the layer.
Q_INVOKABLE void selectByExpression(const QString &expression, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, QgsExpressionContext *context=nullptr)
Selects matching features using an expression.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
void setRenderer(QgsFeatureRenderer *r)
Sets the feature renderer which will be invoked to represent this layer in 2D map views.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, bool validateIds=false)
Selects matching features using a list of feature IDs.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
virtual bool setSubsetString(const QString &subset)
Sets the string (typically sql) used to define a subset of the layer.
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
QgsEditFormConfig editFormConfig
Q_INVOKABLE QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const final
Calculates a list of unique values contained within an attribute in the layer.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Implementation of legend node interface for displaying WMS legend entries.
Exception thrown in case of malformed request.
QgsRenderer(const QgsWmsRenderContext &context)
Constructor for QgsRenderer.
QHash< QgsVectorLayer *, SymbolSet > HitTest
QByteArray getPrint()
Returns printed page as binary.
HitTest symbols()
Returns the hit test according to the current context.
std::unique_ptr< QgsDxfExport > getDxf()
Returns the map as DXF data.
QSet< QString > SymbolSet
void configureLayers(QList< QgsMapLayer * > &layers, QgsMapSettings *settings=nullptr)
Configures layers for rendering optionally considering the map settings.
std::unique_ptr< QgsMapRendererTask > getPdf(const QString &tmpFileName)
Returns a configured pdf export task.
QByteArray getFeatureInfo(const QString &version="1.3.0")
Creates an xml document that describes the result of the getFeatureInfo request.
QImage * getLegendGraphics(QgsLayerTreeModel &model)
Returns the map legend as an image (or nullptr in case of error).
std::unique_ptr< QImage > getMap()
Returns the map as an image (or nullptr in case of error).
QJsonObject getLegendGraphicsAsJson(QgsLayerTreeModel &model, const Qgis::LegendJsonRenderFlags &jsonRenderFlags=Qgis::LegendJsonRenderFlags())
Returns the map legend as a JSON object.
Exception class for WMS service exceptions.
ExceptionCode
Exception codes as defined in OGC scpecifications for WMS 1.1.1 and WMS 1.3.0.
@ QGIS_InvalidParameterValue
@ QGIS_MissingParameterValue
WMS parameter received from the client.
bool transparentAsBool() const
Returns TRANSPARENT parameter as a bool or its default value if not defined.
QString formatAsString() const
Returns FORMAT parameter as a string.
QgsWmsParametersComposerMap composerMapParameters(int mapId) const
Returns the requested parameters for a composer map parameter.
DxfFormatOption
Options for DXF format.
QColor backgroundColorAsColor() const
Returns BGCOLOR parameter as a QColor or its default value if not defined.
Format format() const
Returns format.
Format
Output format for the response.
Rendering context for the WMS renderer.
QList< QgsMapLayer * > layersToRender() const
Returns a list of all layers to actually render according to the current configuration.
void setScaleDenominator(double scaleDenominator)
Sets a custom scale denominator.
Median cut implementation.
constexpr const char * MEMBERNAME_QGIS_REQUESTEDWMSNAME
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
constexpr const char * MEMBERNAME_FEATURETYPE
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
#define FID_TO_STRING(fid)
QVector< QgsFeatureStore > QgsFeatureStoreList
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
QgsAbstractMetadataBase::KeywordMap keywords
Metadata keyword map.
QString creator
Metadata creator tag.
QString author
Metadata author tag.
QString subject
Metadata subject tag.
QString title
Metadata title tag.
QDateTime creationDateTime
Metadata creation datetime.
QString producer
Metadata producer tag.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO32000 extension format georeferencing should be used.
Encapsulates the properties of a vector layer containing features that will be exported to the DXF fi...
QPainter * painter
Painter.
Q_NOWARN_DEPRECATED_POP QgsRenderContext * context
Render context, if available.
Contains settings relating to exporting layouts to raster images.
QList< int > pages
List of specific pages to export, or an empty list to export all pages.
QSize imageSize
Manual size in pixels for output image.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
Contains settings relating to exporting layouts to PDF.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO3200 extension format georeferencing should be used.
bool forceVectorOutput
Set to true to force vector object exports, even when the resultant appearance will differ from the l...
bool rasterizeWholeImage
Set to true to force whole layout to be rasterized while exporting.
QStringList exportThemes
Optional list of map themes to export as Geospatial PDF layer groups.
bool appendGeoreference
Indicates whether PDF export should append georeference data.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
bool writeGeoPdf
true if geospatial PDF files should be created, instead of normal PDF files.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
bool simplifyGeometries
Indicates whether vector geometries should be simplified to avoid redundant extraneous detail,...
Qgis::TextRenderFormat textRenderFormat
Text rendering format, which controls how text should be rendered in the export (e....
Contains settings relating to exporting layouts to SVG.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
QList< QgsWmsParametersLayer > mLayers
QList< QgsWmsParametersHighlightLayer > mHighlightLayers