23#include <nlohmann/json.hpp>
83#include <QTemporaryFile>
85#include <QXmlStreamReader>
109 : mContext( context )
111 mProject = mContext.project();
113 mWmsParameters = mContext.parameters();
114 mWmsParameters.dump();
119 removeTemporaryLayers();
125 std::unique_ptr<QgsWmsRestorer> restorer;
126 restorer = std::make_unique<QgsWmsRestorer>( mContext );
129 QList<QgsMapLayer *> layers = mContext.layersToRender();
132 const qreal dpmm = mContext.dotsPerMm();
137 const auto layersToRender = mContext.layersToRender();
138 for (
const auto &layer : std::as_const( layersToRender ) )
141 if ( layer->dataProvider()->name() == QLatin1String(
"wms" ) )
145 const auto image { layerNode->getLegendGraphicBlocking() };
146 if ( !image.isNull() )
149 if ( mContext.isValidWidthHeight( image.width(), image.height() ) )
151 const double w = image.width() / dpmm;
152 const double h = image.height() / dpmm;
153 const QSizeF newWmsSize { w, h };
166 if ( !mWmsParameters.bbox().isEmpty() )
170 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
171 configureMapSettings( tmp.get(), mapSettings );
177 context = configureDefaultRenderContext();
181 std::unique_ptr<QImage> image;
182 const QSizeF minSize = renderer.
minimumSize( &context );
183 const QSize size(
static_cast<int>( minSize.width() * dpmm ),
static_cast<int>( minSize.height() * dpmm ) );
184 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
188 image.reset( createImage( size ) );
191 QPainter painter( image.get() );
194 if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
196 if ( painter.renderHints() & QPainter::LosslessImageRendering )
206 return image.release();
212 std::unique_ptr<QgsWmsRestorer> restorer;
213 restorer = std::make_unique<QgsWmsRestorer>( mContext );
216 QList<QgsMapLayer *> layers = mContext.layersToRender();
220 const QSize size( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() );
222 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
226 std::unique_ptr<QImage> image( createImage( size ) );
229 const qreal dpmm = mContext.dotsPerMm();
230 std::unique_ptr<QPainter> painter;
231 painter = std::make_unique<QPainter>( image.get() );
232 painter->setRenderHint( QPainter::Antialiasing,
true );
233 painter->scale( dpmm, dpmm );
244 nodeModel.
drawSymbol( settings, &ctx, size.height() / dpmm );
247 return image.release();
253 std::unique_ptr<QgsWmsRestorer> restorer;
254 restorer = std::make_unique<QgsWmsRestorer>( mContext );
257 QList<QgsMapLayer *> layers = mContext.layersToRender();
273 std::unique_ptr<QgsWmsRestorer> restorer;
274 restorer = std::make_unique<QgsWmsRestorer>( mContext );
277 QList<QgsMapLayer *> layers = mContext.layersToRender();
286 QJsonObject jsonSymbol {
legendNode.exportSymbolToJson( settings, renderContext ) };
293 if ( vLayer->renderer() )
297 const QString ruleExp { vLayer->renderer()->legendKeyToExpression( ruleKey, vLayer, ok ) };
300 jsonSymbol[QStringLiteral(
"rule" )] = ruleExp;
309 void QgsRenderer::runHitTest(
const QgsMapSettings &mapSettings, HitTest &hitTest )
const
313 for (
const QString &
id : mapSettings.
layerIds() )
330 runHitTestLayer( vl, usedSymbols, context );
334 void QgsRenderer::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context )
const
336 std::unique_ptr<QgsFeatureRenderer> r( vl->
renderer()->
clone() );
338 r->startRender( context, vl->
fields() );
340 QgsFeatureRequest request( context.
extent() );
342 QgsFeatureIterator fi = vl->
getFeatures( request );
346 if ( moreSymbolsPerFeature )
348 for ( QgsSymbol *s : r->originalSymbolsForFeature( f, context ) )
354 r->stopRender( context );
360 if ( !mContext.isValidWidthHeight() )
366 std::unique_ptr<QgsWmsRestorer> restorer;
367 restorer = std::make_unique<QgsWmsRestorer>( mContext );
372 QList<QgsMapLayer *> layers = mContext.layersToRender();
376 std::unique_ptr<QPainter> painter;
377 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
380 configureMapSettings( image.get(), mapSettings );
387 runHitTest( mapSettings,
symbols );
395 std::unique_ptr<QgsWmsRestorer> restorer;
396 restorer = std::make_unique<QgsWmsRestorer>( mContext );
399 const QString templateName = mWmsParameters.composerTemplate();
400 if ( templateName.isEmpty() )
423 std::unique_ptr<QgsPrintLayout> layout( sourceLayout->
clone() );
427 QStringList atlasPk = mWmsParameters.atlasPk();
428 if ( !atlasPk.isEmpty() )
430 atlas = layout->atlas();
431 if ( !atlas || !atlas->
enabled() )
444 if ( atlasPk.size() == 1 && atlasPk.at( 0 ) == QLatin1String(
"*" ) )
448 if ( atlas->
count() > maxAtlasFeatures )
456 if ( pkIndexes.size() == 0 )
458 QgsDebugMsgLevel( QStringLiteral(
"Atlas print: layer %1 has no primary key attributes" ).arg( cLayer->
name() ), 2 );
462 const int pkIndexesSize { std::max<int>( pkIndexes.size(), 1 ) };
464 QStringList pkAttributeNames;
465 for (
int pkIndex : std::as_const( pkIndexes ) )
467 pkAttributeNames.append( cLayer->
fields().
at( pkIndex ).
name() );
470 const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
471 if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() )
477 if ( nAtlasFeatures > maxAtlasFeatures )
482 QString filterString;
483 int currentAtlasPk = 0;
485 for (
int i = 0; i < nAtlasFeatures; ++i )
489 filterString.append(
" OR " );
492 filterString.append(
"( " );
495 if ( pkAttributeNames.isEmpty() )
497 filterString.append( QStringLiteral(
"$id = %1" ).arg( atlasPk.at( currentAtlasPk ) ) );
502 for (
int j = 0; j < pkIndexes.size(); ++j )
506 filterString.append(
" AND " );
513 filterString.append(
" )" );
521 if ( !errorString.isEmpty() )
523 throw QgsException( QStringLiteral(
"An error occurred during the Atlas print: %1" ).arg( errorString ) );
531 QList<QgsMapLayer *> layers = mContext.layersToRender();
535 auto image = std::make_unique<QImage>();
536 configureMapSettings( image.get(), mapSettings );
542 configurePrintLayout( layout.get(), mapSettings, atlas );
546 const QList<QgsMapLayer *> lyrs = mapSettings.
layers();
548#ifdef HAVE_SERVER_PYTHON_PLUGINS
549 mContext.accessControl()->resolveFilterFeatures( lyrs );
553 QHash<const QgsVectorLayer *, QStringList> fltrs;
558 fltrs.insert( vl, dimensionFilter( vl ) );
570 QTemporaryFile tempOutputFile( QDir::tempPath() +
'/' + QStringLiteral(
"XXXXXX.%1" ).arg( extension ) );
571 if ( !tempOutputFile.open() )
573 throw QgsException( QStringLiteral(
"Could not open temporary file for the GetPrint request." ) );
581 if ( !mWmsParameters.dpi().isEmpty() )
584 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
586 exportSettings.
dpi = dpi;
599 atlasSvgExport.
exportToSvg( tempOutputFile.fileName(), exportSettings );
605 exporter.
exportToSvg( tempOutputFile.fileName(), exportSettings );
614 double dpi( layout->renderContext().dpi() );
615 if ( !mWmsParameters.dpi().isEmpty() )
618 double _dpi = mWmsParameters.dpi().toDouble( &ok );
622 exportSettings.
dpi = dpi;
628 QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );
633 const QSize imageSize = QSize(
static_cast<int>( width.
length() * dpi / 25.4 ),
static_cast<int>( height.
length() * dpi / 25.4 ) );
635 const QString paramWidth = mWmsParameters.width();
636 const QString paramHeight = mWmsParameters.height();
641 if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
643 exportSettings.
imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
645 else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
647 exportSettings.
imageSize = QSize( paramWidth.toInt(),
static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
649 else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
651 exportSettings.
imageSize = QSize(
static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
659 exportSettings.
pages.append( 0 );
667 atlasPngExport.
exportToImage( tempOutputFile.fileName(), exportSettings );
671 throw QgsServiceException( QStringLiteral(
"Bad request" ), QStringLiteral(
"Atlas error: empty atlas." ), QString(), 400 );
677 exporter.
exportToImage( tempOutputFile.fileName(), exportSettings );
685 if ( !mWmsParameters.dpi().isEmpty() )
688 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
690 exportSettings.
dpi = dpi;
695 exportSettings.
rasterizeWholeImage = layout->customProperty( QStringLiteral(
"rasterize" ),
false ).toBool();
697 QVector<qreal> requestMapScales = mWmsParameters.pdfPredefinedMapScales();
698 if ( requestMapScales.size() > 0 )
707 QStringList exportThemes = mWmsParameters.pdfExportMapThemes();
708 if ( exportThemes.size() > 0 )
712 exportSettings.
writeGeoPdf = mWmsParameters.writeGeospatialPdf();
718 if ( mWmsParameters.pdfLosslessImageCompression() )
722 if ( mWmsParameters.pdfDisableTiledRasterRendering() )
735 exporter.
exportToPdf( tempOutputFile.fileName(), exportSettings );
745 handlePrintErrors( atlas->
layout() );
749 handlePrintErrors( layout.get() );
752 return tempOutputFile.readAll();
759 QList<QgsLayoutItemMap *> maps;
765 for (
const auto &map : std::as_const( maps ) )
771 if ( cMapParams.
mLayers.isEmpty() )
776 if ( !atlas || !map->atlasDriven() )
782 c->removeLayoutItem( map );
791 QgsRectangle r( cMapParams.
mExtent );
799 if ( cMapParams.
mScale > 0 )
801 map->setScale(
static_cast<double>( cMapParams.
mScale ) );
807 map->setMapRotation( cMapParams.
mRotation );
811 if ( !map->keepLayerSet() )
813 QList<QgsMapLayer *> layerSet;
815 for (
const auto &layer : std::as_const( cMapParams.
mLayers ) )
817 if ( mContext.isValidGroup( layer.mNickname ) )
819 QList<QgsMapLayer *> layersFromGroup;
821 const QList<QgsMapLayer *> cLayersFromGroup = mContext.layersFromGroup( layer.mNickname );
822 for ( QgsMapLayer *layerFromGroup : cLayersFromGroup )
824 if ( !layerFromGroup )
829 layersFromGroup.push_front( layerFromGroup );
832 if ( !layersFromGroup.isEmpty() )
834 layerSet.append( layersFromGroup );
839 QgsMapLayer *mlayer = mContext.layer( layer.mNickname );
846 setLayerStyle( mlayer, layer.mStyle );
851 std::reverse( layerSet.begin(), layerSet.end() );
856 QMap<QString, QString> layersStyle;
857 if ( map->followVisibilityPreset() )
867 const QString presetName = map->followVisibilityPresetName();
868 if ( layerSet.isEmpty() )
871 const QgsExpressionContext ex { map->createExpressionContext() };
872 layerSet = map->layersToRender( &ex );
875 map->setFollowVisibilityPreset(
false );
879 for (
const auto &layerMapThemeRecord : std::as_const( mapThemeRecords ) )
881 if ( layerSet.contains( layerMapThemeRecord.layer() ) )
883 layersStyle.insert( layerMapThemeRecord.layer()->id(), layerMapThemeRecord.layer()->styleManager()->style( layerMapThemeRecord.currentStyle ).xmlData() );
889 const QList<QgsMapLayer *> highlights = highlightLayers( cMapParams.
mHighlightLayers );
890 for (
const auto &hl : std::as_const( highlights ) )
892 layerSet.prepend( hl );
895 map->setLayers( layerSet );
896 map->setKeepLayerSet(
true );
900 if ( !layersStyle.isEmpty() )
902 map->setLayerStyleOverrides( layersStyle );
903 map->setKeepLayerStyles(
true );
910 map->grid()->setIntervalX(
static_cast<double>( cMapParams.
mGridX ) );
911 map->grid()->setIntervalY(
static_cast<double>( cMapParams.
mGridY ) );
916 QList<QgsLayoutItemLabel *> labels;
917 c->layoutItems<QgsLayoutItemLabel>( labels );
918 for (
const auto &label : std::as_const( labels ) )
921 const QString labelId = label->id();
922 const QString labelParam = mWmsParameters.layoutParameter( labelId, ok );
927 if ( labelParam.isEmpty() )
931 c->removeItem( label );
936 label->setText( labelParam );
940 QList<QgsLayoutItemHtml *> htmls;
941 c->layoutObjects<QgsLayoutItemHtml>( htmls );
942 for (
const auto &html : std::as_const( htmls ) )
944 if ( html->frameCount() == 0 )
947 QgsLayoutFrame *htmlFrame = html->frame( 0 );
949 const QString htmlId = htmlFrame->
id();
950 const QString htmlValue = mWmsParameters.layoutParameter( htmlId, ok );
960 if ( htmlValue.isEmpty() )
962 c->removeMultiFrame( html );
969 QUrl newUrl( htmlValue );
970 html->setUrl( newUrl );
974 html->setHtml( htmlValue );
981 QList<QgsLayoutItemLegend *> legends;
982 c->layoutItems<QgsLayoutItemLegend>( legends );
983 for (
const auto &legend : std::as_const( legends ) )
985 if ( legend->autoUpdateModel() )
989 const QgsLayoutItemMap *map = legend->linkedMap();
995 legend->setAutoUpdateModel(
false );
998 QgsLegendModel *model = legend->model();
999 QStringList layerSet;
1000 QList<QgsMapLayer *> mapLayers;
1001 if ( map->
layers().isEmpty() )
1005 mapLayers = mProject->mapLayers(
true ).values();
1009 mapLayers = map->
layers();
1011 const QList<QgsMapLayer *> layerList = mapLayers;
1012 for (
const auto &layer : layerList )
1013 layerSet << layer->id();
1018 QgsLayerTree *root = model->
rootGroup();
1025 for (
const auto &layerId : layerIds )
1027 QgsLayerTreeLayer *nodeLayer = root->
findLayer( layerId );
1032 if ( !layerSet.contains( layerId ) )
1034 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1038 QgsMapLayer *layer = nodeLayer->
layer();
1041 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1054 if ( !mContext.isValidWidthHeight() )
1059 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1065 std::unique_ptr<QgsWmsRestorer> restorer;
1066 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1069 QList<QgsMapLayer *> layers = mContext.layersToRender();
1076 std::unique_ptr<QPainter> painter;
1077 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
1080 configureMapSettings( image.get(), mapSettings );
1086 QPainter *renderedPainter = layersRendering( mapSettings, image.get() );
1087 if ( !renderedPainter )
1092 painter.reset( renderedPainter );
1095 annotationsRendering( painter.get(), mapSettings );
1101 QImage *scaledImage = scaleImage( image.get() );
1103 image.reset( scaledImage );
1106 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1116 QList<QgsMapLayer *> layers = mContext.layersToRender();
1120 const QStringList attributes = mWmsParameters.dxfLayerAttributes();
1121 QList<QgsDxfExport::DxfLayer> dxfLayers;
1133 int layerAttribute = -1;
1134 if ( attributes.size() > layerIdx )
1143 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1145 QString crs = mWmsParameters.crs();
1146 if ( crs.compare( QStringLiteral(
"CRS:84" ), Qt::CaseInsensitive ) == 0 )
1148 crs = QStringLiteral(
"EPSG:4326" );
1151 else if ( crs.isEmpty() )
1153 crs = QStringLiteral(
"EPSG:4326" );
1187 auto dxf = std::make_unique<QgsDxfExport>();
1188 dxf->setExtent( mapExtent );
1189 dxf->setDestinationCrs( outputCRS );
1190 dxf->addLayers( dxfLayers );
1191 dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
1192 dxf->setSymbologyExport( mWmsParameters.dxfMode() );
1195 dxf->setSymbologyScale( mWmsParameters.dxfScale() );
1198 dxf->setForce2d( mWmsParameters.isForce2D() );
1200 if ( mWmsParameters.noMText() )
1203 if ( mWmsParameters.exportLinesWithZeroWidth() )
1208 dxf->setFlags( flags );
1216 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1217 ms.
setLayers( mContext.layersToRender() );
1219 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1223 if ( mWmsParameters.pdfExportMetadata() )
1234 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1235 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, QStringLiteral(
"PDF" ),
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1236 if ( mWmsParameters.pdfAppendGeoreference() )
1238 pdf->setSaveWorldFile(
true );
1246 if ( i < 0 || i > mapSettings.
outputSize().width() )
1253 if ( j < 0 || j > mapSettings.
outputSize().height() )
1270 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1276 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1277 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1278 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1279 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1281 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1285 if ( mWmsParameters.j().isEmpty() )
1298 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1301 std::unique_ptr<QgsWmsRestorer> restorer;
1302 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1306 bool mandatoryCrsParam =
true;
1307 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1309 mandatoryCrsParam =
false;
1315 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1319 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1331#ifdef HAVE_SERVER_PYTHON_PLUGINS
1332 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1335 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1340 ba = convertFeatureInfoToText( result );
1342 ba = convertFeatureInfoToHtml( result );
1344 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1346 ba = result.toByteArray();
1351 QImage *QgsRenderer::createImage(
const QSize &size )
const
1353 std::unique_ptr<QImage> image;
1361 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1366 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1371 if ( image->isNull() )
1373 throw QgsException( QStringLiteral(
"createImage: image could not be created, check for out of memory conditions" ) );
1376 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1377 image->setDotsPerMeterX( dpm );
1378 image->setDotsPerMeterY( dpm );
1380 return image.release();
1383 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1387 throw QgsException( QStringLiteral(
"configureMapSettings: no paint device" ) );
1390 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1393 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1396 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1397 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1402 QString crs = mWmsParameters.crs();
1403 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1405 crs = QString(
"EPSG:4326" );
1408 else if ( crs.isEmpty() && !mandatoryCrsParam )
1410 crs = QString(
"EPSG:4326" );
1413 QgsCoordinateReferenceSystem outputCRS;
1420 QgsWmsParameter parameter;
1422 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1433 throw QgsBadRequestException( code, parameter );
1442 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1450 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1456 bool transparent = mWmsParameters.transparentAsBool();
1457 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1464 else if ( backgroundColor.isValid() )
1470 QgsExpressionContext context = mProject->createExpressionContext();
1485 if ( mContext.settings().logProfile() )
1495 const QString timeString { mWmsParameters.dimensionValues().value( QStringLiteral(
"TIME" ), QString() ) };
1496 if ( !timeString.isEmpty() )
1498 bool isValidTemporalRange {
true };
1501 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1512 catch (
const QgsServerApiBadRequestException &ex )
1514 isValidTemporalRange =
false;
1519 if ( isValidTemporalRange )
1528 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1534 QgsDistanceArea distanceArea = QgsDistanceArea();
1535 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1541 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1543 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1545 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1547 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1549 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1551 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1553 int featureCount = mWmsParameters.featureCountAsInt();
1554 if ( featureCount < 1 )
1559 int i = mWmsParameters.iAsInt();
1560 int j = mWmsParameters.jAsInt();
1561 if ( xyDefined && !ijDefined )
1563 i = mWmsParameters.xAsInt();
1564 j = mWmsParameters.yAsInt();
1566 int width = mWmsParameters.widthAsInt();
1567 int height = mWmsParameters.heightAsInt();
1568 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1570 i *= ( outputImage->width() /
static_cast<double>( width ) );
1571 j *= ( outputImage->height() /
static_cast<double>( height ) );
1575 std::unique_ptr<QgsRectangle> featuresRect;
1576 std::unique_ptr<QgsGeometry> filterGeom;
1577 std::unique_ptr<QgsPointXY> infoPoint;
1579 if ( i != -1 && j != -1 )
1581 infoPoint = std::make_unique<QgsPointXY>();
1582 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1584 else if ( filtersDefined )
1586 featuresRect = std::make_unique<QgsRectangle>();
1589 if ( filterGeomDefined )
1591 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1594 QDomDocument result;
1595 const QDomNode header = result.createProcessingInstruction( QStringLiteral(
"xml" ), QStringLiteral(
"version=\"1.0\" encoding=\"UTF-8\"" ) );
1596 result.appendChild( header );
1598 QDomElement getFeatureInfoElement;
1602 getFeatureInfoElement = result.createElement( QStringLiteral(
"wfs:FeatureCollection" ) );
1603 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:wfs" ), QStringLiteral(
"http://www.opengis.net/wfs" ) );
1604 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:ogc" ), QStringLiteral(
"http://www.opengis.net/ogc" ) );
1605 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:gml" ), QStringLiteral(
"http://www.opengis.net/gml" ) );
1606 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:ows" ), QStringLiteral(
"http://www.opengis.net/ows" ) );
1607 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:xlink" ), QStringLiteral(
"http://www.w3.org/1999/xlink" ) );
1608 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:qgs" ), QStringLiteral(
"http://qgis.org/gml" ) );
1609 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
1610 getFeatureInfoElement.setAttribute( QStringLiteral(
"xsi:schemaLocation" ), QStringLiteral(
"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://qgis.org/gml" ) );
1615 if ( featureInfoElemName.isEmpty() )
1617 featureInfoElemName = QStringLiteral(
"GetFeatureInfoResponse" );
1620 if ( featureInfoElemNs.isEmpty() )
1622 getFeatureInfoElement = result.createElement( featureInfoElemName );
1626 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1630 if ( !featureInfoSchema.isEmpty() )
1632 getFeatureInfoElement.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
1633 getFeatureInfoElement.setAttribute( QStringLiteral(
"xsi:schemaLocation" ), featureInfoSchema );
1636 result.appendChild( getFeatureInfoElement );
1646 for (
const QString &queryLayer : queryLayers )
1648 bool validLayer =
false;
1649 bool queryableLayer =
true;
1650 for ( QgsMapLayer *layer : std::as_const( layers ) )
1652 if ( queryLayer == mContext.layerNickname( *layer ) )
1656 if ( !queryableLayer )
1661 QDomElement layerElement;
1664 layerElement = getFeatureInfoElement;
1668 layerElement = result.createElement( QStringLiteral(
"Layer" ) );
1669 QString layerName = queryLayer;
1672 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1673 if ( layerAliasIt != layerAliasMap.constEnd() )
1675 layerName = layerAliasIt.value();
1678 layerElement.setAttribute( QStringLiteral(
"name" ), layerName );
1679 const QString layerTitle = layer->serverProperties()->title();
1680 if ( !layerTitle.isEmpty() )
1682 layerElement.setAttribute( QStringLiteral(
"title" ), layerTitle );
1686 layerElement.setAttribute( QStringLiteral(
"title" ), layerName );
1688 getFeatureInfoElement.appendChild( layerElement );
1691 layerElement.setAttribute( QStringLiteral(
"id" ), layer->id() );
1697 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1700 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1706 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1722 layerElement = result.createElement( QStringLiteral(
"gml:featureMember" ) );
1723 getFeatureInfoElement.appendChild( layerElement );
1726 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1731 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1734 param.mValue = queryLayer;
1737 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1740 param.mValue = queryLayer;
1742 bool hasGroupAndQueryable {
false };
1743 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1746 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1747 for (
const QString &ql : constNicks )
1749 if ( mContext.layerGroups().contains( ql ) )
1751 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1752 for (
const QgsMapLayer *ml : constLayers )
1754 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1760 hasGroupAndQueryable =
true;
1769 if ( !hasGroupAndQueryable )
1776 if ( featuresRect && !featuresRect->isNull() )
1780 QDomElement bBoxElem = result.createElement( QStringLiteral(
"gml:boundedBy" ) );
1781 QDomElement boxElem;
1782 int gmlVersion = mWmsParameters.infoFormatVersion();
1783 if ( gmlVersion < 3 )
1795 boxElem.setAttribute( QStringLiteral(
"srsName" ), crs.
authid() );
1797 bBoxElem.appendChild( boxElem );
1798 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1802 QDomElement bBoxElem = result.createElement( QStringLiteral(
"BoundingBox" ) );
1804 bBoxElem.setAttribute( QStringLiteral(
"minx" ),
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1805 bBoxElem.setAttribute( QStringLiteral(
"maxx" ),
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1806 bBoxElem.setAttribute( QStringLiteral(
"miny" ),
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1807 bBoxElem.setAttribute( QStringLiteral(
"maxy" ),
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1808 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1814 convertFeatureInfoToSia2045( result );
1820 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
1827 QgsFeatureRequest fReq;
1830 std::unique_ptr<QgsGeometry> layerFilterGeom;
1833 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1838 QgsRectangle mapRect = mapSettings.
extent();
1842 QgsRectangle searchRect;
1847 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1849 else if ( layerFilterGeom )
1851 searchRect = layerFilterGeom->boundingBox();
1853 else if ( !mWmsParameters.bbox().isEmpty() )
1855 searchRect = layerRect;
1861 QgsAttributes featureAttributes;
1862 int featureCounter = 0;
1864 const QgsFields fields = layer->
fields();
1881 if ( layerFilterGeom )
1883 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1887 mFeatureFilter.filterFeatures( layer, fReq );
1890#ifdef HAVE_SERVER_PYTHON_PLUGINS
1892 mContext.accessControl()->filterFeatures( layer, fReq );
1895 QStringList attributes;
1896 for (
const QgsField &field : fields )
1898 attributes.append( field.name() );
1900 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1904 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1908 r2->startRender( renderContext, layer->
fields() );
1911 bool featureBBoxInitialized =
false;
1920 if ( featureCounter > nFeatures )
1935 bool render = r2->willRenderFeature( feature, renderContext );
1948 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1951 featureBBoxInitialized =
true;
1960 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
1969 int gmlVersion = mWmsParameters.infoFormatVersion();
1970 QString typeName = mContext.layerNickname( *layer );
1971 QDomElement elem = createFeatureGML(
1972 &feature, layer, infoDocument, outputCrs, mapSettings, typeName, withGeom, gmlVersion
1973#ifdef HAVE_SERVER_PYTHON_PLUGINS
1978 QDomElement featureMemberElem = infoDocument.createElement( QStringLiteral(
"gml:featureMember" ) );
1979 featureMemberElem.appendChild( elem );
1980 layerElement.appendChild( featureMemberElem );
1985 QDomElement featureElement = infoDocument.createElement( QStringLiteral(
"Feature" ) );
1987 layerElement.appendChild( featureElement );
1993 writeAttributesTabLayout( editConfig, layer, fields, featureAttributes, infoDocument, featureElement, renderContext
1994#ifdef HAVE_SERVER_PYTHON_PLUGINS
2002 for (
int i = 0; i < featureAttributes.count(); ++i )
2004 writeVectorLayerAttribute( i, layer, fields, featureAttributes, infoDocument, featureElement, renderContext
2005#ifdef HAVE_SERVER_PYTHON_PLUGINS
2017 QDomElement maptipElem = infoDocument.createElement( QStringLiteral(
"Attribute" ) );
2018 maptipElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"maptip" ) );
2022 featureElement.appendChild( maptipElem );
2026 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2028 QDomElement displayElem = infoDocument.createElement( QStringLiteral(
"Attribute" ) );
2029 displayElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"displayName" ) );
2032 displayExpression.
prepare( &context );
2033 displayElem.setAttribute( QStringLiteral(
"value" ), displayExpression.
evaluate( &context ).toString() );
2034 featureElement.appendChild( displayElem );
2040 QDomElement bBoxElem = infoDocument.createElement( QStringLiteral(
"BoundingBox" ) );
2041 bBoxElem.setAttribute( version == QLatin1String(
"1.1.1" ) ?
"SRS" :
"CRS", outputCrs.
authid() );
2046 featureElement.appendChild( bBoxElem );
2052 QgsGeometry geom = feature.
geometry();
2055 if ( layer->
crs() != outputCrs )
2057 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2062 if ( segmentizeWktGeometry )
2064 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2069 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2070 geom.
set( segmentizedGeom );
2074 QDomElement geometryElement = infoDocument.createElement( QStringLiteral(
"Attribute" ) );
2075 geometryElement.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"geometry" ) );
2076 geometryElement.setAttribute( QStringLiteral(
"value" ), geom.
asWkt( mContext.precision() ) );
2077 geometryElement.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"derived" ) );
2078 featureElement.appendChild( geometryElement );
2085 r2->stopRender( renderContext );
2091 void QgsRenderer::writeAttributesTabGroup(
const QgsAttributeEditorElement *group, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &parentElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2093 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2096 QString groupName = container->
name();
2097 QDomElement nameElem;
2099 if ( !groupName.isEmpty() )
2101 nameElem = doc.createElement( groupName );
2102 parentElem.appendChild( nameElem );
2105 const QList<QgsAttributeEditorElement *> children = container->
children();
2106 for (
const QgsAttributeEditorElement *child : children )
2110 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2114 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2120 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2128 void QgsRenderer::writeAttributesTabLayout( QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2131 if ( !editorContainer )
2136 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2139 void QgsRenderer::writeVectorLayerAttribute(
int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2141#ifndef HAVE_SERVER_PYTHON_PLUGINS
2142 Q_UNUSED( attributes );
2155#ifdef HAVE_SERVER_PYTHON_PLUGINS
2157 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2164 QDomElement attributeElement = doc.createElement( QStringLiteral(
"Attribute" ) );
2165 attributeElement.setAttribute( QStringLiteral(
"name" ), attributeName );
2168 featureElem.appendChild( attributeElement );
2171 bool QgsRenderer::featureInfoFromRasterLayer( QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version )
const
2193 QgsRasterIdentifyResult identifyResult;
2196 const QgsRectangle extent { mapSettings.
extent() };
2209 if ( !identifyResult.
isValid() )
2212 QMap<int, QVariant> attributes = identifyResult.
results();
2218 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2219 int gmlVersion = mWmsParameters.infoFormatVersion();
2220 QString typeName = mContext.layerNickname( *layer );
2226 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2228 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2229 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2232 QDomElement elem = createFeatureGML(
2233 &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr
2235 layerElement.appendChild( elem );
2239 const auto values = identifyResult.
results();
2240 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2242 QVariant value = it.value();
2243 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2249 if ( value.userType() == QMetaType::Type::QString )
2257 for (
const QgsFeatureStore &featureStore : featureStoreList )
2260 for (
const QgsFeature &feature : storeFeatures )
2262 QDomElement elem = createFeatureGML(
2263 &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr
2265 layerElement.appendChild( elem );
2275 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2277 QDomElement attributeElement = infoDocument.createElement( QStringLiteral(
"Attribute" ) );
2278 attributeElement.setAttribute( QStringLiteral(
"name" ), layer->
bandName( it.key() ) );
2283 value = QString::number( it.value().toDouble() );
2286 attributeElement.setAttribute( QStringLiteral(
"value" ), value );
2287 layerElement.appendChild( attributeElement );
2292 const auto values = identifyResult.
results();
2293 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2295 QVariant value = it.value();
2296 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2302 if ( value.userType() == QMetaType::Type::QString )
2309 for (
const QgsFeatureStore &featureStore : featureStoreList )
2312 for (
const QgsFeature &feature : storeFeatures )
2314 for (
const auto &fld : feature.
fields() )
2316 const auto val { feature.
attribute( fld.name() ) };
2317 if ( val.isValid() )
2319 QDomElement attributeElement = infoDocument.createElement( QStringLiteral(
"Attribute" ) );
2320 attributeElement.setAttribute( QStringLiteral(
"name" ), fld.name() );
2321 attributeElement.setAttribute( QStringLiteral(
"value" ), val.toString() );
2322 layerElement.appendChild( attributeElement );
2333 QDomElement maptipElem = infoDocument.createElement( QStringLiteral(
"Attribute" ) );
2334 maptipElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"maptip" ) );
2337 scope->
addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral(
"layer_cursor_point" ), QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2340 layerElement.appendChild( maptipElem );
2346 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2349 if ( filter.contains( QLatin1String(
";" ) ) )
2354 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2355 groupStringList( tokens, QStringLiteral(
"'" ) );
2356 groupStringList( tokens, QStringLiteral(
"\"" ) );
2358 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2361 if ( tokenIt->compare( QLatin1String(
"," ) ) == 0
2362 || tokenIt->compare( QLatin1String(
"(" ) ) == 0
2363 || tokenIt->compare( QLatin1String(
")" ) ) == 0
2364 || tokenIt->compare( QLatin1String(
"=" ) ) == 0
2365 || tokenIt->compare( QLatin1String(
"!=" ) ) == 0
2366 || tokenIt->compare( QLatin1String(
"<" ) ) == 0
2367 || tokenIt->compare( QLatin1String(
"<=" ) ) == 0
2368 || tokenIt->compare( QLatin1String(
">" ) ) == 0
2369 || tokenIt->compare( QLatin1String(
">=" ) ) == 0
2370 || tokenIt->compare( QLatin1String(
"%" ) ) == 0
2371 || tokenIt->compare( QLatin1String(
"IS" ), Qt::CaseInsensitive ) == 0
2372 || tokenIt->compare( QLatin1String(
"NOT" ), Qt::CaseInsensitive ) == 0
2373 || tokenIt->compare( QLatin1String(
"NULL" ), Qt::CaseInsensitive ) == 0
2374 || tokenIt->compare( QLatin1String(
"AND" ), Qt::CaseInsensitive ) == 0
2375 || tokenIt->compare( QLatin1String(
"OR" ), Qt::CaseInsensitive ) == 0
2376 || tokenIt->compare( QLatin1String(
"IN" ), Qt::CaseInsensitive ) == 0
2377 || tokenIt->compare( QLatin1String(
"LIKE" ), Qt::CaseInsensitive ) == 0
2378 || tokenIt->compare( QLatin1String(
"ILIKE" ), Qt::CaseInsensitive ) == 0
2379 || tokenIt->compare( QLatin1String(
"DMETAPHONE" ), Qt::CaseInsensitive ) == 0
2380 || tokenIt->compare( QLatin1String(
"SOUNDEX" ), Qt::CaseInsensitive ) == 0
2381 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2388 ( void ) tokenIt->toDouble( &isNumeric );
2397 if ( *tokenIt == QLatin1String(
"''" ) )
2403 if ( tokenIt->size() > 2
2404 && ( *tokenIt )[0] == QChar(
'\'' )
2405 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2406 && ( *tokenIt )[1] != QChar(
'\'' )
2407 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2413 if ( tokenIt->size() > 2
2414 && ( *tokenIt )[0] == QChar(
'"' )
2415 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' )
2416 && ( *tokenIt )[1] != QChar(
'"' )
2417 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2428 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2431 bool groupActive =
false;
2432 int startGroup = -1;
2433 QString concatString;
2435 for (
int i = 0; i < list.size(); ++i )
2437 QString &str = list[i];
2438 if ( str.startsWith( groupString ) )
2442 concatString.clear();
2447 if ( i != startGroup )
2449 concatString.append(
" " );
2451 concatString.append( str );
2454 if ( str.endsWith( groupString ) )
2457 groupActive =
false;
2459 if ( startGroup != -1 )
2461 list[startGroup] = concatString;
2462 for (
int j = startGroup + 1; j <= endGroup; ++j )
2464 list.removeAt( startGroup + 1 );
2469 concatString.clear();
2475 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2477 QDomDocument SIAInfoDoc;
2478 QDomElement infoDocElement = doc.documentElement();
2479 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2480 SIAInfoDoc.appendChild( SIAInfoDocElement );
2482 QString currentAttributeName;
2483 QString currentAttributeValue;
2484 QDomElement currentAttributeElem;
2485 QString currentLayerName;
2486 QDomElement currentLayerElem;
2487 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( QStringLiteral(
"Layer" ) );
2488 for (
int i = 0; i < layerNodeList.size(); ++i )
2490 currentLayerElem = layerNodeList.at( i ).toElement();
2491 currentLayerName = currentLayerElem.attribute( QStringLiteral(
"name" ) );
2493 QDomElement currentFeatureElem;
2495 QDomNodeList featureList = currentLayerElem.elementsByTagName( QStringLiteral(
"Feature" ) );
2496 if ( featureList.isEmpty() )
2499 QDomNodeList attributeList = currentLayerElem.elementsByTagName( QStringLiteral(
"Attribute" ) );
2500 QDomElement rasterLayerElem;
2501 if ( !attributeList.isEmpty() )
2503 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2505 for (
int j = 0; j < attributeList.size(); ++j )
2507 currentAttributeElem = attributeList.at( j ).toElement();
2508 currentAttributeName = currentAttributeElem.attribute( QStringLiteral(
"name" ) );
2509 currentAttributeValue = currentAttributeElem.attribute( QStringLiteral(
"value" ) );
2510 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2511 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2512 outAttributeElem.appendChild( outAttributeText );
2513 rasterLayerElem.appendChild( outAttributeElem );
2515 if ( !attributeList.isEmpty() )
2517 SIAInfoDocElement.appendChild( rasterLayerElem );
2523 QSet<QString> layerPropertyAttributes;
2524 QString currentLayerId = currentLayerElem.attribute( QStringLiteral(
"id" ) );
2525 if ( !currentLayerId.isEmpty() )
2527 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2530 QString WMSPropertyAttributesString = currentLayer->
customProperty( QStringLiteral(
"WMSPropertyAttributes" ) ).toString();
2531 if ( !WMSPropertyAttributesString.isEmpty() )
2533 QStringList propertyList = WMSPropertyAttributesString.split( QStringLiteral(
"//" ) );
2534 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2536 layerPropertyAttributes.insert( *propertyIt );
2542 QDomElement propertyRefChild;
2543 for (
int j = 0; j < featureList.size(); ++j )
2545 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2546 currentFeatureElem = featureList.at( j ).toElement();
2547 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( QStringLiteral(
"Attribute" ) );
2549 for (
int k = 0; k < attributeList.size(); ++k )
2551 currentAttributeElem = attributeList.at( k ).toElement();
2552 currentAttributeName = currentAttributeElem.attribute( QStringLiteral(
"name" ) );
2553 currentAttributeValue = currentAttributeElem.attribute( QStringLiteral(
"value" ) );
2554 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2556 QDomElement propertyElem = SIAInfoDoc.createElement( QStringLiteral(
"property" ) );
2557 QDomElement identifierElem = SIAInfoDoc.createElement( QStringLiteral(
"identifier" ) );
2558 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2559 identifierElem.appendChild( identifierText );
2560 QDomElement valueElem = SIAInfoDoc.createElement( QStringLiteral(
"value" ) );
2561 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2562 valueElem.appendChild( valueText );
2563 propertyElem.appendChild( identifierElem );
2564 propertyElem.appendChild( valueElem );
2565 if ( propertyRefChild.isNull() )
2567 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2568 propertyRefChild = propertyElem;
2572 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2577 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2578 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2579 SIAAttributeElem.appendChild( SIAAttributeText );
2580 SIAFeatureElem.appendChild( SIAAttributeElem );
2583 SIAInfoDocElement.appendChild( SIAFeatureElem );
2590 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2593 QString featureInfoString = QStringLiteral(
" <!DOCTYPE html>" );
2596 featureInfoString.append( QStringLiteral( R
"HTML(
2599 <title>Information</title>
2600 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2603 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2610 border: 1px solid black;
2611 border-collapse: collapse;
2632 const QDomNodeList layerList = doc.elementsByTagName( QStringLiteral(
"Layer" ) );
2635 for (
int i = 0; i < layerList.size(); ++i )
2637 const QDomElement layerElem = layerList.at( i ).toElement();
2640 const QDomNodeList featureNodeList = layerElem.elementsByTagName( QStringLiteral(
"Feature" ) );
2641 const QDomElement currentFeatureElement;
2643 if ( !featureNodeList.isEmpty() )
2647 const QString featureInfoLayerTitleString = QStringLiteral(
" <div class='layer-title'>%1</div>" ).arg( layerElem.attribute( QStringLiteral(
"title" ) ).toHtmlEscaped() );
2648 featureInfoString.append( featureInfoLayerTitleString );
2651 for (
int j = 0; j < featureNodeList.size(); ++j )
2653 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2656 featureInfoString.append( QStringLiteral( R
"HTML(
2661 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( QStringLiteral(
"Attribute" ) );
2662 for (
int k = 0; k < attributeNodeList.size(); ++k )
2664 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2665 const QString name = attributeElement.attribute( QStringLiteral(
"name" ) ).toHtmlEscaped();
2666 QString value = attributeElement.attribute( QStringLiteral(
"value" ) );
2667 if ( name != QLatin1String(
"maptip" ) )
2669 value = value.toHtmlEscaped();
2674 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2679 .arg( name, value );
2681 featureInfoString.append( featureInfoAttributeString );
2683 else if ( name == QLatin1String(
"maptip" ) )
2685 featureInfoString.append( QStringLiteral( R
"HTML(
2693 featureInfoString.append( QStringLiteral( R
"HTML(
2700 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( QStringLiteral(
"Attribute" ) );
2703 if ( !attributeNodeList.isEmpty() )
2707 const QString featureInfoLayerTitleString = QStringLiteral(
" <div class='layer-title'>%1</div>" ).arg( layerElem.attribute( QStringLiteral(
"title" ) ).toHtmlEscaped() );
2708 featureInfoString.append( featureInfoLayerTitleString );
2710 featureInfoString.append( QStringLiteral( R
"HTML(
2714 for (
int j = 0; j < attributeNodeList.size(); ++j )
2716 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2717 const QString name = attributeElement.attribute( QStringLiteral(
"name" ) ).toHtmlEscaped();
2718 QString value = attributeElement.attribute( QStringLiteral(
"value" ) );
2719 if ( value.isEmpty() )
2721 value = QStringLiteral(
"no data" );
2723 if ( name != QLatin1String(
"maptip" ) )
2725 value = value.toHtmlEscaped();
2730 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2735 .arg( name, value );
2738 featureInfoString.append( featureInfoAttributeString );
2740 else if ( name == QLatin1String(
"maptip" ) )
2742 featureInfoString.append( QStringLiteral( R
"HTML(
2750 featureInfoString.append( QStringLiteral( R
"HTML(
2760 featureInfoString.append( QStringLiteral( R
"HTML(
2764 return featureInfoString.toUtf8();
2767 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2769 QString featureInfoString;
2772 featureInfoString.append(
"GetFeatureInfo results\n" );
2773 featureInfoString.append(
"\n" );
2775 QDomNodeList layerList = doc.elementsByTagName( QStringLiteral(
"Layer" ) );
2778 for (
int i = 0; i < layerList.size(); ++i )
2780 QDomElement layerElem = layerList.at( i ).toElement();
2782 featureInfoString.append(
"Layer '" + layerElem.attribute( QStringLiteral(
"name" ) ) +
"'\n" );
2785 QDomNodeList featureNodeList = layerElem.elementsByTagName( QStringLiteral(
"Feature" ) );
2786 QDomElement currentFeatureElement;
2788 if ( !featureNodeList.isEmpty() )
2790 for (
int j = 0; j < featureNodeList.size(); ++j )
2792 QDomElement featureElement = featureNodeList.at( j ).toElement();
2793 featureInfoString.append(
"Feature " + featureElement.attribute( QStringLiteral(
"id" ) ) +
"\n" );
2796 QDomNodeList attributeNodeList = featureElement.elementsByTagName( QStringLiteral(
"Attribute" ) );
2797 for (
int k = 0; k < attributeNodeList.size(); ++k )
2799 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2800 featureInfoString.append( attributeElement.attribute( QStringLiteral(
"name" ) ) +
" = '" + attributeElement.attribute( QStringLiteral(
"value" ) ) +
"'\n" );
2806 QDomNodeList attributeNodeList = layerElem.elementsByTagName( QStringLiteral(
"Attribute" ) );
2807 for (
int j = 0; j < attributeNodeList.size(); ++j )
2809 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2810 QString value = attributeElement.attribute( QStringLiteral(
"value" ) );
2811 if ( value.isEmpty() )
2813 value = QStringLiteral(
"no data" );
2815 featureInfoString.append( attributeElement.attribute( QStringLiteral(
"name" ) ) +
" = '" + value +
"'\n" );
2819 featureInfoString.append(
"\n" );
2822 return featureInfoString.toUtf8();
2825 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
2828 {
"type",
"FeatureCollection" },
2829 {
"features", json::array() },
2832 const bool withDisplayName = mWmsParameters.withDisplayName();
2834 const QDomNodeList layerList = doc.elementsByTagName( QStringLiteral(
"Layer" ) );
2835 for (
int i = 0; i < layerList.size(); ++i )
2837 const QDomElement layerElem = layerList.at( i ).toElement();
2838 const QString layerName = layerElem.attribute( QStringLiteral(
"name" ) );
2840 QgsMapLayer *layer =
nullptr;
2841 for ( QgsMapLayer *l : layers )
2843 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
2854 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
2859 const QDomNodeList featuresNode = layerElem.elementsByTagName( QStringLiteral(
"Feature" ) );
2860 if ( featuresNode.isEmpty() )
2863 QMap<QgsFeatureId, QString> fidMap;
2864 QMap<QgsFeatureId, QString> fidDisplayNameMap;
2866 for (
int j = 0; j < featuresNode.size(); ++j )
2868 const QDomElement featureNode = featuresNode.at( j ).toElement();
2869 const QString fid = featureNode.attribute( QStringLiteral(
"id" ) );
2872 if ( expression.isEmpty() )
2874 feature = vl->
getFeature( fid.toLongLong() );
2878 QgsFeatureRequest request { QgsExpression( expression ) };
2883 fidMap.insert( feature.
id(), fid );
2888 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
2889 for (
int k = 0; k < attrs.count(); k++ )
2891 const QDomElement elm = attrs.at( k ).toElement();
2892 if ( elm.attribute( QStringLiteral(
"name" ) ).compare(
"geometry" ) == 0 )
2894 wkt = elm.attribute(
"value" );
2899 if ( !wkt.isEmpty() )
2907 if ( withDisplayName )
2909 QString displayName;
2910 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
2911 for (
int k = 0; k < attrs.count(); k++ )
2913 const QDomElement elm = attrs.at( k ).toElement();
2914 if ( elm.attribute( QStringLiteral(
"name" ) ).compare(
"displayName" ) == 0 )
2916 displayName = elm.attribute(
"value" );
2920 fidDisplayNameMap.insert( feature.
id(), displayName );
2923 features << feature;
2926 if ( !attributes.isEmpty() )
2929 const QDomNodeList attributesNode = featureNode.elementsByTagName( QStringLiteral(
"Attribute" ) );
2930 for (
int k = 0; k < attributesNode.size(); ++k )
2932 const QDomElement attributeElement = attributesNode.at( k ).toElement();
2933 const QString fieldName = attributeElement.attribute( QStringLiteral(
"name" ) );
2934 attributes << feature.fieldNameIndex( fieldName );
2939 QgsJsonExporter exporter( vl );
2940 exporter.setAttributeDisplayName(
true );
2941 exporter.setAttributes( attributes );
2942 exporter.setIncludeGeometry( withGeometry );
2943 exporter.setTransformGeometries(
false );
2947 for (
const auto &feature : std::as_const( features ) )
2949 const QString
id = QStringLiteral(
"%1.%2" ).arg( layerName ).arg( fidMap.value( feature.id() ) );
2950 QVariantMap extraProperties;
2951 if ( withDisplayName )
2953 extraProperties.insert( QStringLiteral(
"display_name" ), fidDisplayNameMap.value( feature.id() ) );
2955 json[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id ) );
2960 auto properties = json::object();
2961 const QDomNodeList attributesNode = layerElem.elementsByTagName( QStringLiteral(
"Attribute" ) );
2962 for (
int j = 0; j < attributesNode.size(); ++j )
2964 const QDomElement attrElmt = attributesNode.at( j ).toElement();
2965 const QString name = attrElmt.attribute( QStringLiteral(
"name" ) );
2967 QString value = attrElmt.attribute( QStringLiteral(
"value" ) );
2968 if ( value.isEmpty() )
2970 value = QStringLiteral(
"null" );
2973 properties[name.toStdString()] = value.toStdString();
2976 json[
"features"].push_back(
2977 { {
"type",
"Feature" },
2978 {
"id", layerName.toStdString() },
2979 {
"properties", properties }
2986 return QByteArray::fromStdString( json.dump( 2 ) );
2988 return QByteArray::fromStdString( json.dump() );
2992 QDomElement QgsRenderer::createFeatureGML(
2993 const QgsFeature *feat,
2994 QgsVectorLayer *layer,
2996 QgsCoordinateReferenceSystem &crs,
2997 const QgsMapSettings &mapSettings,
2998 const QString &typeName,
3001 QStringList *attributes
3005 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3012 typeNameElement.setAttribute( QStringLiteral(
"fid" ), QStringLiteral(
"%1.%2" ).arg( typeName, fid ) );
3014 QgsCoordinateTransform transform;
3015 if ( layer && layer->
crs() != crs )
3020 QgsGeometry geom = feat->
geometry();
3022 QgsExpressionContext expressionContext;
3029 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3043 catch ( QgsCsException &e )
3049 QDomElement bbElem = doc.createElement( QStringLiteral(
"gml:boundedBy" ) );
3050 QDomElement boxElem;
3062 boxElem.setAttribute( QStringLiteral(
"srsName" ), crs.
authid() );
3064 bbElem.appendChild( boxElem );
3065 typeNameElement.appendChild( bbElem );
3069 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3070 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3071 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3074 const QList<QgsAttributeEditorElement *> children = container->
children();
3075 for (
const QgsAttributeEditorElement *child : children )
3077 switch ( child->type() )
3081 if ( findAttributeInTree( attributeName, child ) )
3089 if ( child->name() == attributeName )
3097 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3098 if ( relationEditor )
3100 const QgsRelation &relation { relationEditor->
relation() };
3104 for (
const auto &idx : std::as_const( referencedFields ) )
3106 const QgsField f { layer->
fields().
at( idx ) };
3107 if ( f.
name() == attributeName )
3116 for (
const auto &idx : std::as_const( referencingFields ) )
3118 const QgsField f { layer->
fields().
at( idx ) };
3119 if ( f.
name() == attributeName )
3136 if ( withGeom && !geom.
isNull() )
3145 QDomElement geomElem = doc.createElement( QStringLiteral(
"qgs:geometry" ) );
3146 QDomElement gmlElem;
3156 if ( !gmlElem.isNull() )
3160 gmlElem.setAttribute( QStringLiteral(
"srsName" ), crs.
authid() );
3162 geomElem.appendChild( gmlElem );
3163 typeNameElement.appendChild( geomElem );
3168 QgsAttributes featureAttributes = feat->
attributes();
3169 QgsFields fields = feat->
fields();
3170 for (
int i = 0; i < fields.
count(); ++i )
3172 QString attributeName = fields.
at( i ).
name();
3179 if ( attributes && !attributes->contains( attributeName ) )
3184 if ( honorFormConfig )
3187 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3193 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3194 QString fieldTextString = featureAttributes.at( i ).toString();
3199 QDomText fieldText = doc.createTextNode( fieldTextString );
3200 fieldElem.appendChild( fieldText );
3201 typeNameElement.appendChild( fieldElem );
3212 QDomElement fieldElem = doc.createElement( QStringLiteral(
"qgs:maptip" ) );
3213 QDomText maptipText = doc.createTextNode( fieldTextString );
3214 fieldElem.appendChild( maptipText );
3215 typeNameElement.appendChild( fieldElem );
3219 return typeNameElement;
3222 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3226 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3228 if ( setup.
config().value( QStringLiteral(
"AllowMulti" ) ).toBool() && value.startsWith( QLatin1Char(
'{' ) ) && value.endsWith( QLatin1Char(
'}' ) ) )
3230 value = value.mid( 1, value.size() - 2 );
3235 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3239 return QgsRectangle();
3242 double mapUnitTolerance = 0.0;
3245 if ( !mWmsParameters.polygonTolerance().isEmpty()
3246 && mWmsParameters.polygonToleranceAsInt() > 0 )
3252 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3257 if ( !mWmsParameters.lineTolerance().isEmpty()
3258 && mWmsParameters.lineToleranceAsInt() > 0 )
3264 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3269 if ( !mWmsParameters.pointTolerance().isEmpty()
3270 && mWmsParameters.pointToleranceAsInt() > 0 )
3276 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3283 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3287 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3289 QList<QgsMapLayer *> highlightLayers;
3292 QString crs = mWmsParameters.crs();
3293 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3296 QDomDocument sldDoc;
3300 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3307 std::unique_ptr<QgsFeatureRenderer> renderer;
3308 QDomElement el = sldDoc.documentElement();
3318 QString url = typeName +
"?crs=" + crs;
3319 if ( !param.mLabel.isEmpty() )
3321 url +=
"&field=label:string";
3326 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName, QLatin1String(
"memory" ), options );
3333 QgsFeature fet( layer->
fields() );
3334 if ( !param.mLabel.isEmpty() )
3336 fet.setAttribute( 0, param.mLabel );
3339 QgsPalLayerSettings palSettings;
3344 palSettings.
dist = param.mLabelDistance;
3353 switch ( param.mGeom.type() )
3364 QgsPointXY pt = param.mGeom.asPoint();
3366 QVariant x( pt.
x() );
3369 QVariant y( pt.
y() );
3381 QgsGeometry point = param.mGeom.pointOnSurface();
3382 QgsPointXY pt = point.
asPoint();
3386 QVariant x( pt.
x() );
3390 QVariant y( pt.
y() );
3394 QVariant hali(
"Center" );
3398 QVariant vali(
"Half" );
3410 QgsTextFormat textFormat;
3411 QgsTextBufferSettings bufferSettings;
3413 if ( param.mColor.isValid() )
3415 textFormat.
setColor( param.mColor );
3418 if ( param.mSize > 0 )
3420 textFormat.
setSize( param.mSize );
3428 if ( !param.mFont.isEmpty() )
3430 textFormat.
setFont( param.mFont );
3433 if ( param.mBufferColor.isValid() )
3435 bufferSettings.
setColor( param.mBufferColor );
3438 if ( param.mBufferSize > 0 )
3441 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3447 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3451 fet.setGeometry( param.mGeom );
3460 highlightLayers.append( layer.release() );
3464 mTemporaryLayers.append( highlightLayers );
3465 return highlightLayers;
3468 void QgsRenderer::removeTemporaryLayers()
3470 qDeleteAll( mTemporaryLayers );
3471 mTemporaryLayers.clear();
3474 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3476 QPainter *painter =
nullptr;
3478 QgsFeatureFilterProviderGroup filters;
3480#ifdef HAVE_SERVER_PYTHON_PLUGINS
3481 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3484 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3486 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3487 painter = renderJob.takePainter();
3489 logRenderingErrors( renderJob.errors() );
3491 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3493 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3495 QString layerWMSName;
3496 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3499 layerWMSName = mContext.layerNickname( *errorLayer );
3502 QString errorMessage = QStringLiteral(
"Rendering error : '%1'" ).arg( e.
message );
3503 if ( !layerWMSName.isEmpty() )
3505 errorMessage = QStringLiteral(
"Rendering error : '%1' in layer '%2'" ).arg( e.
message, layerWMSName );
3507 throw QgsException( errorMessage );
3513 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3515 if ( opacity >= 0 && opacity <= 255 )
3517 switch ( layer->
type() )
3521 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3526 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3534 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3535 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3536 rasterRenderer->
setOpacity( opacity / 255. );
3542 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3558 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3562 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3563 QStringList expList;
3564 for (
const QgsWmsParametersFilter &filter : filters )
3569 QDomDocument filterXml;
3571#if QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 )
3573 if ( !filterXml.setContent( filter.mFilter,
true, &errorMsg ) )
3578 QXmlStreamReader xmlReader( filter.mFilter );
3579 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( QStringLiteral(
"fes" ), QStringLiteral(
"http://www.opengis.net/fes/2.0" ) ) );
3580 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( QStringLiteral(
"ogc" ), QStringLiteral(
"http://www.opengis.net/ogc" ) ) );
3581 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3583 throw QgsBadRequestException(
QgsServiceException::QGIS_InvalidParameterValue, QStringLiteral(
"Filter string rejected. Error %1:%2 : %3. The XML string was: %4" ).arg( QString::number( result.errorLine ), QString::number( result.errorColumn ), result.errorMessage, filter.mFilter ) );
3586 QDomElement filterElem = filterXml.firstChildElement();
3591 expList << filterExp->dump();
3597 if ( !testFilterStringSafety( filter.mFilter ) )
3599 throw QgsSecurityException( QStringLiteral(
"The filter string %1"
3600 " has been rejected because of security reasons."
3601 " Note: Text strings have to be enclosed in single or double quotes."
3602 " A space between each word / special character is mandatory."
3603 " Allowed Keywords and special characters are"
3604 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3605 " Not allowed are semicolons in the filter expression." )
3607 filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' )
3611 QString newSubsetString = filter.mFilter;
3614 newSubsetString.prepend(
") AND (" );
3615 newSubsetString.append(
")" );
3616 newSubsetString.prepend( filteredLayer->
subsetString() );
3617 newSubsetString.prepend(
"(" );
3627 expList.append( dimensionFilter( filteredLayer ) );
3631 if ( expList.size() == 1 )
3635 else if ( expList.size() > 1 )
3637 exp = QStringLiteral(
"( %1 )" ).arg( expList.join( QLatin1String(
" ) AND ( " ) ) );
3639 if ( !exp.isEmpty() )
3641 auto expression = std::make_unique<QgsExpression>( exp );
3645 mFeatureFilter.setFilter( filteredLayer, *expression );
3652 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3654 QStringList expList;
3656 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3657 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3658 if ( wmsDims.isEmpty() )
3663 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3664 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3673 if ( fieldIndex == -1 )
3678 int endFieldIndex = -1;
3679 if ( !dim.endFieldName.isEmpty() )
3681 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3682 if ( endFieldIndex == -1 )
3688 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3692 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::AllValues )
3696 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
3698 defValue = dim.referenceValue;
3703 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3704 if ( endFieldIndex != -1 )
3706 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3709 QList<QVariant> values = qgis::setToList( uniqueValues );
3710 std::sort( values.begin(), values.end() );
3711 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
3713 defValue = values.first();
3715 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
3717 defValue = values.last();
3721 if ( endFieldIndex == -1 )
3727 QStringList expElems;
3732 expList << expElems.join(
' ' );
3738 QgsField dimField = layer->
fields().
at( fieldIndex );
3740 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3742 QStringList dimExplist;
3744 QStringList dimValues = dimParamValue.split(
',' );
3745 for (
int i = 0; i < dimValues.size(); ++i )
3747 QString dimValue = dimValues[i];
3749 if ( dimValue.size() > 1 )
3751 dimValue = dimValue.trimmed();
3754 if ( dimValue.contains(
'/' ) )
3756 QStringList rangeValues = dimValue.split(
'/' );
3758 if ( rangeValues.size() != 2 )
3763 QVariant rangeMin = QVariant( rangeValues[0] );
3764 QVariant rangeMax = QVariant( rangeValues[1] );
3775 QStringList expElems;
3776 if ( endFieldIndex == -1 )
3796 << QStringLiteral(
")" );
3798 dimExplist << expElems.join(
' ' );
3802 QVariant dimVariant = QVariant( dimValue );
3808 if ( endFieldIndex == -1 )
3817 QStringList expElems;
3822 dimExplist << expElems.join(
' ' );
3827 if ( dimExplist.size() == 1 )
3829 expList << dimExplist;
3831 else if ( dimExplist.size() > 1 )
3833 expList << QStringLiteral(
"( %1 )" ).arg( dimExplist.join( QLatin1String(
" ) OR ( " ) ) );
3840 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
3844 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3846 QgsFeatureRequest request;
3850 if ( selectedIds.empty() )
3861 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
3863#ifdef HAVE_SERVER_PYTHON_PLUGINS
3870 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
3873 QgsRectangle mapExtent = mapSettings.
extent();
3881 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
3883 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
3884 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
3888 renderContext.
setFeedback( mContext.socketFeedback() );
3890 for ( QgsAnnotation *annotation : annotations )
3892 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
3894 if ( !annotation || !annotation->isVisible() )
3900 if ( annotation->hasFixedMapPosition() )
3902 QgsPointXY mapPos = annotation->mapPosition();
3903 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
3908 mapPos = coordTransform.transform( mapPos );
3910 catch (
const QgsCsException &e )
3916 offsetX = devicePos.
x();
3917 offsetY = devicePos.
y();
3921 const QPointF relativePos = annotation->relativePosition();
3922 offsetX = mapSettings.
outputSize().width() * relativePos.x();
3923 offsetY = mapSettings.
outputSize().height() * relativePos.y();
3927 painter->translate( offsetX, offsetY );
3928 annotation->render( renderContext );
3933 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
3938 QImage *scaledImage =
nullptr;
3939 const int width = mWmsParameters.widthAsInt();
3940 const int height = mWmsParameters.heightAsInt();
3941 if ( width != image->width() || height != image->height() )
3943 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
3951 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
3952 for ( ; it != errors.constEnd(); ++it )
3954 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
3955 if ( !it->layerID.isEmpty() )
3957 msg += QString(
" in layer %1" ).arg( it->layerID );
3963 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
3970 QList<QgsLayoutItemMap *> mapList;
3974 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
3975 for ( ; mapIt != mapList.constEnd(); ++mapIt )
3977 logRenderingErrors( ( *mapIt )->renderingErrors() );
3980 if ( mContext.settings().ignoreRenderingErrors() )
3985 mapIt = mapList.constBegin();
3986 for ( ; mapIt != mapList.constEnd(); ++mapIt )
3988 if ( !( *mapIt )->renderingErrors().isEmpty() )
3990 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
3991 throw QgsException( QStringLiteral(
"Rendering error : '%1' in layer %2" ).arg( e.
message, e.
layerID ) );
3998 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4000 for (
auto layer : layers )
4002 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4004 if ( !mContext.layersToRender().contains( layer ) )
4009 if ( mContext.isExternalLayer( param.mNickname ) )
4013 setLayerOpacity( layer, param.mOpacity );
4020 setLayerSld( layer, mContext.sld( *layer ) );
4024 setLayerStyle( layer, mContext.style( *layer ) );
4029 setLayerOpacity( layer, param.mOpacity );
4034 setLayerFilter( layer, param.mFilter );
4039 setLayerAccessControlFilter( layer );
4044 setLayerSelection( layer, param.mSelection );
4047 if ( settings && mContext.updateExtent() )
4049 updateExtent( layer, *settings );
4055 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4059 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4061 if ( style.isEmpty() )
4073 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4078 QString sldStyleName =
"__sld_style";
4079 while ( styles.contains( sldStyleName ) )
4081 sldStyleName.append(
'@' );
4089 QgsLegendSettings QgsRenderer::legendSettings()
4092 QgsLegendSettings settings = mWmsParameters.legendSettings();
4094 if ( !mWmsParameters.bbox().isEmpty() )
4096 QgsMapSettings mapSettings;
4098 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4099 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'...
@ 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)...
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 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.
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.
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.
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.
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.
Layers and optional attribute index to split into multiple layers using attribute value as layer name...
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