23#include <nlohmann/json.hpp>
88#include <QTemporaryFile>
90#include <QXmlStreamReader>
92using namespace Qt::StringLiterals;
116 : mContext( context )
118 mProject = mContext.project();
120 mWmsParameters = mContext.parameters();
121 mWmsParameters.dump();
126 removeTemporaryLayers();
132 std::unique_ptr<QgsWmsRestorer> restorer;
133 restorer = std::make_unique<QgsWmsRestorer>( mContext );
136 QList<QgsMapLayer *> layers = mContext.layersToRender();
139 const qreal dpmm = mContext.dotsPerMm();
144 const auto layersToRender = mContext.layersToRender();
145 for (
const auto &layer : std::as_const( layersToRender ) )
148 if ( layer->dataProvider()->name() ==
"wms"_L1 )
152 const auto image { layerNode->getLegendGraphicBlocking() };
153 if ( !image.isNull() )
156 if ( mContext.isValidWidthHeight( image.width(), image.height() ) )
158 const double w = image.width() / dpmm;
159 const double h = image.height() / dpmm;
160 const QSizeF newWmsSize { w, h };
173 if ( !mWmsParameters.bbox().isEmpty() )
177 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
178 configureMapSettings( tmp.get(), mapSettings );
184 context = configureDefaultRenderContext();
188 std::unique_ptr<QImage> image;
189 const QSizeF minSize = renderer.
minimumSize( &context );
190 const QSize size(
static_cast<int>( minSize.width() * dpmm ),
static_cast<int>( minSize.height() * dpmm ) );
191 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
195 image.reset( createImage( size ) );
198 QPainter painter( image.get() );
201 if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
203 if ( painter.renderHints() & QPainter::LosslessImageRendering )
213 return image.release();
219 std::unique_ptr<QgsWmsRestorer> restorer;
220 restorer = std::make_unique<QgsWmsRestorer>( mContext );
223 QList<QgsMapLayer *> layers = mContext.layersToRender();
227 const QSize size( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() );
229 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
233 std::unique_ptr<QImage> image( createImage( size ) );
236 const qreal dpmm = mContext.dotsPerMm();
237 std::unique_ptr<QPainter> painter;
238 painter = std::make_unique<QPainter>( image.get() );
239 painter->setRenderHint( QPainter::Antialiasing,
true );
240 painter->scale( dpmm, dpmm );
251 nodeModel.
drawSymbol( settings, &ctx, size.height() / dpmm );
254 return image.release();
260 std::unique_ptr<QgsWmsRestorer> restorer;
261 restorer = std::make_unique<QgsWmsRestorer>( mContext );
264 QList<QgsMapLayer *> layers = mContext.layersToRender();
280 std::unique_ptr<QgsWmsRestorer> restorer;
281 restorer = std::make_unique<QgsWmsRestorer>( mContext );
284 QList<QgsMapLayer *> layers = mContext.layersToRender();
293 QJsonObject jsonSymbol {
legendNode.exportSymbolToJson( settings, renderContext ) };
300 if ( vLayer->renderer() )
304 const QString ruleExp { vLayer->renderer()->legendKeyToExpression( ruleKey, vLayer, ok ) };
307 jsonSymbol[u
"rule"_s] = ruleExp;
316 void QgsRenderer::runHitTest(
const QgsMapSettings &mapSettings, HitTest &hitTest )
const
320 for (
const QString &
id : mapSettings.
layerIds() )
337 runHitTestLayer( vl, usedSymbols, context );
341 void QgsRenderer::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context )
const
343 std::unique_ptr<QgsFeatureRenderer> r( vl->
renderer()->
clone() );
345 r->startRender( context, vl->
fields() );
347 QgsFeatureRequest request( context.
extent() );
349 QgsFeatureIterator fi = vl->
getFeatures( request );
353 if ( moreSymbolsPerFeature )
355 for ( QgsSymbol *s : r->originalSymbolsForFeature( f, context ) )
361 r->stopRender( context );
367 if ( !mContext.isValidWidthHeight() )
373 std::unique_ptr<QgsWmsRestorer> restorer;
374 restorer = std::make_unique<QgsWmsRestorer>( mContext );
379 QList<QgsMapLayer *> layers = mContext.layersToRender();
383 std::unique_ptr<QPainter> painter;
384 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
387 configureMapSettings( image.get(), mapSettings );
394 runHitTest( mapSettings,
symbols );
402 std::unique_ptr<QgsWmsRestorer> restorer;
403 restorer = std::make_unique<QgsWmsRestorer>( mContext );
406 const QString templateName = mWmsParameters.composerTemplate();
407 if ( templateName.isEmpty() )
430 std::unique_ptr<QgsPrintLayout> layout( sourceLayout->
clone() );
434 QStringList atlasPk = mWmsParameters.atlasPk();
435 if ( !atlasPk.isEmpty() )
437 atlas = layout->atlas();
438 if ( !atlas || !atlas->
enabled() )
451 if ( atlasPk.size() == 1 && atlasPk.at( 0 ) ==
"*"_L1 )
455 if ( atlas->
count() > maxAtlasFeatures )
463 if ( pkIndexes.size() == 0 )
465 QgsDebugMsgLevel( u
"Atlas print: layer %1 has no primary key attributes"_s.arg( cLayer->
name() ), 2 );
469 const int pkIndexesSize { std::max<int>( pkIndexes.size(), 1 ) };
471 QStringList pkAttributeNames;
472 for (
int pkIndex : std::as_const( pkIndexes ) )
474 pkAttributeNames.append( cLayer->
fields().
at( pkIndex ).
name() );
477 const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
478 if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() )
484 if ( nAtlasFeatures > maxAtlasFeatures )
489 QString filterString;
490 int currentAtlasPk = 0;
492 for (
int i = 0; i < nAtlasFeatures; ++i )
496 filterString.append(
" OR " );
499 filterString.append(
"( " );
502 if ( pkAttributeNames.isEmpty() )
504 filterString.append( u
"$id = %1"_s.arg( atlasPk.at( currentAtlasPk ) ) );
509 for (
int j = 0; j < pkIndexes.size(); ++j )
513 filterString.append(
" AND " );
520 filterString.append(
" )" );
528 if ( !errorString.isEmpty() )
530 throw QgsException( u
"An error occurred during the Atlas print: %1"_s.arg( errorString ) );
538 QList<QgsMapLayer *> layers = mContext.layersToRender();
542 auto image = std::make_unique<QImage>();
543 configureMapSettings( image.get(), mapSettings );
549 configurePrintLayout( layout.get(), mapSettings, atlas );
553 const QList<QgsMapLayer *> lyrs = mapSettings.
layers();
555#ifdef HAVE_SERVER_PYTHON_PLUGINS
556 mContext.accessControl()->resolveFilterFeatures( lyrs );
560 QHash<const QgsVectorLayer *, QStringList> fltrs;
565 fltrs.insert( vl, dimensionFilter( vl ) );
577 QTemporaryFile tempOutputFile( QDir::tempPath() +
'/' + u
"XXXXXX.%1"_s.arg( extension ) );
578 if ( !tempOutputFile.open() )
580 throw QgsException( u
"Could not open temporary file for the GetPrint request."_s );
588 if ( !mWmsParameters.dpi().isEmpty() )
591 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
593 exportSettings.
dpi = dpi;
606 atlasSvgExport.
exportToSvg( tempOutputFile.fileName(), exportSettings );
612 exporter.
exportToSvg( tempOutputFile.fileName(), exportSettings );
621 double dpi( layout->renderContext().dpi() );
622 if ( !mWmsParameters.dpi().isEmpty() )
625 double _dpi = mWmsParameters.dpi().toDouble( &ok );
629 exportSettings.
dpi = dpi;
635 QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );
640 const QSize imageSize = QSize(
static_cast<int>( width.
length() * dpi / 25.4 ),
static_cast<int>( height.
length() * dpi / 25.4 ) );
642 const QString paramWidth = mWmsParameters.width();
643 const QString paramHeight = mWmsParameters.height();
648 if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
650 exportSettings.
imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
652 else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
654 exportSettings.
imageSize = QSize( paramWidth.toInt(),
static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
656 else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
658 exportSettings.
imageSize = QSize(
static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
666 exportSettings.
pages.append( 0 );
674 atlasPngExport.
exportToImage( tempOutputFile.fileName(), exportSettings );
678 throw QgsServiceException( u
"Bad request"_s, u
"Atlas error: empty atlas."_s, QString(), 400 );
684 exporter.
exportToImage( tempOutputFile.fileName(), exportSettings );
692 if ( !mWmsParameters.dpi().isEmpty() )
695 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
697 exportSettings.
dpi = dpi;
702 exportSettings.
rasterizeWholeImage = layout->customProperty( u
"rasterize"_s,
false ).toBool();
704 QVector<qreal> requestMapScales = mWmsParameters.pdfPredefinedMapScales();
705 if ( requestMapScales.size() > 0 )
714 QStringList exportThemes = mWmsParameters.pdfExportMapThemes();
715 if ( exportThemes.size() > 0 )
719 exportSettings.
writeGeoPdf = mWmsParameters.writeGeospatialPdf();
725 if ( mWmsParameters.pdfLosslessImageCompression() )
729 if ( mWmsParameters.pdfDisableTiledRasterRendering() )
742 exporter.
exportToPdf( tempOutputFile.fileName(), exportSettings );
752 handlePrintErrors( atlas->
layout() );
756 handlePrintErrors( layout.get() );
759 return tempOutputFile.readAll();
766 QList<QgsLayoutItemMap *> maps;
772 for (
const auto &map : std::as_const( maps ) )
778 if ( cMapParams.
mLayers.isEmpty() )
783 if ( !atlas || !map->atlasDriven() )
789 c->removeLayoutItem( map );
798 QgsRectangle r( cMapParams.
mExtent );
806 if ( cMapParams.
mScale > 0 )
808 map->setScale(
static_cast<double>( cMapParams.
mScale ) );
814 map->setMapRotation( cMapParams.
mRotation );
818 if ( !map->keepLayerSet() )
820 QList<QgsMapLayer *> layerSet;
822 for (
const auto &layer : std::as_const( cMapParams.
mLayers ) )
824 if ( mContext.isValidGroup( layer.mNickname ) )
826 QList<QgsMapLayer *> layersFromGroup;
828 const QList<QgsMapLayer *> cLayersFromGroup = mContext.layersFromGroup( layer.mNickname );
829 for ( QgsMapLayer *layerFromGroup : cLayersFromGroup )
831 if ( !layerFromGroup )
836 layersFromGroup.push_front( layerFromGroup );
839 if ( !layersFromGroup.isEmpty() )
841 layerSet.append( layersFromGroup );
846 QgsMapLayer *mlayer = mContext.layer( layer.mNickname );
853 setLayerStyle( mlayer, layer.mStyle );
858 std::reverse( layerSet.begin(), layerSet.end() );
863 QMap<QString, QString> layersStyle;
864 if ( map->followVisibilityPreset() )
874 const QString presetName = map->followVisibilityPresetName();
875 if ( layerSet.isEmpty() )
878 const QgsExpressionContext ex { map->createExpressionContext() };
879 layerSet = map->layersToRender( &ex );
882 map->setFollowVisibilityPreset(
false );
886 for (
const auto &layerMapThemeRecord : std::as_const( mapThemeRecords ) )
888 if ( layerSet.contains( layerMapThemeRecord.layer() ) )
890 layersStyle.insert( layerMapThemeRecord.layer()->id(), layerMapThemeRecord.layer()->styleManager()->style( layerMapThemeRecord.currentStyle ).xmlData() );
896 const QList<QgsMapLayer *> highlights = highlightLayers( cMapParams.
mHighlightLayers );
897 for (
const auto &hl : std::as_const( highlights ) )
899 layerSet.prepend( hl );
902 map->setLayers( layerSet );
903 map->setKeepLayerSet(
true );
907 if ( !layersStyle.isEmpty() )
909 map->setLayerStyleOverrides( layersStyle );
910 map->setKeepLayerStyles(
true );
917 map->grid()->setIntervalX(
static_cast<double>( cMapParams.
mGridX ) );
918 map->grid()->setIntervalY(
static_cast<double>( cMapParams.
mGridY ) );
923 QList<QgsLayoutItemLabel *> labels;
924 c->layoutItems<QgsLayoutItemLabel>( labels );
925 for (
const auto &label : std::as_const( labels ) )
928 const QString labelId = label->id();
929 const QString labelParam = mWmsParameters.layoutParameter( labelId, ok );
934 if ( labelParam.isEmpty() )
938 c->removeItem( label );
943 label->setText( labelParam );
947 QList<QgsLayoutItemHtml *> htmls;
948 c->layoutObjects<QgsLayoutItemHtml>( htmls );
949 for (
const auto &html : std::as_const( htmls ) )
951 if ( html->frameCount() == 0 )
954 QgsLayoutFrame *htmlFrame = html->frame( 0 );
956 const QString htmlId = htmlFrame->
id();
957 const QString htmlValue = mWmsParameters.layoutParameter( htmlId, ok );
967 if ( htmlValue.isEmpty() )
969 c->removeMultiFrame( html );
976 QUrl newUrl( htmlValue );
977 html->setUrl( newUrl );
981 html->setHtml( htmlValue );
988 QList<QgsLayoutItemLegend *> legends;
989 c->layoutItems<QgsLayoutItemLegend>( legends );
990 for (
const auto &legend : std::as_const( legends ) )
992 switch ( legend->syncMode() )
999 const QgsLayoutItemMap *map = legend->linkedMap();
1008 QgsLegendModel *model = legend->model();
1009 QStringList layerSet;
1010 QList<QgsMapLayer *> mapLayers;
1011 if ( map->
layers().isEmpty() )
1015 mapLayers = mProject->mapLayers(
true ).values();
1019 mapLayers = map->
layers();
1021 const QList<QgsMapLayer *> layerList = mapLayers;
1022 for (
const auto &layer : layerList )
1023 layerSet << layer->id();
1026 QgsLayerTree *root = model->
rootGroup();
1033 for (
const auto &layerId : layerIds )
1035 QgsLayerTreeLayer *nodeLayer = root->
findLayer( layerId );
1040 if ( !layerSet.contains( layerId ) )
1042 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1046 QgsMapLayer *layer = nodeLayer->
layer();
1049 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1067 if ( !mContext.isValidWidthHeight() )
1072 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1078 std::unique_ptr<QgsWmsRestorer> restorer;
1079 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1082 QList<QgsMapLayer *> layers = mContext.layersToRender();
1089 std::unique_ptr<QPainter> painter;
1090 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
1093 configureMapSettings( image.get(), mapSettings );
1099 QPainter *renderedPainter = layersRendering( mapSettings, image.get() );
1100 if ( !renderedPainter )
1105 painter.reset( renderedPainter );
1108 annotationsRendering( painter.get(), mapSettings );
1114 QImage *scaledImage = scaleImage( image.get() );
1116 image.reset( scaledImage );
1119 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1129 QList<QgsMapLayer *> layers = mContext.layersToRender();
1133 const QStringList attributes = mWmsParameters.dxfLayerAttributes();
1134 QList<QgsDxfExport::DxfLayer> dxfLayers;
1146 int layerAttribute = -1;
1147 if ( attributes.size() > layerIdx )
1156 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1158 QString crs = mWmsParameters.crs();
1159 if ( crs.compare( u
"CRS:84"_s, Qt::CaseInsensitive ) == 0 )
1161 crs = u
"EPSG:4326"_s;
1164 else if ( crs.isEmpty() )
1166 crs = u
"EPSG:4326"_s;
1200 auto dxf = std::make_unique<QgsDxfExport>();
1201 dxf->setExtent( mapExtent );
1202 dxf->setDestinationCrs( outputCRS );
1203 dxf->addLayers( dxfLayers );
1204 dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
1205 dxf->setSymbologyExport( mWmsParameters.dxfMode() );
1208 dxf->setSymbologyScale( mWmsParameters.dxfScale() );
1211 dxf->setForce2d( mWmsParameters.isForce2D() );
1213 if ( mWmsParameters.noMText() )
1216 if ( mWmsParameters.exportLinesWithZeroWidth() )
1221 dxf->setFlags( flags );
1229 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1230 ms.
setLayers( mContext.layersToRender() );
1232 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1236 if ( mWmsParameters.pdfExportMetadata() )
1247 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1248 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, u
"PDF"_s,
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1249 if ( mWmsParameters.pdfAppendGeoreference() )
1251 pdf->setSaveWorldFile(
true );
1259 if ( i < 0 || i > mapSettings.
outputSize().width() )
1266 if ( j < 0 || j > mapSettings.
outputSize().height() )
1283 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1289 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1290 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1291 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1292 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1294 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1298 if ( mWmsParameters.j().isEmpty() )
1311 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1314 std::unique_ptr<QgsWmsRestorer> restorer;
1315 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1319 bool mandatoryCrsParam =
true;
1320 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1322 mandatoryCrsParam =
false;
1328 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1332 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1344#ifdef HAVE_SERVER_PYTHON_PLUGINS
1345 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1348 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1353 ba = convertFeatureInfoToText( result );
1355 ba = convertFeatureInfoToHtml( result );
1357 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1359 ba = result.toByteArray();
1364 QImage *QgsRenderer::createImage(
const QSize &size )
const
1366 std::unique_ptr<QImage> image;
1374 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1379 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1384 if ( image->isNull() )
1386 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1389 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1390 image->setDotsPerMeterX( dpm );
1391 image->setDotsPerMeterY( dpm );
1393 return image.release();
1396 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1400 throw QgsException( u
"configureMapSettings: no paint device"_s );
1403 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1406 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1409 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1410 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1415 QString crs = mWmsParameters.crs();
1416 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1418 crs = QString(
"EPSG:4326" );
1421 else if ( crs.isEmpty() && !mandatoryCrsParam )
1423 crs = QString(
"EPSG:4326" );
1426 QgsCoordinateReferenceSystem outputCRS;
1433 QgsWmsParameter parameter;
1435 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1446 throw QgsBadRequestException( code, parameter );
1455 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1463 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1469 bool transparent = mWmsParameters.transparentAsBool();
1470 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1477 else if ( backgroundColor.isValid() )
1483 QgsExpressionContext context = mProject->createExpressionContext();
1500 if ( mContext.settings().logProfile() )
1510 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1511 if ( !timeString.isEmpty() )
1513 bool isValidTemporalRange {
true };
1516 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1527 catch (
const QgsServerApiBadRequestException &ex )
1529 isValidTemporalRange =
false;
1534 if ( isValidTemporalRange )
1543 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1549 QgsDistanceArea distanceArea = QgsDistanceArea();
1550 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1556 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1558 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1560 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1562 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1564 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1566 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1568 int featureCount = mWmsParameters.featureCountAsInt();
1569 if ( featureCount < 1 )
1574 int i = mWmsParameters.iAsInt();
1575 int j = mWmsParameters.jAsInt();
1576 if ( xyDefined && !ijDefined )
1578 i = mWmsParameters.xAsInt();
1579 j = mWmsParameters.yAsInt();
1581 int width = mWmsParameters.widthAsInt();
1582 int height = mWmsParameters.heightAsInt();
1583 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1585 i *= ( outputImage->width() /
static_cast<double>( width ) );
1586 j *= ( outputImage->height() /
static_cast<double>( height ) );
1590 std::unique_ptr<QgsRectangle> featuresRect;
1591 std::unique_ptr<QgsGeometry> filterGeom;
1592 std::unique_ptr<QgsPointXY> infoPoint;
1594 if ( i != -1 && j != -1 )
1596 infoPoint = std::make_unique<QgsPointXY>();
1597 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1599 else if ( filtersDefined )
1601 featuresRect = std::make_unique<QgsRectangle>();
1604 if ( filterGeomDefined )
1606 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1609 QDomDocument result;
1610 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1611 result.appendChild( header );
1613 QDomElement getFeatureInfoElement;
1617 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1618 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1619 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1620 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1621 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1622 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1623 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1624 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1625 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 );
1630 if ( featureInfoElemName.isEmpty() )
1632 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1635 if ( featureInfoElemNs.isEmpty() )
1637 getFeatureInfoElement = result.createElement( featureInfoElemName );
1641 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1645 if ( !featureInfoSchema.isEmpty() )
1647 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1648 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1651 result.appendChild( getFeatureInfoElement );
1661 for (
const QString &queryLayer : queryLayers )
1663 bool validLayer =
false;
1664 bool queryableLayer =
true;
1665 for ( QgsMapLayer *layer : std::as_const( layers ) )
1667 if ( queryLayer == mContext.layerNickname( *layer ) )
1671 if ( !queryableLayer )
1676 QDomElement layerElement;
1679 layerElement = getFeatureInfoElement;
1683 layerElement = result.createElement( u
"Layer"_s );
1684 QString layerName = queryLayer;
1687 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1688 if ( layerAliasIt != layerAliasMap.constEnd() )
1690 layerName = layerAliasIt.value();
1693 layerElement.setAttribute( u
"name"_s, layerName );
1694 const QString layerTitle = layer->serverProperties()->title();
1695 if ( !layerTitle.isEmpty() )
1697 layerElement.setAttribute( u
"title"_s, layerTitle );
1701 layerElement.setAttribute( u
"title"_s, layerName );
1703 getFeatureInfoElement.appendChild( layerElement );
1706 layerElement.setAttribute( u
"id"_s, layer->id() );
1712 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1715 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1721 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1737 layerElement = result.createElement( u
"gml:featureMember"_s );
1738 getFeatureInfoElement.appendChild( layerElement );
1740 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1744 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1752 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1756 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1759 param.mValue = queryLayer;
1762 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1765 param.mValue = queryLayer;
1767 bool hasGroupAndQueryable {
false };
1768 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1771 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1772 for (
const QString &ql : constNicks )
1774 if ( mContext.layerGroups().contains( ql ) )
1776 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1777 for (
const QgsMapLayer *ml : constLayers )
1779 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1785 hasGroupAndQueryable =
true;
1794 if ( !hasGroupAndQueryable )
1801 if ( featuresRect && !featuresRect->isNull() )
1805 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1806 QDomElement boxElem;
1807 int gmlVersion = mWmsParameters.infoFormatVersion();
1808 if ( gmlVersion < 3 )
1820 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1822 bBoxElem.appendChild( boxElem );
1823 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1827 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1829 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1830 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1831 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1832 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1833 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1839 convertFeatureInfoToSia2045( result );
1845 bool QgsRenderer::featureInfoFromVectorLayer( QgsVectorLayer *layer,
const QgsPointXY *infoPoint,
int nFeatures, QDomDocument &infoDocument, QDomElement &layerElement,
const QgsMapSettings &mapSettings, QgsRenderContext &renderContext,
const QString &version, QgsRectangle *featureBBox, QgsGeometry *filterGeom )
const
1852 QgsFeatureRequest fReq;
1855 std::unique_ptr<QgsGeometry> layerFilterGeom;
1858 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1863 QgsRectangle mapRect = mapSettings.
extent();
1867 QgsRectangle searchRect;
1872 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1874 else if ( layerFilterGeom )
1876 searchRect = layerFilterGeom->boundingBox();
1878 else if ( !mWmsParameters.bbox().isEmpty() )
1880 searchRect = layerRect;
1886 QgsAttributes featureAttributes;
1887 int featureCounter = 0;
1889 const QgsFields fields = layer->
fields();
1906 if ( layerFilterGeom )
1908 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1912 mFeatureFilter.filterFeatures( layer, fReq );
1915#ifdef HAVE_SERVER_PYTHON_PLUGINS
1917 mContext.accessControl()->filterFeatures( layer, fReq );
1920 QStringList attributes;
1921 for (
const QgsField &field : fields )
1923 attributes.append( field.name() );
1925 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1929 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1933 r2->startRender( renderContext, layer->
fields() );
1936 bool featureBBoxInitialized =
false;
1945 if ( featureCounter > nFeatures )
1960 bool render = r2->willRenderFeature( feature, renderContext );
1973 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1976 featureBBoxInitialized =
true;
1985 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
1994 int gmlVersion = mWmsParameters.infoFormatVersion();
1995 QString typeName = mContext.layerNickname( *layer );
1996 QDomElement elem = createFeatureGML(
1997 &feature, layer, infoDocument, outputCrs, mapSettings, typeName, withGeom, gmlVersion
1998#ifdef HAVE_SERVER_PYTHON_PLUGINS
2003 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2004 featureMemberElem.appendChild( elem );
2005 layerElement.appendChild( featureMemberElem );
2010 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2012 layerElement.appendChild( featureElement );
2018 writeAttributesTabLayout( editConfig, layer, fields, featureAttributes, infoDocument, featureElement, renderContext
2019#ifdef HAVE_SERVER_PYTHON_PLUGINS
2027 for (
int i = 0; i < featureAttributes.count(); ++i )
2029 writeVectorLayerAttribute( i, layer, fields, featureAttributes, infoDocument, featureElement, renderContext
2030#ifdef HAVE_SERVER_PYTHON_PLUGINS
2042 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2043 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2047 featureElement.appendChild( maptipElem );
2051 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2053 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2054 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2057 displayExpression.
prepare( &context );
2058 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2059 featureElement.appendChild( displayElem );
2065 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2066 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2071 featureElement.appendChild( bBoxElem );
2077 QgsGeometry geom = feature.
geometry();
2080 if ( layer->
crs() != outputCrs )
2082 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2087 if ( segmentizeWktGeometry )
2089 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2094 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2095 geom.
set( segmentizedGeom );
2099 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2100 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2101 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2102 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2103 featureElement.appendChild( geometryElement );
2110 r2->stopRender( renderContext );
2116 void QgsRenderer::writeAttributesTabGroup(
const QgsAttributeEditorElement *group, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &parentElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2118 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2121 QString groupName = container->
name();
2122 QDomElement nameElem;
2124 if ( !groupName.isEmpty() )
2126 nameElem = doc.createElement( groupName );
2127 parentElem.appendChild( nameElem );
2130 const QList<QgsAttributeEditorElement *> children = container->
children();
2131 for (
const QgsAttributeEditorElement *child : children )
2135 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2139 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2145 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2153 void QgsRenderer::writeAttributesTabLayout( QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2156 if ( !editorContainer )
2161 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2164 void QgsRenderer::writeVectorLayerAttribute(
int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2166#ifndef HAVE_SERVER_PYTHON_PLUGINS
2167 Q_UNUSED( attributes );
2180#ifdef HAVE_SERVER_PYTHON_PLUGINS
2182 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2189 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2190 attributeElement.setAttribute( u
"name"_s, attributeName );
2193 featureElem.appendChild( attributeElement );
2196 bool QgsRenderer::featureInfoFromMeshLayer( QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version )
const
2199 Q_UNUSED( mapSettings )
2208 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2210 QList<QgsMeshDatasetIndex> datasetIndexList;
2219 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2221 if ( activeScalarGroup >= 0 )
2223 QgsMeshDatasetIndex indice;
2225 datasetIndexList.append( indice );
2228 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2231 for (
int groupIndex : allGroup )
2233 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2239 if ( activeScalarGroup >= 0 )
2241 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2244 for (
int groupIndex : allGroup )
2246 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2249 datasetIndexList.append( groupIndex );
2256 double scalarDoubleValue = 0.0;
2258 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2260 if ( !index.isValid() )
2264 QMap<QString, QString> derivedAttributes;
2266 QMap<QString, QString> attribute;
2270 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2271 scalarDoubleValue = scalarValue.
scalar();
2272 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2277 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2278 const double vectorX = vectorValue.
x();
2279 const double vectorY = vectorValue.
y();
2280 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2282 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2286 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2287 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2288 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2295 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2296 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2298 const QString resultName = groupMeta.
name();
2300 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2301 attributeElement.setAttribute( u
"name"_s, resultName );
2306 value = QString::number( scalarDoubleValue );
2309 attributeElement.setAttribute( u
"value"_s, value );
2310 layerElement.appendChild( attributeElement );
2314 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2315 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2318 value = range.
begin().toString( dateFormat );
2322 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2324 attributeElementTime.setAttribute( u
"value"_s, value );
2325 layerElement.appendChild( attributeElementTime );
2331 bool QgsRenderer::featureInfoFromRasterLayer( QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version )
const
2353 QgsRasterIdentifyResult identifyResult;
2356 const QgsRectangle extent { mapSettings.
extent() };
2369 if ( !identifyResult.
isValid() )
2372 QMap<int, QVariant> attributes = identifyResult.
results();
2378 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2379 int gmlVersion = mWmsParameters.infoFormatVersion();
2380 QString typeName = mContext.layerNickname( *layer );
2386 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2388 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2389 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2392 QDomElement elem = createFeatureGML(
2393 &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr
2395 layerElement.appendChild( elem );
2399 const auto values = identifyResult.
results();
2400 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2402 QVariant value = it.value();
2403 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2409 if ( value.userType() == QMetaType::Type::QString )
2417 for (
const QgsFeatureStore &featureStore : featureStoreList )
2420 for (
const QgsFeature &feature : storeFeatures )
2422 QDomElement elem = createFeatureGML(
2423 &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr
2425 layerElement.appendChild( elem );
2435 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2437 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2438 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2443 value = QString::number( it.value().toDouble() );
2446 attributeElement.setAttribute( u
"value"_s, value );
2447 layerElement.appendChild( attributeElement );
2452 const auto values = identifyResult.
results();
2453 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2455 QVariant value = it.value();
2456 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2462 if ( value.userType() == QMetaType::Type::QString )
2469 for (
const QgsFeatureStore &featureStore : featureStoreList )
2472 for (
const QgsFeature &feature : storeFeatures )
2474 for (
const auto &fld : feature.
fields() )
2476 const auto val { feature.
attribute( fld.name() ) };
2477 if ( val.isValid() )
2479 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2480 attributeElement.setAttribute( u
"name"_s, fld.name() );
2481 attributeElement.setAttribute( u
"value"_s, val.toString() );
2482 layerElement.appendChild( attributeElement );
2493 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2494 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2497 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2500 layerElement.appendChild( maptipElem );
2506 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2509 if ( filter.contains(
";"_L1 ) )
2514 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2515 groupStringList( tokens, u
"'"_s );
2516 groupStringList( tokens, u
"\""_s );
2518 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2521 if ( tokenIt->compare(
','_L1 ) == 0
2522 || tokenIt->compare(
'('_L1 ) == 0
2523 || tokenIt->compare(
')'_L1 ) == 0
2524 || tokenIt->compare(
'='_L1 ) == 0
2525 || tokenIt->compare(
"!="_L1 ) == 0
2526 || tokenIt->compare(
'<'_L1 ) == 0
2527 || tokenIt->compare(
"<="_L1 ) == 0
2528 || tokenIt->compare(
'>'_L1 ) == 0
2529 || tokenIt->compare(
">="_L1 ) == 0
2530 || tokenIt->compare(
'%'_L1 ) == 0
2531 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2532 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2533 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2534 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2535 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2536 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2537 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2538 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2539 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2540 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2541 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2548 ( void ) tokenIt->toDouble( &isNumeric );
2557 if ( *tokenIt ==
"''"_L1 )
2563 if ( tokenIt->size() > 2
2564 && ( *tokenIt )[0] == QChar(
'\'' )
2565 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2566 && ( *tokenIt )[1] != QChar(
'\'' )
2567 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2573 if ( tokenIt->size() > 2
2574 && ( *tokenIt )[0] == QChar(
'"' )
2575 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' )
2576 && ( *tokenIt )[1] != QChar(
'"' )
2577 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2588 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2591 bool groupActive =
false;
2592 int startGroup = -1;
2593 QString concatString;
2595 for (
int i = 0; i < list.size(); ++i )
2597 QString &str = list[i];
2598 if ( str.startsWith( groupString ) )
2602 concatString.clear();
2607 if ( i != startGroup )
2609 concatString.append(
" " );
2611 concatString.append( str );
2614 if ( str.endsWith( groupString ) )
2617 groupActive =
false;
2619 if ( startGroup != -1 )
2621 list[startGroup] = concatString;
2622 for (
int j = startGroup + 1; j <= endGroup; ++j )
2624 list.removeAt( startGroup + 1 );
2629 concatString.clear();
2635 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2637 QDomDocument SIAInfoDoc;
2638 QDomElement infoDocElement = doc.documentElement();
2639 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2640 SIAInfoDoc.appendChild( SIAInfoDocElement );
2642 QString currentAttributeName;
2643 QString currentAttributeValue;
2644 QDomElement currentAttributeElem;
2645 QString currentLayerName;
2646 QDomElement currentLayerElem;
2647 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2648 for (
int i = 0; i < layerNodeList.size(); ++i )
2650 currentLayerElem = layerNodeList.at( i ).toElement();
2651 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2653 QDomElement currentFeatureElem;
2655 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2656 if ( featureList.isEmpty() )
2659 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2660 QDomElement rasterLayerElem;
2661 if ( !attributeList.isEmpty() )
2663 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2665 for (
int j = 0; j < attributeList.size(); ++j )
2667 currentAttributeElem = attributeList.at( j ).toElement();
2668 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2669 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2670 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2671 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2672 outAttributeElem.appendChild( outAttributeText );
2673 rasterLayerElem.appendChild( outAttributeElem );
2675 if ( !attributeList.isEmpty() )
2677 SIAInfoDocElement.appendChild( rasterLayerElem );
2683 QSet<QString> layerPropertyAttributes;
2684 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2685 if ( !currentLayerId.isEmpty() )
2687 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2690 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2691 if ( !WMSPropertyAttributesString.isEmpty() )
2693 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2694 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2696 layerPropertyAttributes.insert( *propertyIt );
2702 QDomElement propertyRefChild;
2703 for (
int j = 0; j < featureList.size(); ++j )
2705 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2706 currentFeatureElem = featureList.at( j ).toElement();
2707 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2709 for (
int k = 0; k < attributeList.size(); ++k )
2711 currentAttributeElem = attributeList.at( k ).toElement();
2712 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2713 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2714 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2716 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2717 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2718 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2719 identifierElem.appendChild( identifierText );
2720 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2721 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2722 valueElem.appendChild( valueText );
2723 propertyElem.appendChild( identifierElem );
2724 propertyElem.appendChild( valueElem );
2725 if ( propertyRefChild.isNull() )
2727 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2728 propertyRefChild = propertyElem;
2732 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2737 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2738 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2739 SIAAttributeElem.appendChild( SIAAttributeText );
2740 SIAFeatureElem.appendChild( SIAAttributeElem );
2743 SIAInfoDocElement.appendChild( SIAFeatureElem );
2750 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2753 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2756 featureInfoString.append( QStringLiteral( R
"HTML(
2759 <title>Information</title>
2760 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2763 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2770 border: 1px solid black;
2771 border-collapse: collapse;
2792 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2795 for (
int i = 0; i < layerList.size(); ++i )
2797 const QDomElement layerElem = layerList.at( i ).toElement();
2800 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2801 const QDomElement currentFeatureElement;
2803 if ( !featureNodeList.isEmpty() )
2807 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2808 featureInfoString.append( featureInfoLayerTitleString );
2811 for (
int j = 0; j < featureNodeList.size(); ++j )
2813 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2816 featureInfoString.append( QStringLiteral( R
"HTML(
2821 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2822 for (
int k = 0; k < attributeNodeList.size(); ++k )
2824 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2825 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2826 QString value = attributeElement.attribute( u
"value"_s );
2827 if ( name !=
"maptip"_L1 )
2829 value = value.toHtmlEscaped();
2834 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2839 .arg( name, value );
2841 featureInfoString.append( featureInfoAttributeString );
2843 else if ( name ==
"maptip"_L1 )
2845 featureInfoString.append( QStringLiteral( R
"HTML(
2853 featureInfoString.append( QStringLiteral( R
"HTML(
2860 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2863 if ( !attributeNodeList.isEmpty() )
2867 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2868 featureInfoString.append( featureInfoLayerTitleString );
2870 featureInfoString.append( QStringLiteral( R
"HTML(
2874 for (
int j = 0; j < attributeNodeList.size(); ++j )
2876 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2877 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2878 QString value = attributeElement.attribute( u
"value"_s );
2879 if ( value.isEmpty() )
2881 value = u
"no data"_s;
2883 if ( name !=
"maptip"_L1 )
2885 value = value.toHtmlEscaped();
2890 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2895 .arg( name, value );
2898 featureInfoString.append( featureInfoAttributeString );
2900 else if ( name ==
"maptip"_L1 )
2902 featureInfoString.append( QStringLiteral( R
"HTML(
2910 featureInfoString.append( QStringLiteral( R
"HTML(
2920 featureInfoString.append( QStringLiteral( R
"HTML(
2924 return featureInfoString.toUtf8();
2927 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2929 QString featureInfoString;
2932 featureInfoString.append(
"GetFeatureInfo results\n" );
2933 featureInfoString.append(
"\n" );
2935 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2938 for (
int i = 0; i < layerList.size(); ++i )
2940 QDomElement layerElem = layerList.at( i ).toElement();
2942 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2945 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2946 QDomElement currentFeatureElement;
2948 if ( !featureNodeList.isEmpty() )
2950 for (
int j = 0; j < featureNodeList.size(); ++j )
2952 QDomElement featureElement = featureNodeList.at( j ).toElement();
2953 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
2956 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2957 for (
int k = 0; k < attributeNodeList.size(); ++k )
2959 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2960 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
2966 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2967 for (
int j = 0; j < attributeNodeList.size(); ++j )
2969 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2970 QString value = attributeElement.attribute( u
"value"_s );
2971 if ( value.isEmpty() )
2973 value = u
"no data"_s;
2975 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
2979 featureInfoString.append(
"\n" );
2982 return featureInfoString.toUtf8();
2985 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
2988 {
"type",
"FeatureCollection" },
2989 {
"features", json::array() },
2992 const bool withDisplayName = mWmsParameters.withDisplayName();
2994 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2995 for (
int i = 0; i < layerList.size(); ++i )
2997 const QDomElement layerElem = layerList.at( i ).toElement();
2998 const QString layerName = layerElem.attribute( u
"name"_s );
3000 QgsMapLayer *layer =
nullptr;
3001 for ( QgsMapLayer *l : layers )
3003 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3014 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3019 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3020 if ( featuresNode.isEmpty() )
3023 QMap<QgsFeatureId, QString> fidMap;
3024 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3026 for (
int j = 0; j < featuresNode.size(); ++j )
3028 const QDomElement featureNode = featuresNode.at( j ).toElement();
3029 const QString fid = featureNode.attribute( u
"id"_s );
3032 if ( expression.isEmpty() )
3034 feature = vl->
getFeature( fid.toLongLong() );
3038 QgsFeatureRequest request { QgsExpression( expression ) };
3043 fidMap.insert( feature.
id(), fid );
3048 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3049 for (
int k = 0; k < attrs.count(); k++ )
3051 const QDomElement elm = attrs.at( k ).toElement();
3052 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3054 wkt = elm.attribute(
"value" );
3059 if ( !wkt.isEmpty() )
3067 if ( withDisplayName )
3069 QString displayName;
3070 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3071 for (
int k = 0; k < attrs.count(); k++ )
3073 const QDomElement elm = attrs.at( k ).toElement();
3074 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3076 displayName = elm.attribute(
"value" );
3080 fidDisplayNameMap.insert( feature.
id(), displayName );
3083 features << feature;
3086 if ( !attributes.isEmpty() )
3089 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3090 for (
int k = 0; k < attributesNode.size(); ++k )
3092 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3093 const QString fieldName = attributeElement.attribute( u
"name"_s );
3094 attributes << feature.fieldNameIndex( fieldName );
3099 QgsJsonExporter exporter( vl );
3100 exporter.setAttributeDisplayName(
true );
3101 exporter.setAttributes( attributes );
3102 exporter.setIncludeGeometry( withGeometry );
3103 exporter.setTransformGeometries(
false );
3107 for (
const auto &feature : std::as_const( features ) )
3109 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3110 QVariantMap extraProperties;
3111 if ( withDisplayName )
3113 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3115 json[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id ) );
3120 auto properties = json::object();
3121 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3122 for (
int j = 0; j < attributesNode.size(); ++j )
3124 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3125 const QString name = attrElmt.attribute( u
"name"_s );
3127 QString value = attrElmt.attribute( u
"value"_s );
3128 if ( value.isEmpty() )
3133 properties[name.toStdString()] = value.toStdString();
3136 json[
"features"].push_back(
3137 { {
"type",
"Feature" },
3138 {
"id", layerName.toStdString() },
3139 {
"properties", properties }
3146 return QByteArray::fromStdString( json.dump( 2 ) );
3148 return QByteArray::fromStdString( json.dump() );
3152 QDomElement QgsRenderer::createFeatureGML(
3153 const QgsFeature *feat,
3154 QgsVectorLayer *layer,
3156 QgsCoordinateReferenceSystem &crs,
3157 const QgsMapSettings &mapSettings,
3158 const QString &typeName,
3161 QStringList *attributes
3165 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3172 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3174 QgsCoordinateTransform transform;
3175 if ( layer && layer->
crs() != crs )
3180 QgsGeometry geom = feat->
geometry();
3182 QgsExpressionContext expressionContext;
3189 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3203 catch ( QgsCsException &e )
3209 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3210 QDomElement boxElem;
3222 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3224 bbElem.appendChild( boxElem );
3225 typeNameElement.appendChild( bbElem );
3229 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3230 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3231 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3234 const QList<QgsAttributeEditorElement *> children = container->
children();
3235 for (
const QgsAttributeEditorElement *child : children )
3237 switch ( child->type() )
3241 if ( findAttributeInTree( attributeName, child ) )
3249 if ( child->name() == attributeName )
3257 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3258 if ( relationEditor )
3260 const QgsRelation &relation { relationEditor->
relation() };
3264 for (
const auto &idx : std::as_const( referencedFields ) )
3266 const QgsField f { layer->
fields().
at( idx ) };
3267 if ( f.
name() == attributeName )
3276 for (
const auto &idx : std::as_const( referencingFields ) )
3278 const QgsField f { layer->
fields().
at( idx ) };
3279 if ( f.
name() == attributeName )
3296 if ( withGeom && !geom.
isNull() )
3305 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3306 QDomElement gmlElem;
3316 if ( !gmlElem.isNull() )
3320 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3322 geomElem.appendChild( gmlElem );
3323 typeNameElement.appendChild( geomElem );
3328 QgsAttributes featureAttributes = feat->
attributes();
3329 QgsFields fields = feat->
fields();
3330 for (
int i = 0; i < fields.
count(); ++i )
3332 QString attributeName = fields.
at( i ).
name();
3339 if ( attributes && !attributes->contains( attributeName ) )
3344 if ( honorFormConfig )
3347 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3353 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3354 QString fieldTextString = featureAttributes.at( i ).toString();
3359 QDomText fieldText = doc.createTextNode( fieldTextString );
3360 fieldElem.appendChild( fieldText );
3361 typeNameElement.appendChild( fieldElem );
3372 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3373 QDomText maptipText = doc.createTextNode( fieldTextString );
3374 fieldElem.appendChild( maptipText );
3375 typeNameElement.appendChild( fieldElem );
3379 return typeNameElement;
3382 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3386 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3388 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3390 value = value.mid( 1, value.size() - 2 );
3395 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3399 return QgsRectangle();
3402 double mapUnitTolerance = 0.0;
3405 if ( !mWmsParameters.polygonTolerance().isEmpty()
3406 && mWmsParameters.polygonToleranceAsInt() > 0 )
3412 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3417 if ( !mWmsParameters.lineTolerance().isEmpty()
3418 && mWmsParameters.lineToleranceAsInt() > 0 )
3424 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3429 if ( !mWmsParameters.pointTolerance().isEmpty()
3430 && mWmsParameters.pointToleranceAsInt() > 0 )
3436 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3443 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3447 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3449 QList<QgsMapLayer *> highlightLayers;
3452 QString crs = mWmsParameters.crs();
3453 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3456 QDomDocument sldDoc;
3460 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3467 std::unique_ptr<QgsFeatureRenderer> renderer;
3468 QDomElement el = sldDoc.documentElement();
3478 QString url = typeName +
"?crs=" + crs;
3479 if ( !param.mLabel.isEmpty() )
3481 url +=
"&field=label:string";
3486 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3493 QgsFeature fet( layer->
fields() );
3494 if ( !param.mLabel.isEmpty() )
3496 fet.setAttribute( 0, param.mLabel );
3499 QgsPalLayerSettings palSettings;
3504 palSettings.
dist = param.mLabelDistance;
3513 switch ( param.mGeom.type() )
3524 QgsPointXY pt = param.mGeom.asPoint();
3526 QVariant x( pt.
x() );
3529 QVariant y( pt.
y() );
3541 QgsGeometry point = param.mGeom.pointOnSurface();
3542 QgsPointXY pt = point.
asPoint();
3546 QVariant x( pt.
x() );
3550 QVariant y( pt.
y() );
3554 QVariant hali(
"Center" );
3558 QVariant vali(
"Half" );
3570 QgsTextFormat textFormat;
3571 QgsTextBufferSettings bufferSettings;
3573 if ( param.mColor.isValid() )
3575 textFormat.
setColor( param.mColor );
3578 if ( param.mSize > 0 )
3580 textFormat.
setSize( param.mSize );
3588 if ( !param.mFont.isEmpty() )
3590 textFormat.
setFont( param.mFont );
3593 if ( param.mBufferColor.isValid() )
3595 bufferSettings.
setColor( param.mBufferColor );
3598 if ( param.mBufferSize > 0 )
3601 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3607 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3611 fet.setGeometry( param.mGeom );
3620 highlightLayers.append( layer.release() );
3624 mTemporaryLayers.append( highlightLayers );
3625 return highlightLayers;
3628 void QgsRenderer::removeTemporaryLayers()
3630 qDeleteAll( mTemporaryLayers );
3631 mTemporaryLayers.clear();
3634 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3636 QPainter *painter =
nullptr;
3638 QgsFeatureFilterProviderGroup filters;
3640#ifdef HAVE_SERVER_PYTHON_PLUGINS
3641 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3644 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3646 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3647 painter = renderJob.takePainter();
3649 logRenderingErrors( renderJob.errors() );
3651 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3653 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3655 QString layerWMSName;
3656 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3659 layerWMSName = mContext.layerNickname( *errorLayer );
3662 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3663 if ( !layerWMSName.isEmpty() )
3665 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3667 throw QgsException( errorMessage );
3673 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3675 if ( opacity >= 0 && opacity <= 255 )
3677 switch ( layer->
type() )
3681 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3686 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3694 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3695 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3696 rasterRenderer->
setOpacity( opacity / 255. );
3702 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3718 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3722 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3723 QStringList expList;
3724 for (
const QgsWmsParametersFilter &filter : filters )
3729 QDomDocument filterXml;
3731#if QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 )
3733 if ( !filterXml.setContent( filter.mFilter,
true, &errorMsg ) )
3738 QXmlStreamReader xmlReader( filter.mFilter );
3739 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3740 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3741 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3743 throw QgsBadRequestException(
QgsServiceException::QGIS_InvalidParameterValue, 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 ) );
3746 QDomElement filterElem = filterXml.firstChildElement();
3751 expList << filterExp->dump();
3757 if ( !testFilterStringSafety( filter.mFilter ) )
3759 throw QgsSecurityException( QStringLiteral(
"The filter string %1"
3760 " has been rejected because of security reasons."
3761 " Note: Text strings have to be enclosed in single or double quotes."
3762 " A space between each word / special character is mandatory."
3763 " Allowed Keywords and special characters are"
3764 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3765 " Not allowed are semicolons in the filter expression." )
3767 filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' )
3771 QString newSubsetString = filter.mFilter;
3774 newSubsetString.prepend(
") AND (" );
3775 newSubsetString.append(
")" );
3776 newSubsetString.prepend( filteredLayer->
subsetString() );
3777 newSubsetString.prepend(
"(" );
3787 expList.append( dimensionFilter( filteredLayer ) );
3791 if ( expList.size() == 1 )
3795 else if ( expList.size() > 1 )
3797 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3799 if ( !exp.isEmpty() )
3801 auto expression = std::make_unique<QgsExpression>( exp );
3805 mFeatureFilter.setFilter( filteredLayer, *expression );
3812 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3814 QStringList expList;
3816 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3817 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3818 if ( wmsDims.isEmpty() )
3823 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3824 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3833 if ( fieldIndex == -1 )
3838 int endFieldIndex = -1;
3839 if ( !dim.endFieldName.isEmpty() )
3841 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3842 if ( endFieldIndex == -1 )
3848 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3852 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::AllValues )
3856 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
3858 defValue = dim.referenceValue;
3863 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3864 if ( endFieldIndex != -1 )
3866 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3869 QList<QVariant> values = qgis::setToList( uniqueValues );
3870 std::sort( values.begin(), values.end() );
3871 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
3873 defValue = values.first();
3875 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
3877 defValue = values.last();
3881 if ( endFieldIndex == -1 )
3887 QStringList expElems;
3892 expList << expElems.join(
' ' );
3898 QgsField dimField = layer->
fields().
at( fieldIndex );
3900 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3902 QStringList dimExplist;
3904 QStringList dimValues = dimParamValue.split(
',' );
3905 for (
int i = 0; i < dimValues.size(); ++i )
3907 QString dimValue = dimValues[i];
3909 if ( dimValue.size() > 1 )
3911 dimValue = dimValue.trimmed();
3914 if ( dimValue.contains(
'/' ) )
3916 QStringList rangeValues = dimValue.split(
'/' );
3918 if ( rangeValues.size() != 2 )
3923 QVariant rangeMin = QVariant( rangeValues[0] );
3924 QVariant rangeMax = QVariant( rangeValues[1] );
3935 QStringList expElems;
3936 if ( endFieldIndex == -1 )
3958 dimExplist << expElems.join(
' ' );
3962 QVariant dimVariant = QVariant( dimValue );
3968 if ( endFieldIndex == -1 )
3977 QStringList expElems;
3982 dimExplist << expElems.join(
' ' );
3987 if ( dimExplist.size() == 1 )
3989 expList << dimExplist;
3991 else if ( dimExplist.size() > 1 )
3993 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
4000 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4004 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4006 QgsFeatureRequest request;
4010 if ( selectedIds.empty() )
4021 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4023#ifdef HAVE_SERVER_PYTHON_PLUGINS
4030 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4033 QgsRectangle mapExtent = mapSettings.
extent();
4041 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4043 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4044 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4048 renderContext.
setFeedback( mContext.socketFeedback() );
4050 for ( QgsAnnotation *annotation : annotations )
4052 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4054 if ( !annotation || !annotation->isVisible() )
4060 if ( annotation->hasFixedMapPosition() )
4062 QgsPointXY mapPos = annotation->mapPosition();
4063 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4068 mapPos = coordTransform.transform( mapPos );
4070 catch (
const QgsCsException &e )
4076 offsetX = devicePos.
x();
4077 offsetY = devicePos.
y();
4081 const QPointF relativePos = annotation->relativePosition();
4082 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4083 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4087 painter->translate( offsetX, offsetY );
4088 annotation->render( renderContext );
4093 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4098 QImage *scaledImage =
nullptr;
4099 const int width = mWmsParameters.widthAsInt();
4100 const int height = mWmsParameters.heightAsInt();
4101 if ( width != image->width() || height != image->height() )
4103 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4111 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4112 for ( ; it != errors.constEnd(); ++it )
4114 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4115 if ( !it->layerID.isEmpty() )
4117 msg += QString(
" in layer %1" ).arg( it->layerID );
4123 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4130 QList<QgsLayoutItemMap *> mapList;
4134 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4135 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4137 logRenderingErrors( ( *mapIt )->renderingErrors() );
4140 if ( mContext.settings().ignoreRenderingErrors() )
4145 mapIt = mapList.constBegin();
4146 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4148 if ( !( *mapIt )->renderingErrors().isEmpty() )
4150 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4151 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4158 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4160 for (
auto layer : layers )
4162 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4164 if ( !mContext.layersToRender().contains( layer ) )
4169 if ( mContext.isExternalLayer( param.mNickname ) )
4173 setLayerOpacity( layer, param.mOpacity );
4180 setLayerSld( layer, mContext.sld( *layer ) );
4184 setLayerStyle( layer, mContext.style( *layer ) );
4189 setLayerOpacity( layer, param.mOpacity );
4194 setLayerFilter( layer, param.mFilter );
4199 setLayerAccessControlFilter( layer );
4204 setLayerSelection( layer, param.mSelection );
4207 if ( settings && mContext.updateExtent() )
4209 updateExtent( layer, *settings );
4215 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4219 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4221 if ( style.isEmpty() )
4233 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4238 QString sldStyleName =
"__sld_style";
4239 while ( styles.contains( sldStyleName ) )
4241 sldStyleName.append(
'@' );
4249 QgsLegendSettings QgsRenderer::legendSettings()
4252 QgsLegendSettings settings = mWmsParameters.legendSettings();
4254 if ( !mWmsParameters.bbox().isEmpty() )
4256 QgsMapSettings mapSettings;
4258 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4259 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
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
@ 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 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)
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 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
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...
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())
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.
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.
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 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.
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)
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
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.
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
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