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 );
1336 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1348#ifdef HAVE_SERVER_PYTHON_PLUGINS
1349 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1352 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1357 ba = convertFeatureInfoToText( result );
1359 ba = convertFeatureInfoToHtml( result );
1361 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1363 ba = result.toByteArray();
1368 QImage *QgsRenderer::createImage(
const QSize &size )
const
1370 std::unique_ptr<QImage> image;
1378 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1383 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1388 if ( image->isNull() )
1390 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1393 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1394 image->setDotsPerMeterX( dpm );
1395 image->setDotsPerMeterY( dpm );
1397 return image.release();
1400 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1404 throw QgsException( u
"configureMapSettings: no paint device"_s );
1407 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1410 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1413 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1414 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1419 QString crs = mWmsParameters.crs();
1420 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1422 crs = QString(
"EPSG:4326" );
1425 else if ( crs.isEmpty() && !mandatoryCrsParam )
1427 crs = QString(
"EPSG:4326" );
1430 QgsCoordinateReferenceSystem outputCRS;
1437 QgsWmsParameter parameter;
1439 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1450 throw QgsBadRequestException( code, parameter );
1459 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1467 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1473 bool transparent = mWmsParameters.transparentAsBool();
1474 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1481 else if ( backgroundColor.isValid() )
1487 QgsExpressionContext context = mProject->createExpressionContext();
1504 if ( mContext.settings().logProfile() )
1514 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1515 if ( !timeString.isEmpty() )
1517 bool isValidTemporalRange {
true };
1520 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1531 catch (
const QgsServerApiBadRequestException &ex )
1533 isValidTemporalRange =
false;
1538 if ( isValidTemporalRange )
1547 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1553 QgsDistanceArea distanceArea = QgsDistanceArea();
1554 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1560 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1562 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1564 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1566 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1568 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1570 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1572 int featureCount = mWmsParameters.featureCountAsInt();
1573 if ( featureCount < 1 )
1578 int i = mWmsParameters.iAsInt();
1579 int j = mWmsParameters.jAsInt();
1580 if ( xyDefined && !ijDefined )
1582 i = mWmsParameters.xAsInt();
1583 j = mWmsParameters.yAsInt();
1585 int width = mWmsParameters.widthAsInt();
1586 int height = mWmsParameters.heightAsInt();
1587 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1589 i *= ( outputImage->width() /
static_cast<double>( width ) );
1590 j *= ( outputImage->height() /
static_cast<double>( height ) );
1594 std::unique_ptr<QgsRectangle> featuresRect;
1595 std::unique_ptr<QgsGeometry> filterGeom;
1596 std::unique_ptr<QgsPointXY> infoPoint;
1598 if ( i != -1 && j != -1 )
1600 infoPoint = std::make_unique<QgsPointXY>();
1601 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1603 else if ( filtersDefined )
1605 featuresRect = std::make_unique<QgsRectangle>();
1608 if ( filterGeomDefined )
1610 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1613 QDomDocument result;
1614 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1615 result.appendChild( header );
1617 QDomElement getFeatureInfoElement;
1621 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1622 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1623 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1624 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1625 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1626 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1627 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1628 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1629 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 );
1634 if ( featureInfoElemName.isEmpty() )
1636 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1639 if ( featureInfoElemNs.isEmpty() )
1641 getFeatureInfoElement = result.createElement( featureInfoElemName );
1645 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1649 if ( !featureInfoSchema.isEmpty() )
1651 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1652 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1655 result.appendChild( getFeatureInfoElement );
1665 for (
const QString &queryLayer : queryLayers )
1667 bool validLayer =
false;
1668 bool queryableLayer =
true;
1669 for ( QgsMapLayer *layer : std::as_const( layers ) )
1671 if ( queryLayer == mContext.layerNickname( *layer ) )
1675 if ( !queryableLayer )
1680 QDomElement layerElement;
1683 layerElement = getFeatureInfoElement;
1687 layerElement = result.createElement( u
"Layer"_s );
1688 QString layerName = queryLayer;
1691 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1692 if ( layerAliasIt != layerAliasMap.constEnd() )
1694 layerName = layerAliasIt.value();
1697 layerElement.setAttribute( u
"name"_s, layerName );
1698 const QString layerTitle = layer->serverProperties()->title();
1699 if ( !layerTitle.isEmpty() )
1701 layerElement.setAttribute( u
"title"_s, layerTitle );
1705 layerElement.setAttribute( u
"title"_s, layerName );
1707 getFeatureInfoElement.appendChild( layerElement );
1710 layerElement.setAttribute( u
"id"_s, layer->id() );
1716 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1719 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1725 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1741 layerElement = result.createElement( u
"gml:featureMember"_s );
1742 getFeatureInfoElement.appendChild( layerElement );
1744 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1748 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1756 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1760 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1763 param.mValue = queryLayer;
1766 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1769 param.mValue = queryLayer;
1771 bool hasGroupAndQueryable {
false };
1772 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1775 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1776 for (
const QString &ql : constNicks )
1778 if ( mContext.layerGroups().contains( ql ) )
1780 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1781 for (
const QgsMapLayer *ml : constLayers )
1783 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1789 hasGroupAndQueryable =
true;
1798 if ( !hasGroupAndQueryable )
1805 if ( featuresRect && !featuresRect->isNull() )
1809 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1810 QDomElement boxElem;
1811 int gmlVersion = mWmsParameters.infoFormatVersion();
1812 if ( gmlVersion < 3 )
1824 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1826 bBoxElem.appendChild( boxElem );
1827 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1831 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1833 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1834 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1835 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1836 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1837 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1843 convertFeatureInfoToSia2045( result );
1849 bool QgsRenderer::featureInfoFromVectorLayer(
1850 QgsVectorLayer *layer,
1851 const QgsPointXY *infoPoint,
1853 QDomDocument &infoDocument,
1854 QDomElement &layerElement,
1855 const QgsMapSettings &mapSettings,
1856 QgsRenderContext &renderContext,
1857 const QString &version,
1858 QgsRectangle *featureBBox,
1859 QgsGeometry *filterGeom
1867 QgsFeatureRequest fReq;
1870 std::unique_ptr<QgsGeometry> layerFilterGeom;
1873 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1878 QgsRectangle mapRect = mapSettings.
extent();
1882 QgsRectangle searchRect;
1887 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1889 else if ( layerFilterGeom )
1891 searchRect = layerFilterGeom->boundingBox();
1893 else if ( !mWmsParameters.bbox().isEmpty() )
1895 searchRect = layerRect;
1901 QgsAttributes featureAttributes;
1902 int featureCounter = 0;
1904 const QgsFields fields = layer->
fields();
1921 if ( layerFilterGeom )
1923 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1927 mFeatureFilter.filterFeatures( layer, fReq );
1930#ifdef HAVE_SERVER_PYTHON_PLUGINS
1932 mContext.accessControl()->filterFeatures( layer, fReq );
1935 QStringList attributes;
1936 for (
const QgsField &field : fields )
1938 attributes.append( field.name() );
1940 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1944 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1948 r2->startRender( renderContext, layer->
fields() );
1951 bool featureBBoxInitialized =
false;
1960 if ( featureCounter > nFeatures )
1975 bool render = r2->willRenderFeature( feature, renderContext );
1988 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1991 featureBBoxInitialized =
true;
2000 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
2009 int gmlVersion = mWmsParameters.infoFormatVersion();
2010 QString typeName = mContext.layerNickname( *layer );
2011 QDomElement elem = createFeatureGML(
2020#ifdef HAVE_SERVER_PYTHON_PLUGINS
2025 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2026 featureMemberElem.appendChild( elem );
2027 layerElement.appendChild( featureMemberElem );
2032 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2034 layerElement.appendChild( featureElement );
2040 writeAttributesTabLayout(
2048#ifdef HAVE_SERVER_PYTHON_PLUGINS
2056 for (
int i = 0; i < featureAttributes.count(); ++i )
2058 writeVectorLayerAttribute(
2066#ifdef HAVE_SERVER_PYTHON_PLUGINS
2078 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2079 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2083 featureElement.appendChild( maptipElem );
2087 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2089 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2090 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2093 displayExpression.
prepare( &context );
2094 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2095 featureElement.appendChild( displayElem );
2101 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2102 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2107 featureElement.appendChild( bBoxElem );
2113 QgsGeometry geom = feature.
geometry();
2116 if ( layer->
crs() != outputCrs )
2118 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2123 if ( segmentizeWktGeometry )
2125 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2130 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2131 geom.
set( segmentizedGeom );
2135 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2136 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2137 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2138 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2139 featureElement.appendChild( geometryElement );
2146 r2->stopRender( renderContext );
2152 void QgsRenderer::writeAttributesTabGroup(
2153 const QgsAttributeEditorElement *group,
2154 QgsVectorLayer *layer,
2155 const QgsFields &fields,
2156 QgsAttributes &featureAttributes,
2158 QDomElement &parentElem,
2159 QgsRenderContext &renderContext,
2160 QStringList *attributes
2163 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2166 QString groupName = container->
name();
2167 QDomElement nameElem;
2169 if ( !groupName.isEmpty() )
2171 nameElem = doc.createElement( groupName );
2172 parentElem.appendChild( nameElem );
2175 const QList<QgsAttributeEditorElement *> children = container->
children();
2176 for (
const QgsAttributeEditorElement *child : children )
2180 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2184 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2190 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2198 void QgsRenderer::writeAttributesTabLayout(
2199 QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2203 if ( !editorContainer )
2208 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2211 void QgsRenderer::writeVectorLayerAttribute(
2212 int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2215#ifndef HAVE_SERVER_PYTHON_PLUGINS
2216 Q_UNUSED( attributes );
2229#ifdef HAVE_SERVER_PYTHON_PLUGINS
2231 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2238 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2239 attributeElement.setAttribute( u
"name"_s, attributeName );
2242 featureElem.appendChild( attributeElement );
2245 bool QgsRenderer::featureInfoFromMeshLayer(
2246 QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2250 Q_UNUSED( mapSettings )
2259 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2261 QList<QgsMeshDatasetIndex> datasetIndexList;
2270 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2272 if ( activeScalarGroup >= 0 )
2274 QgsMeshDatasetIndex indice;
2276 datasetIndexList.append( indice );
2279 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2282 for (
int groupIndex : allGroup )
2284 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2290 if ( activeScalarGroup >= 0 )
2292 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2295 for (
int groupIndex : allGroup )
2297 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2300 datasetIndexList.append( groupIndex );
2307 double scalarDoubleValue = 0.0;
2309 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2311 if ( !index.isValid() )
2315 QMap<QString, QString> derivedAttributes;
2317 QMap<QString, QString> attribute;
2321 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2322 scalarDoubleValue = scalarValue.
scalar();
2323 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2328 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2329 const double vectorX = vectorValue.
x();
2330 const double vectorY = vectorValue.
y();
2331 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2333 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2337 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2338 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2339 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2346 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2347 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2349 const QString resultName = groupMeta.
name();
2351 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2352 attributeElement.setAttribute( u
"name"_s, resultName );
2357 value = QString::number( scalarDoubleValue );
2360 attributeElement.setAttribute( u
"value"_s, value );
2361 layerElement.appendChild( attributeElement );
2365 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2366 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2369 value = range.
begin().toString( dateFormat );
2373 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2375 attributeElementTime.setAttribute( u
"value"_s, value );
2376 layerElement.appendChild( attributeElementTime );
2382 bool QgsRenderer::featureInfoFromRasterLayer(
2383 QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2404 QgsRasterIdentifyResult identifyResult;
2407 const QgsRectangle extent { mapSettings.
extent() };
2411 throw QgsBadRequestException(
2422 if ( !identifyResult.
isValid() )
2425 QMap<int, QVariant> attributes = identifyResult.
results();
2431 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2432 int gmlVersion = mWmsParameters.infoFormatVersion();
2433 QString typeName = mContext.layerNickname( *layer );
2439 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2441 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2442 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2445 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2446 layerElement.appendChild( elem );
2450 const auto values = identifyResult.
results();
2451 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2453 QVariant value = it.value();
2454 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2460 if ( value.userType() == QMetaType::Type::QString )
2468 for (
const QgsFeatureStore &featureStore : featureStoreList )
2471 for (
const QgsFeature &feature : storeFeatures )
2473 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2474 layerElement.appendChild( elem );
2484 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2486 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2487 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2492 value = QString::number( it.value().toDouble() );
2495 attributeElement.setAttribute( u
"value"_s, value );
2496 layerElement.appendChild( attributeElement );
2501 const auto values = identifyResult.
results();
2502 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2504 QVariant value = it.value();
2505 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2511 if ( value.userType() == QMetaType::Type::QString )
2518 for (
const QgsFeatureStore &featureStore : featureStoreList )
2521 for (
const QgsFeature &feature : storeFeatures )
2523 for (
const auto &fld : feature.
fields() )
2525 const auto val { feature.
attribute( fld.name() ) };
2526 if ( val.isValid() )
2528 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2529 attributeElement.setAttribute( u
"name"_s, fld.name() );
2530 attributeElement.setAttribute( u
"value"_s, val.toString() );
2531 layerElement.appendChild( attributeElement );
2542 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2543 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2546 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2549 layerElement.appendChild( maptipElem );
2555 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2558 if ( filter.contains(
";"_L1 ) )
2563 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2564 groupStringList( tokens, u
"'"_s );
2565 groupStringList( tokens, u
"\""_s );
2567 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2570 if ( 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(
'%'_L1 ) == 0
2580 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2581 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2582 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2583 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2584 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2585 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2586 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2587 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2588 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2589 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2590 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2597 ( void ) tokenIt->toDouble( &isNumeric );
2606 if ( *tokenIt ==
"''"_L1 )
2612 if ( tokenIt->size() > 2
2613 && ( *tokenIt )[0] == QChar(
'\'' )
2614 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2615 && ( *tokenIt )[1] != QChar(
'\'' )
2616 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2622 if ( tokenIt->size() > 2 && ( *tokenIt )[0] == QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' ) && ( *tokenIt )[1] != QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2633 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2636 bool groupActive =
false;
2637 int startGroup = -1;
2638 QString concatString;
2640 for (
int i = 0; i < list.size(); ++i )
2642 QString &str = list[i];
2643 if ( str.startsWith( groupString ) )
2647 concatString.clear();
2652 if ( i != startGroup )
2654 concatString.append(
" " );
2656 concatString.append( str );
2659 if ( str.endsWith( groupString ) )
2662 groupActive =
false;
2664 if ( startGroup != -1 )
2666 list[startGroup] = concatString;
2667 for (
int j = startGroup + 1; j <= endGroup; ++j )
2669 list.removeAt( startGroup + 1 );
2674 concatString.clear();
2680 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2682 QDomDocument SIAInfoDoc;
2683 QDomElement infoDocElement = doc.documentElement();
2684 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2685 SIAInfoDoc.appendChild( SIAInfoDocElement );
2687 QString currentAttributeName;
2688 QString currentAttributeValue;
2689 QDomElement currentAttributeElem;
2690 QString currentLayerName;
2691 QDomElement currentLayerElem;
2692 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2693 for (
int i = 0; i < layerNodeList.size(); ++i )
2695 currentLayerElem = layerNodeList.at( i ).toElement();
2696 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2698 QDomElement currentFeatureElem;
2700 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2701 if ( featureList.isEmpty() )
2704 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2705 QDomElement rasterLayerElem;
2706 if ( !attributeList.isEmpty() )
2708 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2710 for (
int j = 0; j < attributeList.size(); ++j )
2712 currentAttributeElem = attributeList.at( j ).toElement();
2713 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2714 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2715 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2716 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2717 outAttributeElem.appendChild( outAttributeText );
2718 rasterLayerElem.appendChild( outAttributeElem );
2720 if ( !attributeList.isEmpty() )
2722 SIAInfoDocElement.appendChild( rasterLayerElem );
2728 QSet<QString> layerPropertyAttributes;
2729 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2730 if ( !currentLayerId.isEmpty() )
2732 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2735 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2736 if ( !WMSPropertyAttributesString.isEmpty() )
2738 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2739 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2741 layerPropertyAttributes.insert( *propertyIt );
2747 QDomElement propertyRefChild;
2748 for (
int j = 0; j < featureList.size(); ++j )
2750 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2751 currentFeatureElem = featureList.at( j ).toElement();
2752 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2754 for (
int k = 0; k < attributeList.size(); ++k )
2756 currentAttributeElem = attributeList.at( k ).toElement();
2757 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2758 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2759 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2761 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2762 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2763 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2764 identifierElem.appendChild( identifierText );
2765 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2766 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2767 valueElem.appendChild( valueText );
2768 propertyElem.appendChild( identifierElem );
2769 propertyElem.appendChild( valueElem );
2770 if ( propertyRefChild.isNull() )
2772 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2773 propertyRefChild = propertyElem;
2777 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2782 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2783 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2784 SIAAttributeElem.appendChild( SIAAttributeText );
2785 SIAFeatureElem.appendChild( SIAAttributeElem );
2788 SIAInfoDocElement.appendChild( SIAFeatureElem );
2795 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2798 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2801 featureInfoString.append( QStringLiteral( R
"HTML(
2804 <title>Information</title>
2805 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2808 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2815 border: 1px solid black;
2816 border-collapse: collapse;
2837 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2840 for (
int i = 0; i < layerList.size(); ++i )
2842 const QDomElement layerElem = layerList.at( i ).toElement();
2845 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2846 const QDomElement currentFeatureElement;
2848 if ( !featureNodeList.isEmpty() )
2852 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2853 featureInfoString.append( featureInfoLayerTitleString );
2856 for (
int j = 0; j < featureNodeList.size(); ++j )
2858 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2861 featureInfoString.append( QStringLiteral( R
"HTML(
2866 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2867 for (
int k = 0; k < attributeNodeList.size(); ++k )
2869 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2870 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2871 QString value = attributeElement.attribute( u
"value"_s );
2872 if ( name !=
"maptip"_L1 )
2874 value = value.toHtmlEscaped();
2879 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2884 .arg( name, value );
2886 featureInfoString.append( featureInfoAttributeString );
2888 else if ( name ==
"maptip"_L1 )
2890 featureInfoString.append( QStringLiteral( R
"HTML(
2898 featureInfoString.append( QStringLiteral( R
"HTML(
2905 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2908 if ( !attributeNodeList.isEmpty() )
2912 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2913 featureInfoString.append( featureInfoLayerTitleString );
2915 featureInfoString.append( QStringLiteral( R
"HTML(
2919 for (
int j = 0; j < attributeNodeList.size(); ++j )
2921 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2922 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2923 QString value = attributeElement.attribute( u
"value"_s );
2924 if ( value.isEmpty() )
2926 value = u
"no data"_s;
2928 if ( name !=
"maptip"_L1 )
2930 value = value.toHtmlEscaped();
2935 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2940 .arg( name, value );
2943 featureInfoString.append( featureInfoAttributeString );
2945 else if ( name ==
"maptip"_L1 )
2947 featureInfoString.append( QStringLiteral( R
"HTML(
2955 featureInfoString.append( QStringLiteral( R
"HTML(
2965 featureInfoString.append( QStringLiteral( R
"HTML(
2969 return featureInfoString.toUtf8();
2972 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2974 QString featureInfoString;
2977 featureInfoString.append(
"GetFeatureInfo results\n" );
2978 featureInfoString.append(
"\n" );
2980 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2983 for (
int i = 0; i < layerList.size(); ++i )
2985 QDomElement layerElem = layerList.at( i ).toElement();
2987 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2990 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2991 QDomElement currentFeatureElement;
2993 if ( !featureNodeList.isEmpty() )
2995 for (
int j = 0; j < featureNodeList.size(); ++j )
2997 QDomElement featureElement = featureNodeList.at( j ).toElement();
2998 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
3001 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
3002 for (
int k = 0; k < attributeNodeList.size(); ++k )
3004 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
3005 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
3011 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
3012 for (
int j = 0; j < attributeNodeList.size(); ++j )
3014 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
3015 QString value = attributeElement.attribute( u
"value"_s );
3016 if ( value.isEmpty() )
3018 value = u
"no data"_s;
3020 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
3024 featureInfoString.append(
"\n" );
3027 return featureInfoString.toUtf8();
3030 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
3033 {
"type",
"FeatureCollection" },
3034 {
"features", json::array() },
3037 const bool withDisplayName = mWmsParameters.withDisplayName();
3039 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
3040 for (
int i = 0; i < layerList.size(); ++i )
3042 const QDomElement layerElem = layerList.at( i ).toElement();
3043 const QString layerName = layerElem.attribute( u
"name"_s );
3045 QgsMapLayer *layer =
nullptr;
3046 for ( QgsMapLayer *l : layers )
3048 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3059 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3064 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3065 if ( featuresNode.isEmpty() )
3068 QMap<QgsFeatureId, QString> fidMap;
3069 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3071 for (
int j = 0; j < featuresNode.size(); ++j )
3073 const QDomElement featureNode = featuresNode.at( j ).toElement();
3074 const QString fid = featureNode.attribute( u
"id"_s );
3077 if ( expression.isEmpty() )
3079 feature = vl->
getFeature( fid.toLongLong() );
3083 QgsFeatureRequest request { QgsExpression( expression ) };
3088 fidMap.insert( feature.
id(), fid );
3093 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3094 for (
int k = 0; k < attrs.count(); k++ )
3096 const QDomElement elm = attrs.at( k ).toElement();
3097 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3099 wkt = elm.attribute(
"value" );
3104 if ( !wkt.isEmpty() )
3112 if ( withDisplayName )
3114 QString displayName;
3115 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3116 for (
int k = 0; k < attrs.count(); k++ )
3118 const QDomElement elm = attrs.at( k ).toElement();
3119 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3121 displayName = elm.attribute(
"value" );
3125 fidDisplayNameMap.insert( feature.
id(), displayName );
3128 features << feature;
3131 if ( !attributes.isEmpty() )
3134 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3135 for (
int k = 0; k < attributesNode.size(); ++k )
3137 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3138 const QString fieldName = attributeElement.attribute( u
"name"_s );
3139 attributes << feature.fieldNameIndex( fieldName );
3144 QgsJsonExporter exporter( vl );
3145 exporter.setAttributeDisplayName(
true );
3146 exporter.setAttributes( attributes );
3147 exporter.setIncludeGeometry( withGeometry );
3148 exporter.setTransformGeometries(
false );
3152 for (
const auto &feature : std::as_const( features ) )
3154 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3155 QVariantMap extraProperties;
3156 if ( withDisplayName )
3158 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3160 json[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id ) );
3165 auto properties = json::object();
3166 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3167 for (
int j = 0; j < attributesNode.size(); ++j )
3169 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3170 const QString name = attrElmt.attribute( u
"name"_s );
3172 QString value = attrElmt.attribute( u
"value"_s );
3173 if ( value.isEmpty() )
3178 properties[name.toStdString()] = value.toStdString();
3181 json[
"features"].push_back( { {
"type",
"Feature" }, {
"id", layerName.toStdString() }, {
"properties", properties } } );
3186 return QByteArray::fromStdString( json.dump( 2 ) );
3188 return QByteArray::fromStdString( json.dump() );
3192 QDomElement QgsRenderer::createFeatureGML(
3193 const QgsFeature *feat, QgsVectorLayer *layer, QDomDocument &doc, QgsCoordinateReferenceSystem &crs,
const QgsMapSettings &mapSettings,
const QString &typeName,
bool withGeom,
int version, QStringList *attributes
3197 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3204 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3206 QgsCoordinateTransform transform;
3207 if ( layer && layer->
crs() != crs )
3212 QgsGeometry geom = feat->
geometry();
3214 QgsExpressionContext expressionContext;
3220 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3234 catch ( QgsCsException &e )
3240 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3241 QDomElement boxElem;
3253 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3255 bbElem.appendChild( boxElem );
3256 typeNameElement.appendChild( bbElem );
3260 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3261 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3262 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3265 const QList<QgsAttributeEditorElement *> children = container->
children();
3266 for (
const QgsAttributeEditorElement *child : children )
3268 switch ( child->type() )
3272 if ( findAttributeInTree( attributeName, child ) )
3280 if ( child->name() == attributeName )
3288 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3289 if ( relationEditor )
3291 const QgsRelation &relation { relationEditor->
relation() };
3295 for (
const auto &idx : std::as_const( referencedFields ) )
3297 const QgsField f { layer->
fields().
at( idx ) };
3298 if ( f.
name() == attributeName )
3307 for (
const auto &idx : std::as_const( referencingFields ) )
3309 const QgsField f { layer->
fields().
at( idx ) };
3310 if ( f.
name() == attributeName )
3327 if ( withGeom && !geom.
isNull() )
3336 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3337 QDomElement gmlElem;
3347 if ( !gmlElem.isNull() )
3351 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3353 geomElem.appendChild( gmlElem );
3354 typeNameElement.appendChild( geomElem );
3359 QgsAttributes featureAttributes = feat->
attributes();
3360 QgsFields fields = feat->
fields();
3361 for (
int i = 0; i < fields.
count(); ++i )
3363 QString attributeName = fields.
at( i ).
name();
3370 if ( attributes && !attributes->contains( attributeName ) )
3375 if ( honorFormConfig )
3378 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3384 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3385 QString fieldTextString = featureAttributes.at( i ).toString();
3390 QDomText fieldText = doc.createTextNode( fieldTextString );
3391 fieldElem.appendChild( fieldText );
3392 typeNameElement.appendChild( fieldElem );
3403 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3404 QDomText maptipText = doc.createTextNode( fieldTextString );
3405 fieldElem.appendChild( maptipText );
3406 typeNameElement.appendChild( fieldElem );
3410 return typeNameElement;
3413 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3417 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3419 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3421 value = value.mid( 1, value.size() - 2 );
3426 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3430 return QgsRectangle();
3433 double mapUnitTolerance = 0.0;
3436 if ( !mWmsParameters.polygonTolerance().isEmpty() && mWmsParameters.polygonToleranceAsInt() > 0 )
3442 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3447 if ( !mWmsParameters.lineTolerance().isEmpty() && mWmsParameters.lineToleranceAsInt() > 0 )
3453 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3458 if ( !mWmsParameters.pointTolerance().isEmpty() && mWmsParameters.pointToleranceAsInt() > 0 )
3464 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3471 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3475 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3477 QList<QgsMapLayer *> highlightLayers;
3480 QString crs = mWmsParameters.crs();
3481 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3484 QDomDocument sldDoc;
3488 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3495 std::unique_ptr<QgsFeatureRenderer> renderer;
3496 QDomElement el = sldDoc.documentElement();
3506 QString url = typeName +
"?crs=" + crs;
3507 if ( !param.mLabel.isEmpty() )
3509 url +=
"&field=label:string";
3514 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3521 QgsFeature fet( layer->
fields() );
3522 if ( !param.mLabel.isEmpty() )
3524 fet.setAttribute( 0, param.mLabel );
3527 QgsPalLayerSettings palSettings;
3532 palSettings.
dist = param.mLabelDistance;
3541 switch ( param.mGeom.type() )
3552 QgsPointXY pt = param.mGeom.asPoint();
3554 QVariant x( pt.
x() );
3557 QVariant y( pt.
y() );
3569 QgsGeometry point = param.mGeom.pointOnSurface();
3570 QgsPointXY pt = point.
asPoint();
3574 QVariant x( pt.
x() );
3578 QVariant y( pt.
y() );
3582 QVariant hali(
"Center" );
3586 QVariant vali(
"Half" );
3598 QgsTextFormat textFormat;
3599 QgsTextBufferSettings bufferSettings;
3601 if ( param.mColor.isValid() )
3603 textFormat.
setColor( param.mColor );
3606 if ( param.mSize > 0 )
3608 textFormat.
setSize( param.mSize );
3616 if ( !param.mFont.isEmpty() )
3618 textFormat.
setFont( param.mFont );
3621 if ( param.mBufferColor.isValid() )
3623 bufferSettings.
setColor( param.mBufferColor );
3626 if ( param.mBufferSize > 0 )
3629 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3635 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3639 fet.setGeometry( param.mGeom );
3648 highlightLayers.append( layer.release() );
3652 mTemporaryLayers.append( highlightLayers );
3653 return highlightLayers;
3656 void QgsRenderer::removeTemporaryLayers()
3658 qDeleteAll( mTemporaryLayers );
3659 mTemporaryLayers.clear();
3662 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3664 QPainter *painter =
nullptr;
3666 QgsFeatureFilterProviderGroup filters;
3668#ifdef HAVE_SERVER_PYTHON_PLUGINS
3669 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3672 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3674 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3675 painter = renderJob.takePainter();
3677 logRenderingErrors( renderJob.errors() );
3679 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3681 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3683 QString layerWMSName;
3684 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3687 layerWMSName = mContext.layerNickname( *errorLayer );
3690 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3691 if ( !layerWMSName.isEmpty() )
3693 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3695 throw QgsException( errorMessage );
3701 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3703 if ( opacity >= 0 && opacity <= 255 )
3705 switch ( layer->
type() )
3709 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3714 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3722 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3723 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3724 rasterRenderer->
setOpacity( opacity / 255. );
3730 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3746 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3750 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3751 QStringList expList;
3752 for (
const QgsWmsParametersFilter &filter : filters )
3757 QDomDocument filterXml;
3759 QXmlStreamReader xmlReader( filter.mFilter );
3760 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3761 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3762 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3764 throw QgsBadRequestException(
3766 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 )
3770 QDomElement filterElem = filterXml.firstChildElement();
3775 expList << filterExp->dump();
3781 if ( !testFilterStringSafety( filter.mFilter ) )
3783 throw QgsSecurityException(
3785 "The filter string %1"
3786 " has been rejected because of security reasons."
3787 " Note: Text strings have to be enclosed in single or double quotes."
3788 " A space between each word / special character is mandatory."
3789 " Allowed Keywords and special characters are"
3790 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3791 " Not allowed are semicolons in the filter expression."
3793 .arg( filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' ) )
3797 QString newSubsetString = filter.mFilter;
3800 newSubsetString.prepend(
") AND (" );
3801 newSubsetString.append(
")" );
3802 newSubsetString.prepend( filteredLayer->
subsetString() );
3803 newSubsetString.prepend(
"(" );
3813 expList.append( dimensionFilter( filteredLayer ) );
3817 if ( expList.size() == 1 )
3821 else if ( expList.size() > 1 )
3823 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3825 if ( !exp.isEmpty() )
3827 auto expression = std::make_unique<QgsExpression>( exp );
3831 mFeatureFilter.setFilter( filteredLayer, *expression );
3838 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3840 QStringList expList;
3842 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3843 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3844 if ( wmsDims.isEmpty() )
3849 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3850 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3859 if ( fieldIndex == -1 )
3864 int endFieldIndex = -1;
3865 if ( !dim.endFieldName.isEmpty() )
3867 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3868 if ( endFieldIndex == -1 )
3874 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3878 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::AllValues )
3882 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
3884 defValue = dim.referenceValue;
3889 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3890 if ( endFieldIndex != -1 )
3892 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3895 QList<QVariant> values = qgis::setToList( uniqueValues );
3896 std::sort( values.begin(), values.end() );
3897 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
3899 defValue = values.first();
3901 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
3903 defValue = values.last();
3907 if ( endFieldIndex == -1 )
3913 QStringList expElems;
3922 expList << expElems.join(
' ' );
3928 QgsField dimField = layer->
fields().
at( fieldIndex );
3930 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3932 QStringList dimExplist;
3934 QStringList dimValues = dimParamValue.split(
',' );
3935 for (
int i = 0; i < dimValues.size(); ++i )
3937 QString dimValue = dimValues[i];
3939 if ( dimValue.size() > 1 )
3941 dimValue = dimValue.trimmed();
3944 if ( dimValue.contains(
'/' ) )
3946 QStringList rangeValues = dimValue.split(
'/' );
3948 if ( rangeValues.size() != 2 )
3953 QVariant rangeMin = QVariant( rangeValues[0] );
3954 QVariant rangeMax = QVariant( rangeValues[1] );
3965 QStringList expElems;
3966 if ( endFieldIndex == -1 )
4001 dimExplist << expElems.join(
' ' );
4005 QVariant dimVariant = QVariant( dimValue );
4011 if ( endFieldIndex == -1 )
4020 QStringList expElems;
4029 dimExplist << expElems.join(
' ' );
4034 if ( dimExplist.size() == 1 )
4036 expList << dimExplist;
4038 else if ( dimExplist.size() > 1 )
4040 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
4047 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4051 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4053 QgsFeatureRequest request;
4057 if ( selectedIds.empty() )
4068 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4070#ifdef HAVE_SERVER_PYTHON_PLUGINS
4077 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4080 QgsRectangle mapExtent = mapSettings.
extent();
4088 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4090 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4091 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4095 renderContext.
setFeedback( mContext.socketFeedback() );
4097 for ( QgsAnnotation *annotation : annotations )
4099 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4101 if ( !annotation || !annotation->isVisible() )
4107 if ( annotation->hasFixedMapPosition() )
4109 QgsPointXY mapPos = annotation->mapPosition();
4110 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4115 mapPos = coordTransform.transform( mapPos );
4117 catch (
const QgsCsException &e )
4123 offsetX = devicePos.
x();
4124 offsetY = devicePos.
y();
4128 const QPointF relativePos = annotation->relativePosition();
4129 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4130 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4134 painter->translate( offsetX, offsetY );
4135 annotation->render( renderContext );
4140 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4145 QImage *scaledImage =
nullptr;
4146 const int width = mWmsParameters.widthAsInt();
4147 const int height = mWmsParameters.heightAsInt();
4148 if ( width != image->width() || height != image->height() )
4150 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4158 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4159 for ( ; it != errors.constEnd(); ++it )
4161 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4162 if ( !it->layerID.isEmpty() )
4164 msg += QString(
" in layer %1" ).arg( it->layerID );
4170 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4177 QList<QgsLayoutItemMap *> mapList;
4181 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4182 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4184 logRenderingErrors( ( *mapIt )->renderingErrors() );
4187 if ( mContext.settings().ignoreRenderingErrors() )
4192 mapIt = mapList.constBegin();
4193 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4195 if ( !( *mapIt )->renderingErrors().isEmpty() )
4197 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4198 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4205 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4207 for (
auto layer : layers )
4209 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4211 if ( !mContext.layersToRender().contains( layer ) )
4216 if ( mContext.isExternalLayer( param.mNickname ) )
4220 setLayerOpacity( layer, param.mOpacity );
4227 setLayerSld( layer, mContext.sld( *layer ) );
4231 setLayerStyle( layer, mContext.style( *layer ) );
4236 setLayerOpacity( layer, param.mOpacity );
4241 setLayerFilter( layer, param.mFilter );
4246 setLayerAccessControlFilter( layer );
4251 setLayerSelection( layer, param.mSelection );
4254 if ( settings && mContext.updateExtent() )
4256 updateExtent( layer, *settings );
4262 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4266 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4268 if ( style.isEmpty() )
4280 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4285 QString sldStyleName =
"__sld_style";
4286 while ( styles.contains( sldStyleName ) )
4288 sldStyleName.append(
'@' );
4296 QgsLegendSettings QgsRenderer::legendSettings()
4299 QgsLegendSettings settings = mWmsParameters.legendSettings();
4301 if ( !mWmsParameters.bbox().isEmpty() )
4303 QgsMapSettings mapSettings;
4305 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4306 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 Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual bool readSld(const QDomNode &node, QString &errorMessage)
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QList< QgsMapRendererJob::Error > Errors
Contains configuration for rendering maps.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setSelectiveMaskingSourceSets(const QVector< QgsSelectiveMaskingSourceSet > &sets)
Sets a list of all selective masking source sets defined for the map.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QColor selectionColor() const
Returns the color that is used for drawing of selected vector features.
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
QString ellipsoid() const
Returns ellipsoid's acronym.
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QList< QgsMapThemeCollection::MapThemeLayerRecord > layerRecords() const
Returns a list of records for all visible layer belonging to the theme.
QgsMapThemeCollection::MapThemeRecord mapThemeState(const QString &name) const
Returns the recorded state of a map theme.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
void updateTriangularMesh(const QgsCoordinateTransform &transform=QgsCoordinateTransform())
Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh.
QgsMeshDatasetIndex staticVectorDatasetIndex(int group=-1) const
Returns the static vector dataset index that is rendered if the temporal properties is not active.
QList< int > enabledDatasetGroupsIndexes() const
Returns the list of indexes of enables dataset groups handled by the layer.
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset metadata.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetIndex datasetIndexAtTime(const QgsDateTimeRange &timeRange, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the time range.
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsMeshDatasetIndex activeScalarDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active scalar group depending on the time range.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshDatasetIndex staticScalarDatasetIndex(int group=-1) const
Returns the static scalar dataset index that is rendered if the temporal properties is not active.
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
static QDomElement rectangleToGMLEnvelope(const QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static QDomElement geometryToGML(const QgsGeometry &geometry, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
static QDomElement rectangleToGMLBox(const QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
Qgis::LabelPlacement placement
Label placement mode.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
int priority
Label priority.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
double dist
Distance from feature to the label.
Property
Data definable properties.
@ PositionX
X-coordinate data defined label position.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top).
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right).
QString fieldName
Name of field (or an expression) to use for label text.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsPrintLayout * clone() const override
Creates a clone of the layout.
Describes the version of a project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsMapThemeCollection * mapThemeCollection
QgsProjectMetadata metadata
QgsCoordinateTransformContext transformContext
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, Qgis::RasterIdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
bool isValid() const
Returns true if valid.
QMap< int, QVariant > results() const
Returns the identify results.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QString bandName(int bandNoInt) const
Returns the name of a band given its number.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
QList< int > referencedFields
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QList< int > referencingFields
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setDistanceArea(const QgsDistanceArea &distanceArea)
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly during rendering to check if rendering should ...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Scoped object for temporary scaling of a QgsRenderContext for millimeter based rendering.
static QgsDateTimeRange parseTemporalDateTimeInterval(const QString &interval)
Parses a datetime interval and returns a QgsDateTimeRange.
Exception base class for server exceptions.
static QString getExpressionFromServerFid(const QString &serverFid, const QgsVectorDataProvider *provider)
Returns the expression feature id based on primary keys.
static QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
static QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
static QString wmsFeatureInfoSchema(const QgsProject &project)
Returns the schema URL for XML GetFeatureInfo request.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static bool wmsHTMLFeatureInfoUseOnlyMaptip(const QgsProject &project)
Returns if only the maptip should be used for HTML feature info response so that the HTML response to...
static QString wmsFeatureInfoDocumentElementNs(const QgsProject &project)
Returns the document element namespace for XML GetFeatureInfo request.
static QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
static bool wmsFeatureInfoSegmentizeWktGeometry(const QgsProject &project)
Returns if the geometry has to be segmentize in GetFeatureInfo request.
static bool wmsFeatureInfoUseAttributeFormSettings(const QgsProject &project)
Returns if feature form settings should be considered for the format of the feature info response.
static QHash< QString, QString > wmsFeatureInfoLayerAliasMap(const QgsProject &project)
Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
static bool wmsFeatureInfoAddWktGeometry(const QgsProject &project)
Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
static double wmsDefaultMapUnitsPerMm(const QgsProject &project)
Returns the default number of map units per millimeters in case of the scale is not given.
static QString wmsFeatureInfoDocumentElement(const QgsProject &project)
Returns the document element name for XML GetFeatureInfo request.
static int wmsMaxAtlasFeatures(const QgsProject &project)
Returns the maximum number of atlas features which can be printed in a request.
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
Q_INVOKABLE QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const final
Calculates a list of unique values contained within an attribute in the layer.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Implementation of legend node interface for displaying WMS legend entries.
Exception thrown in case of malformed request.
QgsRenderer(const QgsWmsRenderContext &context)
Constructor for QgsRenderer.
QHash< QgsVectorLayer *, SymbolSet > HitTest
QByteArray getPrint()
Returns printed page as binary.
HitTest symbols()
Returns the hit test according to the current context.
std::unique_ptr< QgsDxfExport > getDxf()
Returns the map as DXF data.
QSet< QString > SymbolSet
void configureLayers(QList< QgsMapLayer * > &layers, QgsMapSettings *settings=nullptr)
Configures layers for rendering optionally considering the map settings.
std::unique_ptr< QgsMapRendererTask > getPdf(const QString &tmpFileName)
Returns a configured pdf export task.
QByteArray getFeatureInfo(const QString &version="1.3.0")
Creates an xml document that describes the result of the getFeatureInfo request.
QImage * getLegendGraphics(QgsLayerTreeModel &model)
Returns the map legend as an image (or nullptr in case of error).
std::unique_ptr< QImage > getMap()
Returns the map as an image (or nullptr in case of error).
QJsonObject getLegendGraphicsAsJson(QgsLayerTreeModel &model, const Qgis::LegendJsonRenderFlags &jsonRenderFlags=Qgis::LegendJsonRenderFlags())
Returns the map legend as a JSON object.
Exception class for WMS service exceptions.
ExceptionCode
Exception codes as defined in OGC scpecifications for WMS 1.1.1 and WMS 1.3.0.
@ QGIS_InvalidParameterValue
@ QGIS_MissingParameterValue
WMS parameter received from the client.
bool transparentAsBool() const
Returns TRANSPARENT parameter as a bool or its default value if not defined.
QString formatAsString() const
Returns FORMAT parameter as a string.
QgsWmsParametersComposerMap composerMapParameters(int mapId) const
Returns the requested parameters for a composer map parameter.
DxfFormatOption
Options for DXF format.
QColor backgroundColorAsColor() const
Returns BGCOLOR parameter as a QColor or its default value if not defined.
Format format() const
Returns format.
Format
Output format for the response.
Rendering context for the WMS renderer.
QList< QgsMapLayer * > layersToRender() const
Returns a list of all layers to actually render according to the current configuration.
void setScaleDenominator(double scaleDenominator)
Sets a custom scale denominator.
Median cut implementation.
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