23#include <nlohmann/json.hpp>
88#include <QTemporaryFile>
90#include <QXmlStreamReader>
92using namespace Qt::StringLiterals;
116 : mContext( context )
118 mProject = mContext.project();
120 mWmsParameters = mContext.parameters();
121 mWmsParameters.dump();
126 removeTemporaryLayers();
132 std::unique_ptr<QgsWmsRestorer> restorer;
133 restorer = std::make_unique<QgsWmsRestorer>( mContext );
136 QList<QgsMapLayer *> layers = mContext.layersToRender();
139 const qreal dpmm = mContext.dotsPerMm();
144 const auto layersToRender = mContext.layersToRender();
145 for (
const auto &layer : std::as_const( layersToRender ) )
148 if ( layer->dataProvider()->name() ==
"wms"_L1 )
152 const auto image { layerNode->getLegendGraphicBlocking() };
153 if ( !image.isNull() )
156 if ( mContext.isValidWidthHeight( image.width(), image.height() ) )
158 const double w = image.width() / dpmm;
159 const double h = image.height() / dpmm;
160 const QSizeF newWmsSize { w, h };
173 if ( !mWmsParameters.bbox().isEmpty() )
177 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
178 configureMapSettings( tmp.get(), mapSettings );
184 context = configureDefaultRenderContext();
188 std::unique_ptr<QImage> image;
189 const QSizeF minSize = renderer.
minimumSize( &context );
190 const QSize size(
static_cast<int>( minSize.width() * dpmm ),
static_cast<int>( minSize.height() * dpmm ) );
191 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
195 image.reset( createImage( size ) );
198 QPainter painter( image.get() );
201 if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
203 if ( painter.renderHints() & QPainter::LosslessImageRendering )
213 return image.release();
219 std::unique_ptr<QgsWmsRestorer> restorer;
220 restorer = std::make_unique<QgsWmsRestorer>( mContext );
223 QList<QgsMapLayer *> layers = mContext.layersToRender();
227 const QSize size( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() );
229 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
233 std::unique_ptr<QImage> image( createImage( size ) );
236 const qreal dpmm = mContext.dotsPerMm();
237 std::unique_ptr<QPainter> painter;
238 painter = std::make_unique<QPainter>( image.get() );
239 painter->setRenderHint( QPainter::Antialiasing,
true );
240 painter->scale( dpmm, dpmm );
251 nodeModel.
drawSymbol( settings, &ctx, size.height() / dpmm );
254 return image.release();
260 std::unique_ptr<QgsWmsRestorer> restorer;
261 restorer = std::make_unique<QgsWmsRestorer>( mContext );
264 QList<QgsMapLayer *> layers = mContext.layersToRender();
280 std::unique_ptr<QgsWmsRestorer> restorer;
281 restorer = std::make_unique<QgsWmsRestorer>( mContext );
284 QList<QgsMapLayer *> layers = mContext.layersToRender();
293 QJsonObject jsonSymbol {
legendNode.exportSymbolToJson( settings, renderContext ) };
300 if ( vLayer->renderer() )
304 const QString ruleExp { vLayer->renderer()->legendKeyToExpression( ruleKey, vLayer, ok ) };
307 jsonSymbol[u
"rule"_s] = ruleExp;
316 void QgsRenderer::runHitTest(
const QgsMapSettings &mapSettings, HitTest &hitTest )
const
320 for (
const QString &
id : mapSettings.
layerIds() )
337 runHitTestLayer( vl, usedSymbols, context );
341 void QgsRenderer::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context )
const
343 std::unique_ptr<QgsFeatureRenderer> r( vl->
renderer()->
clone() );
345 r->startRender( context, vl->
fields() );
347 QgsFeatureRequest request( context.
extent() );
349 QgsFeatureIterator fi = vl->
getFeatures( request );
353 if ( moreSymbolsPerFeature )
355 for ( QgsSymbol *s : r->originalSymbolsForFeature( f, context ) )
361 r->stopRender( context );
367 if ( !mContext.isValidWidthHeight() )
373 std::unique_ptr<QgsWmsRestorer> restorer;
374 restorer = std::make_unique<QgsWmsRestorer>( mContext );
379 QList<QgsMapLayer *> layers = mContext.layersToRender();
383 std::unique_ptr<QPainter> painter;
384 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
387 configureMapSettings( image.get(), mapSettings );
394 runHitTest( mapSettings,
symbols );
402 std::unique_ptr<QgsWmsRestorer> restorer;
403 restorer = std::make_unique<QgsWmsRestorer>( mContext );
406 const QString templateName = mWmsParameters.composerTemplate();
407 if ( templateName.isEmpty() )
430 std::unique_ptr<QgsPrintLayout> layout( sourceLayout->
clone() );
434 QStringList atlasPk = mWmsParameters.atlasPk();
435 if ( !atlasPk.isEmpty() )
437 atlas = layout->atlas();
438 if ( !atlas || !atlas->
enabled() )
451 if ( atlasPk.size() == 1 && atlasPk.at( 0 ) ==
"*"_L1 )
455 if ( atlas->
count() > maxAtlasFeatures )
463 if ( pkIndexes.size() == 0 )
465 QgsDebugMsgLevel( u
"Atlas print: layer %1 has no primary key attributes"_s.arg( cLayer->
name() ), 2 );
469 const int pkIndexesSize { std::max<int>( pkIndexes.size(), 1 ) };
471 QStringList pkAttributeNames;
472 for (
int pkIndex : std::as_const( pkIndexes ) )
474 pkAttributeNames.append( cLayer->
fields().
at( pkIndex ).
name() );
477 const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
478 if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() )
484 if ( nAtlasFeatures > maxAtlasFeatures )
488 QString(
"%1 atlas features have been requested, but the project configuration only allows printing %2 atlas features at a time" ).arg( nAtlasFeatures ).arg( maxAtlasFeatures )
492 QString filterString;
493 int currentAtlasPk = 0;
495 for (
int i = 0; i < nAtlasFeatures; ++i )
499 filterString.append(
" OR " );
502 filterString.append(
"( " );
505 if ( pkAttributeNames.isEmpty() )
507 filterString.append( u
"$id = %1"_s.arg( atlasPk.at( currentAtlasPk ) ) );
512 for (
int j = 0; j < pkIndexes.size(); ++j )
516 filterString.append(
" AND " );
523 filterString.append(
" )" );
531 if ( !errorString.isEmpty() )
533 throw QgsException( u
"An error occurred during the Atlas print: %1"_s.arg( errorString ) );
541 QList<QgsMapLayer *> layers = mContext.layersToRender();
545 auto image = std::make_unique<QImage>();
546 configureMapSettings( image.get(), mapSettings );
552 configurePrintLayout( layout.get(), mapSettings, atlas );
556 const QList<QgsMapLayer *> lyrs = mapSettings.
layers();
558#ifdef HAVE_SERVER_PYTHON_PLUGINS
559 mContext.accessControl()->resolveFilterFeatures( lyrs );
563 QHash<const QgsVectorLayer *, QStringList> fltrs;
568 fltrs.insert( vl, dimensionFilter( vl ) );
580 QTemporaryFile tempOutputFile( QDir::tempPath() +
'/' + u
"XXXXXX.%1"_s.arg( extension ) );
581 if ( !tempOutputFile.open() )
583 throw QgsException( u
"Could not open temporary file for the GetPrint request."_s );
591 if ( !mWmsParameters.dpi().isEmpty() )
594 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
596 exportSettings.
dpi = dpi;
609 atlasSvgExport.
exportToSvg( tempOutputFile.fileName(), exportSettings );
615 exporter.
exportToSvg( tempOutputFile.fileName(), exportSettings );
624 double dpi( layout->renderContext().dpi() );
625 if ( !mWmsParameters.dpi().isEmpty() )
628 double _dpi = mWmsParameters.dpi().toDouble( &ok );
632 exportSettings.
dpi = dpi;
638 QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );
643 const QSize imageSize = QSize(
static_cast<int>( width.
length() * dpi / 25.4 ),
static_cast<int>( height.
length() * dpi / 25.4 ) );
645 const QString paramWidth = mWmsParameters.width();
646 const QString paramHeight = mWmsParameters.height();
651 if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
653 exportSettings.
imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
655 else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
657 exportSettings.
imageSize = QSize( paramWidth.toInt(),
static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
659 else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
661 exportSettings.
imageSize = QSize(
static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
669 exportSettings.
pages.append( 0 );
677 atlasPngExport.
exportToImage( tempOutputFile.fileName(), exportSettings );
681 throw QgsServiceException( u
"Bad request"_s, u
"Atlas error: empty atlas."_s, QString(), 400 );
687 exporter.
exportToImage( tempOutputFile.fileName(), exportSettings );
695 if ( !mWmsParameters.dpi().isEmpty() )
698 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
700 exportSettings.
dpi = dpi;
705 exportSettings.
rasterizeWholeImage = layout->customProperty( u
"rasterize"_s,
false ).toBool();
707 QVector<qreal> requestMapScales = mWmsParameters.pdfPredefinedMapScales();
708 if ( requestMapScales.size() > 0 )
717 QStringList exportThemes = mWmsParameters.pdfExportMapThemes();
718 if ( exportThemes.size() > 0 )
722 exportSettings.
writeGeoPdf = mWmsParameters.writeGeospatialPdf();
728 if ( mWmsParameters.pdfLosslessImageCompression() )
732 if ( mWmsParameters.pdfDisableTiledRasterRendering() )
745 exporter.
exportToPdf( tempOutputFile.fileName(), exportSettings );
755 handlePrintErrors( atlas->
layout() );
759 handlePrintErrors( layout.get() );
762 return tempOutputFile.readAll();
769 QList<QgsLayoutItemMap *> maps;
775 for (
const auto &map : std::as_const( maps ) )
781 if ( cMapParams.
mLayers.isEmpty() )
786 if ( !atlas || !map->atlasDriven() )
792 c->removeLayoutItem( map );
801 QgsRectangle r( cMapParams.
mExtent );
809 if ( cMapParams.
mScale > 0 )
811 map->setScale(
static_cast<double>( cMapParams.
mScale ) );
817 map->setMapRotation( cMapParams.
mRotation );
821 if ( !map->keepLayerSet() )
823 QList<QgsMapLayer *> layerSet;
825 for (
const auto &layer : std::as_const( cMapParams.
mLayers ) )
827 if ( mContext.isValidGroup( layer.mNickname ) )
829 QList<QgsMapLayer *> layersFromGroup;
831 const QList<QgsMapLayer *> cLayersFromGroup = mContext.layersFromGroup( layer.mNickname );
832 for ( QgsMapLayer *layerFromGroup : cLayersFromGroup )
834 if ( !layerFromGroup )
839 layersFromGroup.push_front( layerFromGroup );
842 if ( !layersFromGroup.isEmpty() )
844 layerSet.append( layersFromGroup );
849 QgsMapLayer *mlayer = mContext.layer( layer.mNickname );
856 setLayerStyle( mlayer, layer.mStyle );
861 std::reverse( layerSet.begin(), layerSet.end() );
866 QMap<QString, QString> layersStyle;
867 if ( map->followVisibilityPreset() )
877 const QString presetName = map->followVisibilityPresetName();
878 if ( layerSet.isEmpty() )
881 const QgsExpressionContext ex { map->createExpressionContext() };
882 layerSet = map->layersToRender( &ex );
885 map->setFollowVisibilityPreset(
false );
889 for (
const auto &layerMapThemeRecord : std::as_const( mapThemeRecords ) )
891 if ( layerSet.contains( layerMapThemeRecord.layer() ) )
893 layersStyle.insert( layerMapThemeRecord.layer()->id(), layerMapThemeRecord.layer()->styleManager()->style( layerMapThemeRecord.currentStyle ).xmlData() );
899 const QList<QgsMapLayer *> highlights = highlightLayers( cMapParams.
mHighlightLayers );
900 for (
const auto &hl : std::as_const( highlights ) )
902 layerSet.prepend( hl );
905 map->setLayers( layerSet );
906 map->setKeepLayerSet(
true );
910 if ( !layersStyle.isEmpty() )
912 map->setLayerStyleOverrides( layersStyle );
913 map->setKeepLayerStyles(
true );
920 map->grid()->setIntervalX(
static_cast<double>( cMapParams.
mGridX ) );
921 map->grid()->setIntervalY(
static_cast<double>( cMapParams.
mGridY ) );
926 QList<QgsLayoutItemLabel *> labels;
927 c->layoutItems<QgsLayoutItemLabel>( labels );
928 for (
const auto &label : std::as_const( labels ) )
931 const QString labelId = label->id();
932 const QString labelParam = mWmsParameters.layoutParameter( labelId, ok );
937 if ( labelParam.isEmpty() )
941 c->removeItem( label );
946 label->setText( labelParam );
950 QList<QgsLayoutItemHtml *> htmls;
951 c->layoutObjects<QgsLayoutItemHtml>( htmls );
952 for (
const auto &html : std::as_const( htmls ) )
954 if ( html->frameCount() == 0 )
957 QgsLayoutFrame *htmlFrame = html->frame( 0 );
959 const QString htmlId = htmlFrame->
id();
960 const QString htmlValue = mWmsParameters.layoutParameter( htmlId, ok );
970 if ( htmlValue.isEmpty() )
972 c->removeMultiFrame( html );
979 QUrl newUrl( htmlValue );
980 html->setUrl( newUrl );
984 html->setHtml( htmlValue );
991 QList<QgsLayoutItemLegend *> legends;
992 c->layoutItems<QgsLayoutItemLegend>( legends );
993 for (
const auto &legend : std::as_const( legends ) )
995 switch ( legend->syncMode() )
1002 const QgsLayoutItemMap *map = legend->linkedMap();
1011 QgsLegendModel *model = legend->model();
1012 QStringList layerSet;
1013 QList<QgsMapLayer *> mapLayers;
1014 if ( map->
layers().isEmpty() )
1018 mapLayers = mProject->mapLayers(
true ).values();
1022 mapLayers = map->
layers();
1024 const QList<QgsMapLayer *> layerList = mapLayers;
1025 for (
const auto &layer : layerList )
1026 layerSet << layer->id();
1029 QgsLayerTree *root = model->
rootGroup();
1036 for (
const auto &layerId : layerIds )
1038 QgsLayerTreeLayer *nodeLayer = root->
findLayer( layerId );
1043 if ( !layerSet.contains( layerId ) )
1045 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1049 QgsMapLayer *layer = nodeLayer->
layer();
1052 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1070 if ( !mContext.isValidWidthHeight() )
1075 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1081 std::unique_ptr<QgsWmsRestorer> restorer;
1082 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1085 QList<QgsMapLayer *> layers = mContext.layersToRender();
1092 std::unique_ptr<QPainter> painter;
1093 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
1096 configureMapSettings( image.get(), mapSettings );
1102 QPainter *renderedPainter = layersRendering( mapSettings, image.get() );
1103 if ( !renderedPainter )
1108 painter.reset( renderedPainter );
1111 annotationsRendering( painter.get(), mapSettings );
1117 QImage *scaledImage = scaleImage( image.get() );
1119 image.reset( scaledImage );
1122 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1132 QList<QgsMapLayer *> layers = mContext.layersToRender();
1136 const QStringList attributes = mWmsParameters.dxfLayerAttributes();
1137 QList<QgsDxfExport::DxfLayer> dxfLayers;
1149 int layerAttribute = -1;
1150 if ( attributes.size() > layerIdx )
1159 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1161 QString crs = mWmsParameters.crs();
1162 if ( crs.compare( u
"CRS:84"_s, Qt::CaseInsensitive ) == 0 )
1164 crs = u
"EPSG:4326"_s;
1167 else if ( crs.isEmpty() )
1169 crs = u
"EPSG:4326"_s;
1203 auto dxf = std::make_unique<QgsDxfExport>();
1204 dxf->setExtent( mapExtent );
1205 dxf->setDestinationCrs( outputCRS );
1206 dxf->addLayers( dxfLayers );
1207 dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
1208 dxf->setSymbologyExport( mWmsParameters.dxfMode() );
1211 dxf->setSymbologyScale( mWmsParameters.dxfScale() );
1214 dxf->setForce2d( mWmsParameters.isForce2D() );
1216 if ( mWmsParameters.noMText() )
1219 if ( mWmsParameters.exportLinesWithZeroWidth() )
1224 dxf->setFlags( flags );
1232 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1233 ms.
setLayers( mContext.layersToRender() );
1235 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1239 if ( mWmsParameters.pdfExportMetadata() )
1250 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1251 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, u
"PDF"_s,
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1252 if ( mWmsParameters.pdfAppendGeoreference() )
1254 pdf->setSaveWorldFile(
true );
1262 if ( i < 0 || i > mapSettings.
outputSize().width() )
1269 if ( j < 0 || j > mapSettings.
outputSize().height() )
1286 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1292 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1293 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1294 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1295 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1297 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1301 if ( mWmsParameters.j().isEmpty() )
1314 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1317 std::unique_ptr<QgsWmsRestorer> restorer;
1318 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1322 bool mandatoryCrsParam =
true;
1323 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1325 mandatoryCrsParam =
false;
1331 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1335 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1347#ifdef HAVE_SERVER_PYTHON_PLUGINS
1348 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1351 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1356 ba = convertFeatureInfoToText( result );
1358 ba = convertFeatureInfoToHtml( result );
1360 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1362 ba = result.toByteArray();
1367 QImage *QgsRenderer::createImage(
const QSize &size )
const
1369 std::unique_ptr<QImage> image;
1377 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1382 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1387 if ( image->isNull() )
1389 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1392 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1393 image->setDotsPerMeterX( dpm );
1394 image->setDotsPerMeterY( dpm );
1396 return image.release();
1399 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1403 throw QgsException( u
"configureMapSettings: no paint device"_s );
1406 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1409 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1412 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1413 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1418 QString crs = mWmsParameters.crs();
1419 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1421 crs = QString(
"EPSG:4326" );
1424 else if ( crs.isEmpty() && !mandatoryCrsParam )
1426 crs = QString(
"EPSG:4326" );
1429 QgsCoordinateReferenceSystem outputCRS;
1436 QgsWmsParameter parameter;
1438 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1449 throw QgsBadRequestException( code, parameter );
1458 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1466 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1472 bool transparent = mWmsParameters.transparentAsBool();
1473 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1480 else if ( backgroundColor.isValid() )
1486 QgsExpressionContext context = mProject->createExpressionContext();
1503 if ( mContext.settings().logProfile() )
1513 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1514 if ( !timeString.isEmpty() )
1516 bool isValidTemporalRange {
true };
1519 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1530 catch (
const QgsServerApiBadRequestException &ex )
1532 isValidTemporalRange =
false;
1537 if ( isValidTemporalRange )
1546 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1552 QgsDistanceArea distanceArea = QgsDistanceArea();
1553 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1559 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1561 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1563 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1565 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1567 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1569 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1571 int featureCount = mWmsParameters.featureCountAsInt();
1572 if ( featureCount < 1 )
1577 int i = mWmsParameters.iAsInt();
1578 int j = mWmsParameters.jAsInt();
1579 if ( xyDefined && !ijDefined )
1581 i = mWmsParameters.xAsInt();
1582 j = mWmsParameters.yAsInt();
1584 int width = mWmsParameters.widthAsInt();
1585 int height = mWmsParameters.heightAsInt();
1586 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1588 i *= ( outputImage->width() /
static_cast<double>( width ) );
1589 j *= ( outputImage->height() /
static_cast<double>( height ) );
1593 std::unique_ptr<QgsRectangle> featuresRect;
1594 std::unique_ptr<QgsGeometry> filterGeom;
1595 std::unique_ptr<QgsPointXY> infoPoint;
1597 if ( i != -1 && j != -1 )
1599 infoPoint = std::make_unique<QgsPointXY>();
1600 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1602 else if ( filtersDefined )
1604 featuresRect = std::make_unique<QgsRectangle>();
1607 if ( filterGeomDefined )
1609 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1612 QDomDocument result;
1613 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1614 result.appendChild( header );
1616 QDomElement getFeatureInfoElement;
1620 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1621 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1622 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1623 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1624 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1625 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1626 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1627 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1628 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, u
"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://qgis.org/gml"_s );
1633 if ( featureInfoElemName.isEmpty() )
1635 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1638 if ( featureInfoElemNs.isEmpty() )
1640 getFeatureInfoElement = result.createElement( featureInfoElemName );
1644 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1648 if ( !featureInfoSchema.isEmpty() )
1650 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1651 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1654 result.appendChild( getFeatureInfoElement );
1664 for (
const QString &queryLayer : queryLayers )
1666 bool validLayer =
false;
1667 bool queryableLayer =
true;
1668 for ( QgsMapLayer *layer : std::as_const( layers ) )
1670 if ( queryLayer == mContext.layerNickname( *layer ) )
1674 if ( !queryableLayer )
1679 QDomElement layerElement;
1682 layerElement = getFeatureInfoElement;
1686 layerElement = result.createElement( u
"Layer"_s );
1687 QString layerName = queryLayer;
1690 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1691 if ( layerAliasIt != layerAliasMap.constEnd() )
1693 layerName = layerAliasIt.value();
1696 layerElement.setAttribute( u
"name"_s, layerName );
1697 const QString layerTitle = layer->serverProperties()->title();
1698 if ( !layerTitle.isEmpty() )
1700 layerElement.setAttribute( u
"title"_s, layerTitle );
1704 layerElement.setAttribute( u
"title"_s, layerName );
1706 getFeatureInfoElement.appendChild( layerElement );
1709 layerElement.setAttribute( u
"id"_s, layer->id() );
1715 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1718 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1724 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1740 layerElement = result.createElement( u
"gml:featureMember"_s );
1741 getFeatureInfoElement.appendChild( layerElement );
1743 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1747 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1755 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1759 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1762 param.mValue = queryLayer;
1765 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1768 param.mValue = queryLayer;
1770 bool hasGroupAndQueryable {
false };
1771 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1774 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1775 for (
const QString &ql : constNicks )
1777 if ( mContext.layerGroups().contains( ql ) )
1779 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1780 for (
const QgsMapLayer *ml : constLayers )
1782 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1788 hasGroupAndQueryable =
true;
1797 if ( !hasGroupAndQueryable )
1804 if ( featuresRect && !featuresRect->isNull() )
1808 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1809 QDomElement boxElem;
1810 int gmlVersion = mWmsParameters.infoFormatVersion();
1811 if ( gmlVersion < 3 )
1823 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1825 bBoxElem.appendChild( boxElem );
1826 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1830 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1832 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1833 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1834 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1835 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1836 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1842 convertFeatureInfoToSia2045( result );
1848 bool QgsRenderer::featureInfoFromVectorLayer(
1849 QgsVectorLayer *layer,
1850 const QgsPointXY *infoPoint,
1852 QDomDocument &infoDocument,
1853 QDomElement &layerElement,
1854 const QgsMapSettings &mapSettings,
1855 QgsRenderContext &renderContext,
1856 const QString &version,
1857 QgsRectangle *featureBBox,
1858 QgsGeometry *filterGeom
1866 QgsFeatureRequest fReq;
1869 std::unique_ptr<QgsGeometry> layerFilterGeom;
1872 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1877 QgsRectangle mapRect = mapSettings.
extent();
1881 QgsRectangle searchRect;
1886 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1888 else if ( layerFilterGeom )
1890 searchRect = layerFilterGeom->boundingBox();
1892 else if ( !mWmsParameters.bbox().isEmpty() )
1894 searchRect = layerRect;
1900 QgsAttributes featureAttributes;
1901 int featureCounter = 0;
1903 const QgsFields fields = layer->
fields();
1920 if ( layerFilterGeom )
1922 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1926 mFeatureFilter.filterFeatures( layer, fReq );
1929#ifdef HAVE_SERVER_PYTHON_PLUGINS
1931 mContext.accessControl()->filterFeatures( layer, fReq );
1934 QStringList attributes;
1935 for (
const QgsField &field : fields )
1937 attributes.append( field.name() );
1939 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1943 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1947 r2->startRender( renderContext, layer->
fields() );
1950 bool featureBBoxInitialized =
false;
1959 if ( featureCounter > nFeatures )
1974 bool render = r2->willRenderFeature( feature, renderContext );
1987 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1990 featureBBoxInitialized =
true;
1999 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
2008 int gmlVersion = mWmsParameters.infoFormatVersion();
2009 QString typeName = mContext.layerNickname( *layer );
2010 QDomElement elem = createFeatureGML(
2019#ifdef HAVE_SERVER_PYTHON_PLUGINS
2024 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2025 featureMemberElem.appendChild( elem );
2026 layerElement.appendChild( featureMemberElem );
2031 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2033 layerElement.appendChild( featureElement );
2039 writeAttributesTabLayout(
2047#ifdef HAVE_SERVER_PYTHON_PLUGINS
2055 for (
int i = 0; i < featureAttributes.count(); ++i )
2057 writeVectorLayerAttribute(
2065#ifdef HAVE_SERVER_PYTHON_PLUGINS
2077 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2078 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2082 featureElement.appendChild( maptipElem );
2086 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2088 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2089 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2092 displayExpression.
prepare( &context );
2093 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2094 featureElement.appendChild( displayElem );
2100 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2101 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2106 featureElement.appendChild( bBoxElem );
2112 QgsGeometry geom = feature.
geometry();
2115 if ( layer->
crs() != outputCrs )
2117 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2122 if ( segmentizeWktGeometry )
2124 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2129 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2130 geom.
set( segmentizedGeom );
2134 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2135 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2136 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2137 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2138 featureElement.appendChild( geometryElement );
2145 r2->stopRender( renderContext );
2151 void QgsRenderer::writeAttributesTabGroup(
2152 const QgsAttributeEditorElement *group,
2153 QgsVectorLayer *layer,
2154 const QgsFields &fields,
2155 QgsAttributes &featureAttributes,
2157 QDomElement &parentElem,
2158 QgsRenderContext &renderContext,
2159 QStringList *attributes
2162 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2165 QString groupName = container->
name();
2166 QDomElement nameElem;
2168 if ( !groupName.isEmpty() )
2170 nameElem = doc.createElement( groupName );
2171 parentElem.appendChild( nameElem );
2174 const QList<QgsAttributeEditorElement *> children = container->
children();
2175 for (
const QgsAttributeEditorElement *child : children )
2179 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2183 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2189 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2197 void QgsRenderer::writeAttributesTabLayout(
2198 QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2202 if ( !editorContainer )
2207 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2210 void QgsRenderer::writeVectorLayerAttribute(
2211 int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2214#ifndef HAVE_SERVER_PYTHON_PLUGINS
2215 Q_UNUSED( attributes );
2228#ifdef HAVE_SERVER_PYTHON_PLUGINS
2230 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2237 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2238 attributeElement.setAttribute( u
"name"_s, attributeName );
2241 featureElem.appendChild( attributeElement );
2244 bool QgsRenderer::featureInfoFromMeshLayer(
2245 QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2249 Q_UNUSED( mapSettings )
2258 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2260 QList<QgsMeshDatasetIndex> datasetIndexList;
2269 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2271 if ( activeScalarGroup >= 0 )
2273 QgsMeshDatasetIndex indice;
2275 datasetIndexList.append( indice );
2278 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2281 for (
int groupIndex : allGroup )
2283 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2289 if ( activeScalarGroup >= 0 )
2291 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2294 for (
int groupIndex : allGroup )
2296 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2299 datasetIndexList.append( groupIndex );
2306 double scalarDoubleValue = 0.0;
2308 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2310 if ( !index.isValid() )
2314 QMap<QString, QString> derivedAttributes;
2316 QMap<QString, QString> attribute;
2320 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2321 scalarDoubleValue = scalarValue.
scalar();
2322 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2327 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2328 const double vectorX = vectorValue.
x();
2329 const double vectorY = vectorValue.
y();
2330 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2332 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2336 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2337 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2338 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2345 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2346 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2348 const QString resultName = groupMeta.
name();
2350 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2351 attributeElement.setAttribute( u
"name"_s, resultName );
2356 value = QString::number( scalarDoubleValue );
2359 attributeElement.setAttribute( u
"value"_s, value );
2360 layerElement.appendChild( attributeElement );
2364 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2365 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2368 value = range.
begin().toString( dateFormat );
2372 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2374 attributeElementTime.setAttribute( u
"value"_s, value );
2375 layerElement.appendChild( attributeElementTime );
2381 bool QgsRenderer::featureInfoFromRasterLayer(
2382 QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2403 QgsRasterIdentifyResult identifyResult;
2406 const QgsRectangle extent { mapSettings.
extent() };
2410 throw QgsBadRequestException(
2421 if ( !identifyResult.
isValid() )
2424 QMap<int, QVariant> attributes = identifyResult.
results();
2430 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2431 int gmlVersion = mWmsParameters.infoFormatVersion();
2432 QString typeName = mContext.layerNickname( *layer );
2438 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2440 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2441 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2444 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2445 layerElement.appendChild( elem );
2449 const auto values = identifyResult.
results();
2450 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2452 QVariant value = it.value();
2453 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2459 if ( value.userType() == QMetaType::Type::QString )
2467 for (
const QgsFeatureStore &featureStore : featureStoreList )
2470 for (
const QgsFeature &feature : storeFeatures )
2472 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2473 layerElement.appendChild( elem );
2483 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2485 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2486 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2491 value = QString::number( it.value().toDouble() );
2494 attributeElement.setAttribute( u
"value"_s, value );
2495 layerElement.appendChild( attributeElement );
2500 const auto values = identifyResult.
results();
2501 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2503 QVariant value = it.value();
2504 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2510 if ( value.userType() == QMetaType::Type::QString )
2517 for (
const QgsFeatureStore &featureStore : featureStoreList )
2520 for (
const QgsFeature &feature : storeFeatures )
2522 for (
const auto &fld : feature.
fields() )
2524 const auto val { feature.
attribute( fld.name() ) };
2525 if ( val.isValid() )
2527 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2528 attributeElement.setAttribute( u
"name"_s, fld.name() );
2529 attributeElement.setAttribute( u
"value"_s, val.toString() );
2530 layerElement.appendChild( attributeElement );
2541 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2542 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2545 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2548 layerElement.appendChild( maptipElem );
2554 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2557 if ( filter.contains(
";"_L1 ) )
2562 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2563 groupStringList( tokens, u
"'"_s );
2564 groupStringList( tokens, u
"\""_s );
2566 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2569 if ( tokenIt->compare(
','_L1 ) == 0
2570 || tokenIt->compare(
'('_L1 ) == 0
2571 || tokenIt->compare(
')'_L1 ) == 0
2572 || tokenIt->compare(
'='_L1 ) == 0
2573 || tokenIt->compare(
"!="_L1 ) == 0
2574 || tokenIt->compare(
'<'_L1 ) == 0
2575 || tokenIt->compare(
"<="_L1 ) == 0
2576 || tokenIt->compare(
'>'_L1 ) == 0
2577 || tokenIt->compare(
">="_L1 ) == 0
2578 || tokenIt->compare(
'%'_L1 ) == 0
2579 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2580 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2581 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2582 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2583 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2584 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2585 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2586 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2587 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2588 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2589 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2596 ( void ) tokenIt->toDouble( &isNumeric );
2605 if ( *tokenIt ==
"''"_L1 )
2611 if ( tokenIt->size() > 2
2612 && ( *tokenIt )[0] == QChar(
'\'' )
2613 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2614 && ( *tokenIt )[1] != QChar(
'\'' )
2615 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2621 if ( tokenIt->size() > 2 && ( *tokenIt )[0] == QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' ) && ( *tokenIt )[1] != QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2632 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2635 bool groupActive =
false;
2636 int startGroup = -1;
2637 QString concatString;
2639 for (
int i = 0; i < list.size(); ++i )
2641 QString &str = list[i];
2642 if ( str.startsWith( groupString ) )
2646 concatString.clear();
2651 if ( i != startGroup )
2653 concatString.append(
" " );
2655 concatString.append( str );
2658 if ( str.endsWith( groupString ) )
2661 groupActive =
false;
2663 if ( startGroup != -1 )
2665 list[startGroup] = concatString;
2666 for (
int j = startGroup + 1; j <= endGroup; ++j )
2668 list.removeAt( startGroup + 1 );
2673 concatString.clear();
2679 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2681 QDomDocument SIAInfoDoc;
2682 QDomElement infoDocElement = doc.documentElement();
2683 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2684 SIAInfoDoc.appendChild( SIAInfoDocElement );
2686 QString currentAttributeName;
2687 QString currentAttributeValue;
2688 QDomElement currentAttributeElem;
2689 QString currentLayerName;
2690 QDomElement currentLayerElem;
2691 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2692 for (
int i = 0; i < layerNodeList.size(); ++i )
2694 currentLayerElem = layerNodeList.at( i ).toElement();
2695 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2697 QDomElement currentFeatureElem;
2699 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2700 if ( featureList.isEmpty() )
2703 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2704 QDomElement rasterLayerElem;
2705 if ( !attributeList.isEmpty() )
2707 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2709 for (
int j = 0; j < attributeList.size(); ++j )
2711 currentAttributeElem = attributeList.at( j ).toElement();
2712 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2713 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2714 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2715 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2716 outAttributeElem.appendChild( outAttributeText );
2717 rasterLayerElem.appendChild( outAttributeElem );
2719 if ( !attributeList.isEmpty() )
2721 SIAInfoDocElement.appendChild( rasterLayerElem );
2727 QSet<QString> layerPropertyAttributes;
2728 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2729 if ( !currentLayerId.isEmpty() )
2731 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2734 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2735 if ( !WMSPropertyAttributesString.isEmpty() )
2737 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2738 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2740 layerPropertyAttributes.insert( *propertyIt );
2746 QDomElement propertyRefChild;
2747 for (
int j = 0; j < featureList.size(); ++j )
2749 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2750 currentFeatureElem = featureList.at( j ).toElement();
2751 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2753 for (
int k = 0; k < attributeList.size(); ++k )
2755 currentAttributeElem = attributeList.at( k ).toElement();
2756 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2757 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2758 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2760 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2761 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2762 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2763 identifierElem.appendChild( identifierText );
2764 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2765 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2766 valueElem.appendChild( valueText );
2767 propertyElem.appendChild( identifierElem );
2768 propertyElem.appendChild( valueElem );
2769 if ( propertyRefChild.isNull() )
2771 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2772 propertyRefChild = propertyElem;
2776 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2781 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2782 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2783 SIAAttributeElem.appendChild( SIAAttributeText );
2784 SIAFeatureElem.appendChild( SIAAttributeElem );
2787 SIAInfoDocElement.appendChild( SIAFeatureElem );
2794 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2797 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2800 featureInfoString.append( QStringLiteral( R
"HTML(
2803 <title>Information</title>
2804 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2807 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2814 border: 1px solid black;
2815 border-collapse: collapse;
2836 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2839 for (
int i = 0; i < layerList.size(); ++i )
2841 const QDomElement layerElem = layerList.at( i ).toElement();
2844 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2845 const QDomElement currentFeatureElement;
2847 if ( !featureNodeList.isEmpty() )
2851 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2852 featureInfoString.append( featureInfoLayerTitleString );
2855 for (
int j = 0; j < featureNodeList.size(); ++j )
2857 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2860 featureInfoString.append( QStringLiteral( R
"HTML(
2865 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2866 for (
int k = 0; k < attributeNodeList.size(); ++k )
2868 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2869 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2870 QString value = attributeElement.attribute( u
"value"_s );
2871 if ( name !=
"maptip"_L1 )
2873 value = value.toHtmlEscaped();
2878 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2883 .arg( name, value );
2885 featureInfoString.append( featureInfoAttributeString );
2887 else if ( name ==
"maptip"_L1 )
2889 featureInfoString.append( QStringLiteral( R
"HTML(
2897 featureInfoString.append( QStringLiteral( R
"HTML(
2904 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2907 if ( !attributeNodeList.isEmpty() )
2911 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2912 featureInfoString.append( featureInfoLayerTitleString );
2914 featureInfoString.append( QStringLiteral( R
"HTML(
2918 for (
int j = 0; j < attributeNodeList.size(); ++j )
2920 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2921 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2922 QString value = attributeElement.attribute( u
"value"_s );
2923 if ( value.isEmpty() )
2925 value = u
"no data"_s;
2927 if ( name !=
"maptip"_L1 )
2929 value = value.toHtmlEscaped();
2934 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2939 .arg( name, value );
2942 featureInfoString.append( featureInfoAttributeString );
2944 else if ( name ==
"maptip"_L1 )
2946 featureInfoString.append( QStringLiteral( R
"HTML(
2954 featureInfoString.append( QStringLiteral( R
"HTML(
2964 featureInfoString.append( QStringLiteral( R
"HTML(
2968 return featureInfoString.toUtf8();
2971 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2973 QString featureInfoString;
2976 featureInfoString.append(
"GetFeatureInfo results\n" );
2977 featureInfoString.append(
"\n" );
2979 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2982 for (
int i = 0; i < layerList.size(); ++i )
2984 QDomElement layerElem = layerList.at( i ).toElement();
2986 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2989 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2990 QDomElement currentFeatureElement;
2992 if ( !featureNodeList.isEmpty() )
2994 for (
int j = 0; j < featureNodeList.size(); ++j )
2996 QDomElement featureElement = featureNodeList.at( j ).toElement();
2997 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
3000 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
3001 for (
int k = 0; k < attributeNodeList.size(); ++k )
3003 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
3004 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
3010 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
3011 for (
int j = 0; j < attributeNodeList.size(); ++j )
3013 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
3014 QString value = attributeElement.attribute( u
"value"_s );
3015 if ( value.isEmpty() )
3017 value = u
"no data"_s;
3019 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
3023 featureInfoString.append(
"\n" );
3026 return featureInfoString.toUtf8();
3029 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
3032 {
"type",
"FeatureCollection" },
3033 {
"features", json::array() },
3036 const bool withDisplayName = mWmsParameters.withDisplayName();
3038 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
3039 for (
int i = 0; i < layerList.size(); ++i )
3041 const QDomElement layerElem = layerList.at( i ).toElement();
3042 const QString layerName = layerElem.attribute( u
"name"_s );
3044 QgsMapLayer *layer =
nullptr;
3045 for ( QgsMapLayer *l : layers )
3047 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3058 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3063 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3064 if ( featuresNode.isEmpty() )
3067 QMap<QgsFeatureId, QString> fidMap;
3068 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3070 for (
int j = 0; j < featuresNode.size(); ++j )
3072 const QDomElement featureNode = featuresNode.at( j ).toElement();
3073 const QString fid = featureNode.attribute( u
"id"_s );
3076 if ( expression.isEmpty() )
3078 feature = vl->
getFeature( fid.toLongLong() );
3082 QgsFeatureRequest request { QgsExpression( expression ) };
3087 fidMap.insert( feature.
id(), fid );
3092 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3093 for (
int k = 0; k < attrs.count(); k++ )
3095 const QDomElement elm = attrs.at( k ).toElement();
3096 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3098 wkt = elm.attribute(
"value" );
3103 if ( !wkt.isEmpty() )
3111 if ( withDisplayName )
3113 QString displayName;
3114 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3115 for (
int k = 0; k < attrs.count(); k++ )
3117 const QDomElement elm = attrs.at( k ).toElement();
3118 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3120 displayName = elm.attribute(
"value" );
3124 fidDisplayNameMap.insert( feature.
id(), displayName );
3127 features << feature;
3130 if ( !attributes.isEmpty() )
3133 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3134 for (
int k = 0; k < attributesNode.size(); ++k )
3136 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3137 const QString fieldName = attributeElement.attribute( u
"name"_s );
3138 attributes << feature.fieldNameIndex( fieldName );
3143 QgsJsonExporter exporter( vl );
3144 exporter.setAttributeDisplayName(
true );
3145 exporter.setAttributes( attributes );
3146 exporter.setIncludeGeometry( withGeometry );
3147 exporter.setTransformGeometries(
false );
3151 for (
const auto &feature : std::as_const( features ) )
3153 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3154 QVariantMap extraProperties;
3155 if ( withDisplayName )
3157 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3159 json[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id ) );
3164 auto properties = json::object();
3165 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3166 for (
int j = 0; j < attributesNode.size(); ++j )
3168 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3169 const QString name = attrElmt.attribute( u
"name"_s );
3171 QString value = attrElmt.attribute( u
"value"_s );
3172 if ( value.isEmpty() )
3177 properties[name.toStdString()] = value.toStdString();
3180 json[
"features"].push_back( { {
"type",
"Feature" }, {
"id", layerName.toStdString() }, {
"properties", properties } } );
3185 return QByteArray::fromStdString( json.dump( 2 ) );
3187 return QByteArray::fromStdString( json.dump() );
3191 QDomElement QgsRenderer::createFeatureGML(
3192 const QgsFeature *feat, QgsVectorLayer *layer, QDomDocument &doc, QgsCoordinateReferenceSystem &crs,
const QgsMapSettings &mapSettings,
const QString &typeName,
bool withGeom,
int version, QStringList *attributes
3196 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3203 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3205 QgsCoordinateTransform transform;
3206 if ( layer && layer->
crs() != crs )
3211 QgsGeometry geom = feat->
geometry();
3213 QgsExpressionContext expressionContext;
3219 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3233 catch ( QgsCsException &e )
3239 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3240 QDomElement boxElem;
3252 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3254 bbElem.appendChild( boxElem );
3255 typeNameElement.appendChild( bbElem );
3259 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3260 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3261 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3264 const QList<QgsAttributeEditorElement *> children = container->
children();
3265 for (
const QgsAttributeEditorElement *child : children )
3267 switch ( child->type() )
3271 if ( findAttributeInTree( attributeName, child ) )
3279 if ( child->name() == attributeName )
3287 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3288 if ( relationEditor )
3290 const QgsRelation &relation { relationEditor->
relation() };
3294 for (
const auto &idx : std::as_const( referencedFields ) )
3296 const QgsField f { layer->
fields().
at( idx ) };
3297 if ( f.
name() == attributeName )
3306 for (
const auto &idx : std::as_const( referencingFields ) )
3308 const QgsField f { layer->
fields().
at( idx ) };
3309 if ( f.
name() == attributeName )
3326 if ( withGeom && !geom.
isNull() )
3335 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3336 QDomElement gmlElem;
3346 if ( !gmlElem.isNull() )
3350 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3352 geomElem.appendChild( gmlElem );
3353 typeNameElement.appendChild( geomElem );
3358 QgsAttributes featureAttributes = feat->
attributes();
3359 QgsFields fields = feat->
fields();
3360 for (
int i = 0; i < fields.
count(); ++i )
3362 QString attributeName = fields.
at( i ).
name();
3369 if ( attributes && !attributes->contains( attributeName ) )
3374 if ( honorFormConfig )
3377 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3383 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3384 QString fieldTextString = featureAttributes.at( i ).toString();
3389 QDomText fieldText = doc.createTextNode( fieldTextString );
3390 fieldElem.appendChild( fieldText );
3391 typeNameElement.appendChild( fieldElem );
3402 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3403 QDomText maptipText = doc.createTextNode( fieldTextString );
3404 fieldElem.appendChild( maptipText );
3405 typeNameElement.appendChild( fieldElem );
3409 return typeNameElement;
3412 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3416 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3418 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3420 value = value.mid( 1, value.size() - 2 );
3425 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3429 return QgsRectangle();
3432 double mapUnitTolerance = 0.0;
3435 if ( !mWmsParameters.polygonTolerance().isEmpty() && mWmsParameters.polygonToleranceAsInt() > 0 )
3441 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3446 if ( !mWmsParameters.lineTolerance().isEmpty() && mWmsParameters.lineToleranceAsInt() > 0 )
3452 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3457 if ( !mWmsParameters.pointTolerance().isEmpty() && mWmsParameters.pointToleranceAsInt() > 0 )
3463 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3470 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3474 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3476 QList<QgsMapLayer *> highlightLayers;
3479 QString crs = mWmsParameters.crs();
3480 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3483 QDomDocument sldDoc;
3487 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3494 std::unique_ptr<QgsFeatureRenderer> renderer;
3495 QDomElement el = sldDoc.documentElement();
3505 QString url = typeName +
"?crs=" + crs;
3506 if ( !param.mLabel.isEmpty() )
3508 url +=
"&field=label:string";
3513 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3520 QgsFeature fet( layer->
fields() );
3521 if ( !param.mLabel.isEmpty() )
3523 fet.setAttribute( 0, param.mLabel );
3526 QgsPalLayerSettings palSettings;
3531 palSettings.
dist = param.mLabelDistance;
3540 switch ( param.mGeom.type() )
3551 QgsPointXY pt = param.mGeom.asPoint();
3553 QVariant x( pt.
x() );
3556 QVariant y( pt.
y() );
3568 QgsGeometry point = param.mGeom.pointOnSurface();
3569 QgsPointXY pt = point.
asPoint();
3573 QVariant x( pt.
x() );
3577 QVariant y( pt.
y() );
3581 QVariant hali(
"Center" );
3585 QVariant vali(
"Half" );
3597 QgsTextFormat textFormat;
3598 QgsTextBufferSettings bufferSettings;
3600 if ( param.mColor.isValid() )
3602 textFormat.
setColor( param.mColor );
3605 if ( param.mSize > 0 )
3607 textFormat.
setSize( param.mSize );
3615 if ( !param.mFont.isEmpty() )
3617 textFormat.
setFont( param.mFont );
3620 if ( param.mBufferColor.isValid() )
3622 bufferSettings.
setColor( param.mBufferColor );
3625 if ( param.mBufferSize > 0 )
3628 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3634 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3638 fet.setGeometry( param.mGeom );
3647 highlightLayers.append( layer.release() );
3651 mTemporaryLayers.append( highlightLayers );
3652 return highlightLayers;
3655 void QgsRenderer::removeTemporaryLayers()
3657 qDeleteAll( mTemporaryLayers );
3658 mTemporaryLayers.clear();
3661 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3663 QPainter *painter =
nullptr;
3665 QgsFeatureFilterProviderGroup filters;
3667#ifdef HAVE_SERVER_PYTHON_PLUGINS
3668 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3671 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3673 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3674 painter = renderJob.takePainter();
3676 logRenderingErrors( renderJob.errors() );
3678 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3680 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3682 QString layerWMSName;
3683 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3686 layerWMSName = mContext.layerNickname( *errorLayer );
3689 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3690 if ( !layerWMSName.isEmpty() )
3692 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3694 throw QgsException( errorMessage );
3700 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3702 if ( opacity >= 0 && opacity <= 255 )
3704 switch ( layer->
type() )
3708 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3713 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3721 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3722 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3723 rasterRenderer->
setOpacity( opacity / 255. );
3729 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3745 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3749 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3750 QStringList expList;
3751 for (
const QgsWmsParametersFilter &filter : filters )
3756 QDomDocument filterXml;
3758 QXmlStreamReader xmlReader( filter.mFilter );
3759 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3760 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3761 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3763 throw QgsBadRequestException(
3765 u
"Filter string rejected. Error %1:%2 : %3. The XML string was: %4"_s.arg( QString::number( result.errorLine ), QString::number( result.errorColumn ), result.errorMessage, filter.mFilter )
3769 QDomElement filterElem = filterXml.firstChildElement();
3774 expList << filterExp->dump();
3780 if ( !testFilterStringSafety( filter.mFilter ) )
3782 throw QgsSecurityException(
3784 "The filter string %1"
3785 " has been rejected because of security reasons."
3786 " Note: Text strings have to be enclosed in single or double quotes."
3787 " A space between each word / special character is mandatory."
3788 " Allowed Keywords and special characters are"
3789 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3790 " Not allowed are semicolons in the filter expression."
3792 .arg( filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' ) )
3796 QString newSubsetString = filter.mFilter;
3799 newSubsetString.prepend(
") AND (" );
3800 newSubsetString.append(
")" );
3801 newSubsetString.prepend( filteredLayer->
subsetString() );
3802 newSubsetString.prepend(
"(" );
3812 expList.append( dimensionFilter( filteredLayer ) );
3816 if ( expList.size() == 1 )
3820 else if ( expList.size() > 1 )
3822 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3824 if ( !exp.isEmpty() )
3826 auto expression = std::make_unique<QgsExpression>( exp );
3830 mFeatureFilter.setFilter( filteredLayer, *expression );
3837 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3839 QStringList expList;
3841 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3842 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3843 if ( wmsDims.isEmpty() )
3848 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3849 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3858 if ( fieldIndex == -1 )
3863 int endFieldIndex = -1;
3864 if ( !dim.endFieldName.isEmpty() )
3866 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3867 if ( endFieldIndex == -1 )
3873 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3877 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::AllValues )
3881 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
3883 defValue = dim.referenceValue;
3888 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3889 if ( endFieldIndex != -1 )
3891 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3894 QList<QVariant> values = qgis::setToList( uniqueValues );
3895 std::sort( values.begin(), values.end() );
3896 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
3898 defValue = values.first();
3900 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
3902 defValue = values.last();
3906 if ( endFieldIndex == -1 )
3912 QStringList expElems;
3921 expList << expElems.join(
' ' );
3927 QgsField dimField = layer->
fields().
at( fieldIndex );
3929 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3931 QStringList dimExplist;
3933 QStringList dimValues = dimParamValue.split(
',' );
3934 for (
int i = 0; i < dimValues.size(); ++i )
3936 QString dimValue = dimValues[i];
3938 if ( dimValue.size() > 1 )
3940 dimValue = dimValue.trimmed();
3943 if ( dimValue.contains(
'/' ) )
3945 QStringList rangeValues = dimValue.split(
'/' );
3947 if ( rangeValues.size() != 2 )
3952 QVariant rangeMin = QVariant( rangeValues[0] );
3953 QVariant rangeMax = QVariant( rangeValues[1] );
3964 QStringList expElems;
3965 if ( endFieldIndex == -1 )
4000 dimExplist << expElems.join(
' ' );
4004 QVariant dimVariant = QVariant( dimValue );
4010 if ( endFieldIndex == -1 )
4019 QStringList expElems;
4028 dimExplist << expElems.join(
' ' );
4033 if ( dimExplist.size() == 1 )
4035 expList << dimExplist;
4037 else if ( dimExplist.size() > 1 )
4039 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
4046 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4050 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4052 QgsFeatureRequest request;
4056 if ( selectedIds.empty() )
4067 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4069#ifdef HAVE_SERVER_PYTHON_PLUGINS
4076 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4079 QgsRectangle mapExtent = mapSettings.
extent();
4087 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4089 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4090 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4094 renderContext.
setFeedback( mContext.socketFeedback() );
4096 for ( QgsAnnotation *annotation : annotations )
4098 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4100 if ( !annotation || !annotation->isVisible() )
4106 if ( annotation->hasFixedMapPosition() )
4108 QgsPointXY mapPos = annotation->mapPosition();
4109 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4114 mapPos = coordTransform.transform( mapPos );
4116 catch (
const QgsCsException &e )
4122 offsetX = devicePos.
x();
4123 offsetY = devicePos.
y();
4127 const QPointF relativePos = annotation->relativePosition();
4128 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4129 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4133 painter->translate( offsetX, offsetY );
4134 annotation->render( renderContext );
4139 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4144 QImage *scaledImage =
nullptr;
4145 const int width = mWmsParameters.widthAsInt();
4146 const int height = mWmsParameters.heightAsInt();
4147 if ( width != image->width() || height != image->height() )
4149 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4157 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4158 for ( ; it != errors.constEnd(); ++it )
4160 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4161 if ( !it->layerID.isEmpty() )
4163 msg += QString(
" in layer %1" ).arg( it->layerID );
4169 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4176 QList<QgsLayoutItemMap *> mapList;
4180 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4181 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4183 logRenderingErrors( ( *mapIt )->renderingErrors() );
4186 if ( mContext.settings().ignoreRenderingErrors() )
4191 mapIt = mapList.constBegin();
4192 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4194 if ( !( *mapIt )->renderingErrors().isEmpty() )
4196 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4197 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4204 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4206 for (
auto layer : layers )
4208 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4210 if ( !mContext.layersToRender().contains( layer ) )
4215 if ( mContext.isExternalLayer( param.mNickname ) )
4219 setLayerOpacity( layer, param.mOpacity );
4226 setLayerSld( layer, mContext.sld( *layer ) );
4230 setLayerStyle( layer, mContext.style( *layer ) );
4235 setLayerOpacity( layer, param.mOpacity );
4240 setLayerFilter( layer, param.mFilter );
4245 setLayerAccessControlFilter( layer );
4250 setLayerSelection( layer, param.mSelection );
4253 if ( settings && mContext.updateExtent() )
4255 updateExtent( layer, *settings );
4261 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4265 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4267 if ( style.isEmpty() )
4279 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4284 QString sldStyleName =
"__sld_style";
4285 while ( styles.contains( sldStyleName ) )
4287 sldStyleName.append(
'@' );
4295 QgsLegendSettings QgsRenderer::legendSettings()
4298 QgsLegendSettings settings = mWmsParameters.legendSettings();
4300 if ( !mWmsParameters.bbox().isEmpty() )
4302 QgsMapSettings mapSettings;
4304 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4305 configureMapSettings( tmp.get(), mapSettings );
static QString version()
Version string.
@ MapOrientation
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
@ AboveLine
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
@ Millimeters
Millimeters.
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ VisibleLayers
Synchronize to map layers. The legend will include layers which are included in the linked map only.
@ AllProjectLayers
Synchronize to all project layers.
@ Manual
No automatic synchronization of legend layers. The legend will be manually populated.
@ DragAndDrop
"Drag and drop" layout. Needs to be configured.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ NoFlags
No flags are set.
@ Warning
Warning message.
@ Critical
Critical/error message.
@ Info
Information message.
QFlags< LabelLinePlacementFlag > LabelLinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
@ ShowRuleDetails
If set, the rule expression of a rule based renderer legend item will be added to the JSON.
@ IdentifyValue
Numerical values.
@ IdentifyFeature
WMS GML -> feature.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Use antialiasing while drawing.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
static const double DEFAULT_SEARCH_RADIUS_MM
Identify search radius in mm.
QFlags< LegendJsonRenderFlag > LegendJsonRenderFlags
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
RasterIdentifyFormat
Raster identify formats.
@ Feature
WMS GML/JSON -> feature.
@ Value
Numerical pixel value.
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
@ AllowOverlapIfRequired
Avoids overlapping labels when possible, but permit overlaps if labels for features cannot otherwise ...
@ Reverse
Reverse/inverse transform (from destination to source).
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ RecordProfile
Enable run-time profiling while rendering.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ DisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ DrawSelection
Draw selection.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
QList< QgsAnnotation * > annotations() const
Returns a list of all annotations contained in the manager.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QString name() const
Returns the name of this element.
const QgsRelation & relation() const
Gets the id of the relation which shall be embedded.
Exception thrown in case of malformed requests.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Qgis::DistanceUnit mapUnits
bool hasAxisInverted() const
Returns whether the axis order is inverted for the CRS compared to the order east/north (longitude/la...
A server filter to apply a dimension filter to a request.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
@ FlagHairlineWidthExport
@ FlagNoMText
Export text as TEXT elements. If not set, text will be exported as MTEXT elements.
Defines a QGIS exception class.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
QString expression() const
Returns the original, unmodified expression string.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
QVariant evaluate()
Evaluate the feature and return the result.
bool isValid() const
Checks if this expression is valid.
A filter filter provider grouping several filter providers.
QgsFeatureFilterProviderGroup & addProvider(const QgsFeatureFilterProvider *provider)
Add another filter provider to the group.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
static QgsFeatureRenderer * loadSld(const QDomNode &node, Qgis::GeometryType geomType, QString &errorMessage)
Create a new renderer according to the information contained in the UserStyle element of a SLD style ...
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
Qgis::FeatureRequestFlags flags() const
Returns the flags which affect how features are fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Qgis::FieldConfigurationFlags configurationFlags
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
static void addCrsInfo(json &value, const QgsCoordinateReferenceSystem &crs)
Add crs information entry in json object regarding old GeoJSON specification format if it differs fro...
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
void removeChildrenGroupWithoutLayers()
Remove all child group nodes without layers.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
@ RuleKey
Rule key of the node (QString).
virtual QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const
Draws symbol on the left side of the item.
A model representing the layer tree, including layers and groups of layers.
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
QgsLayerTreeModelLegendNode * findLegendNode(const QString &layerId, const QString &ruleKey) const
Searches through the layer tree to find a legend node with a matching layer ID and rule key.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
bool beginRender() override
Called when rendering begins, before iteration commences.
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
bool first()
Seeks to the first feature, returning false if no feature was found.
QgsLayout * layout() override
Returns the layout associated with the iterator.
bool enabled() const
Returns whether the atlas generation is enabled.
int count() const override
Returns the number of features to iterate over.
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
Handles rendering and exports of layouts to various formats.
ExportResult exportToSvg(const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings)
Exports the layout as an SVG to the filePath, using the specified export settings.
ExportResult exportToImage(const QString &filePath, const QgsLayoutExporter::ImageExportSettings &settings)
Exports the layout to the filePath, using the specified export settings.
ExportResult exportToPdf(const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings)
Exports the layout as a PDF to the filePath, using the specified export settings.
@ ManualHtml
HTML content is manually set for the item.
@ Url
Using this mode item fetches its content via a url.
Layout graphical items for displaying a map.
double scale() const
Returns the map scale.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
QString id() const
Returns the item's ID name.
Manages storage of a set of layouts.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
double length() const
Returns the length of the measurement.
int pageCount() const
Returns the number of pages in the collection.
Stores information relating to the current rendering settings for a layout.
void setFeatureFilterProvider(QgsFeatureFilterProvider *featureFilterProvider)
Sets feature filter provider to featureFilterProvider.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
static QVector< double > predefinedScales(const QgsLayout *layout)
Returns a list of predefined scales associated with a layout.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Handles automatic layout and rendering of legends.
QSizeF minimumSize(QgsRenderContext *renderContext=nullptr)
Runs the layout algorithm and returns the minimum size required for the legend.
QJsonObject exportLegendToJson(const QgsRenderContext &context)
Renders the legend in a json object.
Q_DECL_DEPRECATED void drawLegend(QPainter *painter)
Draws the legend with given painter.
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
Q_DECL_DEPRECATED void setMapScale(double scale)
Sets the legend map scale.
Q_DECL_DEPRECATED void setMapUnitsPerPixel(double mapUnitsPerPixel)
Sets the mmPerMapUnit calculated by mapUnitsPerPixel mostly taken from the map settings.
void setJsonRenderFlags(const Qgis::LegendJsonRenderFlags &jsonRenderFlags)
Sets the JSON export flags to jsonRenderFlags.
void setWmsLegendSize(QSizeF s)
Sets the desired size (in millimeters) of WMS legend graphics shown in the legend.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual bool readSld(const QDomNode &node, QString &errorMessage)
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QList< QgsMapRendererJob::Error > Errors
Contains configuration for rendering maps.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setSelectiveMaskingSourceSets(const QVector< QgsSelectiveMaskingSourceSet > &sets)
Sets a list of all selective masking source sets defined for the map.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QColor selectionColor() const
Returns the color that is used for drawing of selected vector features.
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QList< QgsMapThemeCollection::MapThemeLayerRecord > layerRecords() const
Returns a list of records for all visible layer belonging to the theme.
QgsMapThemeCollection::MapThemeRecord mapThemeState(const QString &name) const
Returns the recorded state of a map theme.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
void updateTriangularMesh(const QgsCoordinateTransform &transform=QgsCoordinateTransform())
Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh.
QgsMeshDatasetIndex staticVectorDatasetIndex(int group=-1) const
Returns the static vector dataset index that is rendered if the temporal properties is not active.
QList< int > enabledDatasetGroupsIndexes() const
Returns the list of indexes of enables dataset groups handled by the layer.
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset metadata.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetIndex datasetIndexAtTime(const QgsDateTimeRange &timeRange, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the time range.
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsMeshDatasetIndex activeScalarDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active scalar group depending on the time range.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshDatasetIndex staticScalarDatasetIndex(int group=-1) const
Returns the static scalar dataset index that is rendered if the temporal properties is not active.
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
static QDomElement rectangleToGMLEnvelope(const QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static QDomElement geometryToGML(const QgsGeometry &geometry, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
static QDomElement rectangleToGMLBox(const QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
Qgis::LabelPlacement placement
Label placement mode.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
int priority
Label priority.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
double dist
Distance from feature to the label.
Property
Data definable properties.
@ PositionX
X-coordinate data defined label position.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top).
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right).
QString fieldName
Name of field (or an expression) to use for label text.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsPrintLayout * clone() const override
Creates a clone of the layout.
Describes the version of a project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsMapThemeCollection * mapThemeCollection
QgsProjectMetadata metadata
QgsCoordinateTransformContext transformContext
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, Qgis::RasterIdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
bool isValid() const
Returns true if valid.
QMap< int, QVariant > results() const
Returns the identify results.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QString bandName(int bandNoInt) const
Returns the name of a band given its number.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
QList< int > referencedFields
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QList< int > referencingFields
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setDistanceArea(const QgsDistanceArea &distanceArea)
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly during rendering to check if rendering should ...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
Scoped object for temporary scaling of a QgsRenderContext for millimeter based rendering.
static QgsDateTimeRange parseTemporalDateTimeInterval(const QString &interval)
Parses a datetime interval and returns a QgsDateTimeRange.
Exception base class for server exceptions.
static QString getExpressionFromServerFid(const QString &serverFid, const QgsVectorDataProvider *provider)
Returns the expression feature id based on primary keys.
static QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
static QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
static QString wmsFeatureInfoSchema(const QgsProject &project)
Returns the schema URL for XML GetFeatureInfo request.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static bool wmsHTMLFeatureInfoUseOnlyMaptip(const QgsProject &project)
Returns if only the maptip should be used for HTML feature info response so that the HTML response to...
static QString wmsFeatureInfoDocumentElementNs(const QgsProject &project)
Returns the document element namespace for XML GetFeatureInfo request.
static QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
static bool wmsFeatureInfoSegmentizeWktGeometry(const QgsProject &project)
Returns if the geometry has to be segmentize in GetFeatureInfo request.
static bool wmsFeatureInfoUseAttributeFormSettings(const QgsProject &project)
Returns if feature form settings should be considered for the format of the feature info response.
static QHash< QString, QString > wmsFeatureInfoLayerAliasMap(const QgsProject &project)
Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
static bool wmsFeatureInfoAddWktGeometry(const QgsProject &project)
Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
static double wmsDefaultMapUnitsPerMm(const QgsProject &project)
Returns the default number of map units per millimeters in case of the scale is not given.
static QString wmsFeatureInfoDocumentElement(const QgsProject &project)
Returns the document element name for XML GetFeatureInfo request.
static int wmsMaxAtlasFeatures(const QgsProject &project)
Returns the maximum number of atlas features which can be printed in a request.
const QList< QgsServerWmsDimensionProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
@ Hidden
Hide task from GUI.
bool isActive() const
Returns true if the temporal property is active.
void setIsActive(bool active)
Sets whether the temporal property is active.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
bool isInstant() const
Returns true if the range consists only of a single instant.
void setColor(const QColor &color)
Sets the color for the buffer.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
void setSize(double size)
Sets the size of the buffer.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Represents a vector layer which manages a vector based dataset.
void setLabeling(QgsAbstractVectorLayerLabeling *labeling)
Sets labeling configuration.
Q_INVOKABLE QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider,...
void setLabelsEnabled(bool enabled)
Sets whether labels should be enabled for the layer.
Q_INVOKABLE void selectByExpression(const QString &expression, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, QgsExpressionContext *context=nullptr)
Selects matching features using an expression.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
void setRenderer(QgsFeatureRenderer *r)
Sets the feature renderer which will be invoked to represent this layer in 2D map views.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, bool validateIds=false)
Selects matching features using a list of feature IDs.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
virtual bool setSubsetString(const QString &subset)
Sets the string (typically sql) used to define a subset of the layer.
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
QgsEditFormConfig editFormConfig
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const final
Calculates a list of unique values contained within an attribute in the layer.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Implementation of legend node interface for displaying WMS legend entries.
Exception thrown in case of malformed request.
QgsRenderer(const QgsWmsRenderContext &context)
Constructor for QgsRenderer.
QHash< QgsVectorLayer *, SymbolSet > HitTest
QByteArray getPrint()
Returns printed page as binary.
HitTest symbols()
Returns the hit test according to the current context.
std::unique_ptr< QgsDxfExport > getDxf()
Returns the map as DXF data.
QSet< QString > SymbolSet
void configureLayers(QList< QgsMapLayer * > &layers, QgsMapSettings *settings=nullptr)
Configures layers for rendering optionally considering the map settings.
std::unique_ptr< QgsMapRendererTask > getPdf(const QString &tmpFileName)
Returns a configured pdf export task.
QByteArray getFeatureInfo(const QString &version="1.3.0")
Creates an xml document that describes the result of the getFeatureInfo request.
QImage * getLegendGraphics(QgsLayerTreeModel &model)
Returns the map legend as an image (or nullptr in case of error).
std::unique_ptr< QImage > getMap()
Returns the map as an image (or nullptr in case of error).
QJsonObject getLegendGraphicsAsJson(QgsLayerTreeModel &model, const Qgis::LegendJsonRenderFlags &jsonRenderFlags=Qgis::LegendJsonRenderFlags())
Returns the map legend as a JSON object.
Exception class for WMS service exceptions.
ExceptionCode
Exception codes as defined in OGC scpecifications for WMS 1.1.1 and WMS 1.3.0.
@ QGIS_InvalidParameterValue
@ QGIS_MissingParameterValue
WMS parameter received from the client.
bool transparentAsBool() const
Returns TRANSPARENT parameter as a bool or its default value if not defined.
QString formatAsString() const
Returns FORMAT parameter as a string.
QgsWmsParametersComposerMap composerMapParameters(int mapId) const
Returns the requested parameters for a composer map parameter.
DxfFormatOption
Options for DXF format.
QColor backgroundColorAsColor() const
Returns BGCOLOR parameter as a QColor or its default value if not defined.
Format format() const
Returns format.
Format
Output format for the response.
Rendering context for the WMS renderer.
QList< QgsMapLayer * > layersToRender() const
Returns a list of all layers to actually render according to the current configuration.
void setScaleDenominator(double scaleDenominator)
Sets a custom scale denominator.
Median cut implementation.
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
#define FID_TO_STRING(fid)
QVector< QgsFeatureStore > QgsFeatureStoreList
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
QgsAbstractMetadataBase::KeywordMap keywords
Metadata keyword map.
QString creator
Metadata creator tag.
QString author
Metadata author tag.
QString subject
Metadata subject tag.
QString title
Metadata title tag.
QDateTime creationDateTime
Metadata creation datetime.
QString producer
Metadata producer tag.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO32000 extension format georeferencing should be used.
Encapsulates the properties of a vector layer containing features that will be exported to the DXF fi...
QPainter * painter
Painter.
Q_NOWARN_DEPRECATED_POP QgsRenderContext * context
Render context, if available.
Contains settings relating to exporting layouts to raster images.
QList< int > pages
List of specific pages to export, or an empty list to export all pages.
QSize imageSize
Manual size in pixels for output image.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
Contains settings relating to exporting layouts to PDF.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO3200 extension format georeferencing should be used.
bool forceVectorOutput
Set to true to force vector object exports, even when the resultant appearance will differ from the l...
bool rasterizeWholeImage
Set to true to force whole layout to be rasterized while exporting.
QStringList exportThemes
Optional list of map themes to export as Geospatial PDF layer groups.
bool appendGeoreference
Indicates whether PDF export should append georeference data.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
bool writeGeoPdf
true if geospatial PDF files should be created, instead of normal PDF files.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
bool simplifyGeometries
Indicates whether vector geometries should be simplified to avoid redundant extraneous detail,...
Qgis::TextRenderFormat textRenderFormat
Text rendering format, which controls how text should be rendered in the export (e....
Contains settings relating to exporting layouts to SVG.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
QList< QgsWmsParametersLayer > mLayers
QList< QgsWmsParametersHighlightLayer > mHighlightLayers