23#include <nlohmann/json.hpp>
87#include <QTemporaryFile>
89#include <QXmlStreamReader>
91using namespace Qt::StringLiterals;
115 : mContext( context )
117 mProject = mContext.project();
119 mWmsParameters = mContext.parameters();
120 mWmsParameters.dump();
125 removeTemporaryLayers();
131 std::unique_ptr<QgsWmsRestorer> restorer;
132 restorer = std::make_unique<QgsWmsRestorer>( mContext );
135 QList<QgsMapLayer *> layers = mContext.layersToRender();
138 const qreal dpmm = mContext.dotsPerMm();
143 const auto layersToRender = mContext.layersToRender();
144 for (
const auto &layer : std::as_const( layersToRender ) )
147 if ( layer->dataProvider()->name() ==
"wms"_L1 )
151 const auto image { layerNode->getLegendGraphicBlocking() };
152 if ( !image.isNull() )
155 if ( mContext.isValidWidthHeight( image.width(), image.height() ) )
157 const double w = image.width() / dpmm;
158 const double h = image.height() / dpmm;
159 const QSizeF newWmsSize { w, h };
172 if ( !mWmsParameters.bbox().isEmpty() )
176 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
177 configureMapSettings( tmp.get(), mapSettings );
183 context = configureDefaultRenderContext();
187 std::unique_ptr<QImage> image;
188 const QSizeF minSize = renderer.
minimumSize( &context );
189 const QSize size(
static_cast<int>( minSize.width() * dpmm ),
static_cast<int>( minSize.height() * dpmm ) );
190 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
194 image.reset( createImage( size ) );
197 QPainter painter( image.get() );
200 if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
202 if ( painter.renderHints() & QPainter::LosslessImageRendering )
212 return image.release();
218 std::unique_ptr<QgsWmsRestorer> restorer;
219 restorer = std::make_unique<QgsWmsRestorer>( mContext );
222 QList<QgsMapLayer *> layers = mContext.layersToRender();
226 const QSize size( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() );
228 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
232 std::unique_ptr<QImage> image( createImage( size ) );
235 const qreal dpmm = mContext.dotsPerMm();
236 std::unique_ptr<QPainter> painter;
237 painter = std::make_unique<QPainter>( image.get() );
238 painter->setRenderHint( QPainter::Antialiasing,
true );
239 painter->scale( dpmm, dpmm );
250 nodeModel.
drawSymbol( settings, &ctx, size.height() / dpmm );
253 return image.release();
259 std::unique_ptr<QgsWmsRestorer> restorer;
260 restorer = std::make_unique<QgsWmsRestorer>( mContext );
263 QList<QgsMapLayer *> layers = mContext.layersToRender();
279 std::unique_ptr<QgsWmsRestorer> restorer;
280 restorer = std::make_unique<QgsWmsRestorer>( mContext );
283 QList<QgsMapLayer *> layers = mContext.layersToRender();
292 QJsonObject jsonSymbol {
legendNode.exportSymbolToJson( settings, renderContext ) };
299 if ( vLayer->renderer() )
303 const QString ruleExp { vLayer->renderer()->legendKeyToExpression( ruleKey, vLayer, ok ) };
306 jsonSymbol[u
"rule"_s] = ruleExp;
315 void QgsRenderer::runHitTest(
const QgsMapSettings &mapSettings, HitTest &hitTest )
const
319 for (
const QString &
id : mapSettings.
layerIds() )
336 runHitTestLayer( vl, usedSymbols, context );
340 void QgsRenderer::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context )
const
342 std::unique_ptr<QgsFeatureRenderer> r( vl->
renderer()->
clone() );
344 r->startRender( context, vl->
fields() );
346 QgsFeatureRequest request( context.
extent() );
348 QgsFeatureIterator fi = vl->
getFeatures( request );
352 if ( moreSymbolsPerFeature )
354 for ( QgsSymbol *s : r->originalSymbolsForFeature( f, context ) )
360 r->stopRender( context );
366 if ( !mContext.isValidWidthHeight() )
372 std::unique_ptr<QgsWmsRestorer> restorer;
373 restorer = std::make_unique<QgsWmsRestorer>( mContext );
378 QList<QgsMapLayer *> layers = mContext.layersToRender();
382 std::unique_ptr<QPainter> painter;
383 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
386 configureMapSettings( image.get(), mapSettings );
393 runHitTest( mapSettings,
symbols );
401 std::unique_ptr<QgsWmsRestorer> restorer;
402 restorer = std::make_unique<QgsWmsRestorer>( mContext );
405 const QString templateName = mWmsParameters.composerTemplate();
406 if ( templateName.isEmpty() )
429 std::unique_ptr<QgsPrintLayout> layout( sourceLayout->
clone() );
433 QStringList atlasPk = mWmsParameters.atlasPk();
434 if ( !atlasPk.isEmpty() )
436 atlas = layout->atlas();
437 if ( !atlas || !atlas->
enabled() )
450 if ( atlasPk.size() == 1 && atlasPk.at( 0 ) ==
"*"_L1 )
454 if ( atlas->
count() > maxAtlasFeatures )
462 if ( pkIndexes.size() == 0 )
464 QgsDebugMsgLevel( u
"Atlas print: layer %1 has no primary key attributes"_s.arg( cLayer->
name() ), 2 );
468 const int pkIndexesSize { std::max<int>( pkIndexes.size(), 1 ) };
470 QStringList pkAttributeNames;
471 for (
int pkIndex : std::as_const( pkIndexes ) )
473 pkAttributeNames.append( cLayer->
fields().
at( pkIndex ).
name() );
476 const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
477 if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() )
483 if ( nAtlasFeatures > maxAtlasFeatures )
488 QString filterString;
489 int currentAtlasPk = 0;
491 for (
int i = 0; i < nAtlasFeatures; ++i )
495 filterString.append(
" OR " );
498 filterString.append(
"( " );
501 if ( pkAttributeNames.isEmpty() )
503 filterString.append( u
"$id = %1"_s.arg( atlasPk.at( currentAtlasPk ) ) );
508 for (
int j = 0; j < pkIndexes.size(); ++j )
512 filterString.append(
" AND " );
519 filterString.append(
" )" );
527 if ( !errorString.isEmpty() )
529 throw QgsException( u
"An error occurred during the Atlas print: %1"_s.arg( errorString ) );
537 QList<QgsMapLayer *> layers = mContext.layersToRender();
541 auto image = std::make_unique<QImage>();
542 configureMapSettings( image.get(), mapSettings );
548 configurePrintLayout( layout.get(), mapSettings, atlas );
552 const QList<QgsMapLayer *> lyrs = mapSettings.
layers();
554#ifdef HAVE_SERVER_PYTHON_PLUGINS
555 mContext.accessControl()->resolveFilterFeatures( lyrs );
559 QHash<const QgsVectorLayer *, QStringList> fltrs;
564 fltrs.insert( vl, dimensionFilter( vl ) );
576 QTemporaryFile tempOutputFile( QDir::tempPath() +
'/' + u
"XXXXXX.%1"_s.arg( extension ) );
577 if ( !tempOutputFile.open() )
579 throw QgsException( u
"Could not open temporary file for the GetPrint request."_s );
587 if ( !mWmsParameters.dpi().isEmpty() )
590 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
592 exportSettings.
dpi = dpi;
605 atlasSvgExport.
exportToSvg( tempOutputFile.fileName(), exportSettings );
611 exporter.
exportToSvg( tempOutputFile.fileName(), exportSettings );
620 double dpi( layout->renderContext().dpi() );
621 if ( !mWmsParameters.dpi().isEmpty() )
624 double _dpi = mWmsParameters.dpi().toDouble( &ok );
628 exportSettings.
dpi = dpi;
634 QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );
639 const QSize imageSize = QSize(
static_cast<int>( width.
length() * dpi / 25.4 ),
static_cast<int>( height.
length() * dpi / 25.4 ) );
641 const QString paramWidth = mWmsParameters.width();
642 const QString paramHeight = mWmsParameters.height();
647 if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
649 exportSettings.
imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
651 else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
653 exportSettings.
imageSize = QSize( paramWidth.toInt(),
static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
655 else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
657 exportSettings.
imageSize = QSize(
static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
665 exportSettings.
pages.append( 0 );
673 atlasPngExport.
exportToImage( tempOutputFile.fileName(), exportSettings );
677 throw QgsServiceException( u
"Bad request"_s, u
"Atlas error: empty atlas."_s, QString(), 400 );
683 exporter.
exportToImage( tempOutputFile.fileName(), exportSettings );
691 if ( !mWmsParameters.dpi().isEmpty() )
694 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
696 exportSettings.
dpi = dpi;
701 exportSettings.
rasterizeWholeImage = layout->customProperty( u
"rasterize"_s,
false ).toBool();
703 QVector<qreal> requestMapScales = mWmsParameters.pdfPredefinedMapScales();
704 if ( requestMapScales.size() > 0 )
713 QStringList exportThemes = mWmsParameters.pdfExportMapThemes();
714 if ( exportThemes.size() > 0 )
718 exportSettings.
writeGeoPdf = mWmsParameters.writeGeospatialPdf();
724 if ( mWmsParameters.pdfLosslessImageCompression() )
728 if ( mWmsParameters.pdfDisableTiledRasterRendering() )
741 exporter.
exportToPdf( tempOutputFile.fileName(), exportSettings );
751 handlePrintErrors( atlas->
layout() );
755 handlePrintErrors( layout.get() );
758 return tempOutputFile.readAll();
765 QList<QgsLayoutItemMap *> maps;
771 for (
const auto &map : std::as_const( maps ) )
777 if ( cMapParams.
mLayers.isEmpty() )
782 if ( !atlas || !map->atlasDriven() )
788 c->removeLayoutItem( map );
797 QgsRectangle r( cMapParams.
mExtent );
805 if ( cMapParams.
mScale > 0 )
807 map->setScale(
static_cast<double>( cMapParams.
mScale ) );
813 map->setMapRotation( cMapParams.
mRotation );
817 if ( !map->keepLayerSet() )
819 QList<QgsMapLayer *> layerSet;
821 for (
const auto &layer : std::as_const( cMapParams.
mLayers ) )
823 if ( mContext.isValidGroup( layer.mNickname ) )
825 QList<QgsMapLayer *> layersFromGroup;
827 const QList<QgsMapLayer *> cLayersFromGroup = mContext.layersFromGroup( layer.mNickname );
828 for ( QgsMapLayer *layerFromGroup : cLayersFromGroup )
830 if ( !layerFromGroup )
835 layersFromGroup.push_front( layerFromGroup );
838 if ( !layersFromGroup.isEmpty() )
840 layerSet.append( layersFromGroup );
845 QgsMapLayer *mlayer = mContext.layer( layer.mNickname );
852 setLayerStyle( mlayer, layer.mStyle );
857 std::reverse( layerSet.begin(), layerSet.end() );
862 QMap<QString, QString> layersStyle;
863 if ( map->followVisibilityPreset() )
873 const QString presetName = map->followVisibilityPresetName();
874 if ( layerSet.isEmpty() )
877 const QgsExpressionContext ex { map->createExpressionContext() };
878 layerSet = map->layersToRender( &ex );
881 map->setFollowVisibilityPreset(
false );
885 for (
const auto &layerMapThemeRecord : std::as_const( mapThemeRecords ) )
887 if ( layerSet.contains( layerMapThemeRecord.layer() ) )
889 layersStyle.insert( layerMapThemeRecord.layer()->id(), layerMapThemeRecord.layer()->styleManager()->style( layerMapThemeRecord.currentStyle ).xmlData() );
895 const QList<QgsMapLayer *> highlights = highlightLayers( cMapParams.
mHighlightLayers );
896 for (
const auto &hl : std::as_const( highlights ) )
898 layerSet.prepend( hl );
901 map->setLayers( layerSet );
902 map->setKeepLayerSet(
true );
906 if ( !layersStyle.isEmpty() )
908 map->setLayerStyleOverrides( layersStyle );
909 map->setKeepLayerStyles(
true );
916 map->grid()->setIntervalX(
static_cast<double>( cMapParams.
mGridX ) );
917 map->grid()->setIntervalY(
static_cast<double>( cMapParams.
mGridY ) );
922 QList<QgsLayoutItemLabel *> labels;
923 c->layoutItems<QgsLayoutItemLabel>( labels );
924 for (
const auto &label : std::as_const( labels ) )
927 const QString labelId = label->id();
928 const QString labelParam = mWmsParameters.layoutParameter( labelId, ok );
933 if ( labelParam.isEmpty() )
937 c->removeItem( label );
942 label->setText( labelParam );
946 QList<QgsLayoutItemHtml *> htmls;
947 c->layoutObjects<QgsLayoutItemHtml>( htmls );
948 for (
const auto &html : std::as_const( htmls ) )
950 if ( html->frameCount() == 0 )
953 QgsLayoutFrame *htmlFrame = html->frame( 0 );
955 const QString htmlId = htmlFrame->
id();
956 const QString htmlValue = mWmsParameters.layoutParameter( htmlId, ok );
966 if ( htmlValue.isEmpty() )
968 c->removeMultiFrame( html );
975 QUrl newUrl( htmlValue );
976 html->setUrl( newUrl );
980 html->setHtml( htmlValue );
987 QList<QgsLayoutItemLegend *> legends;
988 c->layoutItems<QgsLayoutItemLegend>( legends );
989 for (
const auto &legend : std::as_const( legends ) )
991 switch ( legend->syncMode() )
998 const QgsLayoutItemMap *map = legend->linkedMap();
1007 QgsLegendModel *model = legend->model();
1008 QStringList layerSet;
1009 QList<QgsMapLayer *> mapLayers;
1010 if ( map->
layers().isEmpty() )
1014 mapLayers = mProject->mapLayers(
true ).values();
1018 mapLayers = map->
layers();
1020 const QList<QgsMapLayer *> layerList = mapLayers;
1021 for (
const auto &layer : layerList )
1022 layerSet << layer->id();
1025 QgsLayerTree *root = model->
rootGroup();
1032 for (
const auto &layerId : layerIds )
1034 QgsLayerTreeLayer *nodeLayer = root->
findLayer( layerId );
1039 if ( !layerSet.contains( layerId ) )
1041 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1045 QgsMapLayer *layer = nodeLayer->
layer();
1048 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1066 if ( !mContext.isValidWidthHeight() )
1071 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1077 std::unique_ptr<QgsWmsRestorer> restorer;
1078 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1081 QList<QgsMapLayer *> layers = mContext.layersToRender();
1088 std::unique_ptr<QPainter> painter;
1089 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
1092 configureMapSettings( image.get(), mapSettings );
1098 QPainter *renderedPainter = layersRendering( mapSettings, image.get() );
1099 if ( !renderedPainter )
1104 painter.reset( renderedPainter );
1107 annotationsRendering( painter.get(), mapSettings );
1113 QImage *scaledImage = scaleImage( image.get() );
1115 image.reset( scaledImage );
1118 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1128 QList<QgsMapLayer *> layers = mContext.layersToRender();
1132 const QStringList attributes = mWmsParameters.dxfLayerAttributes();
1133 QList<QgsDxfExport::DxfLayer> dxfLayers;
1145 int layerAttribute = -1;
1146 if ( attributes.size() > layerIdx )
1155 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1157 QString crs = mWmsParameters.crs();
1158 if ( crs.compare( u
"CRS:84"_s, Qt::CaseInsensitive ) == 0 )
1160 crs = u
"EPSG:4326"_s;
1163 else if ( crs.isEmpty() )
1165 crs = u
"EPSG:4326"_s;
1199 auto dxf = std::make_unique<QgsDxfExport>();
1200 dxf->setExtent( mapExtent );
1201 dxf->setDestinationCrs( outputCRS );
1202 dxf->addLayers( dxfLayers );
1203 dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
1204 dxf->setSymbologyExport( mWmsParameters.dxfMode() );
1207 dxf->setSymbologyScale( mWmsParameters.dxfScale() );
1210 dxf->setForce2d( mWmsParameters.isForce2D() );
1212 if ( mWmsParameters.noMText() )
1215 if ( mWmsParameters.exportLinesWithZeroWidth() )
1220 dxf->setFlags( flags );
1228 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1229 ms.
setLayers( mContext.layersToRender() );
1231 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1235 if ( mWmsParameters.pdfExportMetadata() )
1246 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1247 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, u
"PDF"_s,
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1248 if ( mWmsParameters.pdfAppendGeoreference() )
1250 pdf->setSaveWorldFile(
true );
1258 if ( i < 0 || i > mapSettings.
outputSize().width() )
1265 if ( j < 0 || j > mapSettings.
outputSize().height() )
1282 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1288 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1289 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1290 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1291 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1293 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1297 if ( mWmsParameters.j().isEmpty() )
1310 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1313 std::unique_ptr<QgsWmsRestorer> restorer;
1314 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1318 bool mandatoryCrsParam =
true;
1319 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1321 mandatoryCrsParam =
false;
1327 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1331 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1343#ifdef HAVE_SERVER_PYTHON_PLUGINS
1344 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1347 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1352 ba = convertFeatureInfoToText( result );
1354 ba = convertFeatureInfoToHtml( result );
1356 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1358 ba = result.toByteArray();
1363 QImage *QgsRenderer::createImage(
const QSize &size )
const
1365 std::unique_ptr<QImage> image;
1373 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1378 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1383 if ( image->isNull() )
1385 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1388 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1389 image->setDotsPerMeterX( dpm );
1390 image->setDotsPerMeterY( dpm );
1392 return image.release();
1395 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1399 throw QgsException( u
"configureMapSettings: no paint device"_s );
1402 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1405 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1408 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1409 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1414 QString crs = mWmsParameters.crs();
1415 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1417 crs = QString(
"EPSG:4326" );
1420 else if ( crs.isEmpty() && !mandatoryCrsParam )
1422 crs = QString(
"EPSG:4326" );
1425 QgsCoordinateReferenceSystem outputCRS;
1432 QgsWmsParameter parameter;
1434 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1445 throw QgsBadRequestException( code, parameter );
1454 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1462 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1468 bool transparent = mWmsParameters.transparentAsBool();
1469 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1476 else if ( backgroundColor.isValid() )
1482 QgsExpressionContext context = mProject->createExpressionContext();
1497 if ( mContext.settings().logProfile() )
1507 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1508 if ( !timeString.isEmpty() )
1510 bool isValidTemporalRange {
true };
1513 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1524 catch (
const QgsServerApiBadRequestException &ex )
1526 isValidTemporalRange =
false;
1531 if ( isValidTemporalRange )
1540 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1546 QgsDistanceArea distanceArea = QgsDistanceArea();
1547 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1553 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1555 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1557 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1559 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1561 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1563 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1565 int featureCount = mWmsParameters.featureCountAsInt();
1566 if ( featureCount < 1 )
1571 int i = mWmsParameters.iAsInt();
1572 int j = mWmsParameters.jAsInt();
1573 if ( xyDefined && !ijDefined )
1575 i = mWmsParameters.xAsInt();
1576 j = mWmsParameters.yAsInt();
1578 int width = mWmsParameters.widthAsInt();
1579 int height = mWmsParameters.heightAsInt();
1580 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1582 i *= ( outputImage->width() /
static_cast<double>( width ) );
1583 j *= ( outputImage->height() /
static_cast<double>( height ) );
1587 std::unique_ptr<QgsRectangle> featuresRect;
1588 std::unique_ptr<QgsGeometry> filterGeom;
1589 std::unique_ptr<QgsPointXY> infoPoint;
1591 if ( i != -1 && j != -1 )
1593 infoPoint = std::make_unique<QgsPointXY>();
1594 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1596 else if ( filtersDefined )
1598 featuresRect = std::make_unique<QgsRectangle>();
1601 if ( filterGeomDefined )
1603 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1606 QDomDocument result;
1607 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1608 result.appendChild( header );
1610 QDomElement getFeatureInfoElement;
1614 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1615 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1616 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1617 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1618 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1619 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1620 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1621 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1622 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 );
1627 if ( featureInfoElemName.isEmpty() )
1629 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1632 if ( featureInfoElemNs.isEmpty() )
1634 getFeatureInfoElement = result.createElement( featureInfoElemName );
1638 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1642 if ( !featureInfoSchema.isEmpty() )
1644 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1645 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1648 result.appendChild( getFeatureInfoElement );
1658 for (
const QString &queryLayer : queryLayers )
1660 bool validLayer =
false;
1661 bool queryableLayer =
true;
1662 for ( QgsMapLayer *layer : std::as_const( layers ) )
1664 if ( queryLayer == mContext.layerNickname( *layer ) )
1668 if ( !queryableLayer )
1673 QDomElement layerElement;
1676 layerElement = getFeatureInfoElement;
1680 layerElement = result.createElement( u
"Layer"_s );
1681 QString layerName = queryLayer;
1684 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1685 if ( layerAliasIt != layerAliasMap.constEnd() )
1687 layerName = layerAliasIt.value();
1690 layerElement.setAttribute( u
"name"_s, layerName );
1691 const QString layerTitle = layer->serverProperties()->title();
1692 if ( !layerTitle.isEmpty() )
1694 layerElement.setAttribute( u
"title"_s, layerTitle );
1698 layerElement.setAttribute( u
"title"_s, layerName );
1700 getFeatureInfoElement.appendChild( layerElement );
1703 layerElement.setAttribute( u
"id"_s, layer->id() );
1709 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1712 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1718 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1734 layerElement = result.createElement( u
"gml:featureMember"_s );
1735 getFeatureInfoElement.appendChild( layerElement );
1737 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1741 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1749 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1753 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1756 param.mValue = queryLayer;
1759 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1762 param.mValue = queryLayer;
1764 bool hasGroupAndQueryable {
false };
1765 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1768 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1769 for (
const QString &ql : constNicks )
1771 if ( mContext.layerGroups().contains( ql ) )
1773 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1774 for (
const QgsMapLayer *ml : constLayers )
1776 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1782 hasGroupAndQueryable =
true;
1791 if ( !hasGroupAndQueryable )
1798 if ( featuresRect && !featuresRect->isNull() )
1802 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1803 QDomElement boxElem;
1804 int gmlVersion = mWmsParameters.infoFormatVersion();
1805 if ( gmlVersion < 3 )
1817 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1819 bBoxElem.appendChild( boxElem );
1820 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1824 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1826 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1827 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1828 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1829 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1830 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1836 convertFeatureInfoToSia2045( result );
1842 bool QgsRenderer::featureInfoFromVectorLayer( QgsVectorLayer *layer,
const QgsPointXY *infoPoint,
int nFeatures, QDomDocument &infoDocument, QDomElement &layerElement,
const QgsMapSettings &mapSettings, QgsRenderContext &renderContext,
const QString &version, QgsRectangle *featureBBox, QgsGeometry *filterGeom )
const
1849 QgsFeatureRequest fReq;
1852 std::unique_ptr<QgsGeometry> layerFilterGeom;
1855 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1860 QgsRectangle mapRect = mapSettings.
extent();
1864 QgsRectangle searchRect;
1869 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1871 else if ( layerFilterGeom )
1873 searchRect = layerFilterGeom->boundingBox();
1875 else if ( !mWmsParameters.bbox().isEmpty() )
1877 searchRect = layerRect;
1883 QgsAttributes featureAttributes;
1884 int featureCounter = 0;
1886 const QgsFields fields = layer->
fields();
1903 if ( layerFilterGeom )
1905 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1909 mFeatureFilter.filterFeatures( layer, fReq );
1912#ifdef HAVE_SERVER_PYTHON_PLUGINS
1914 mContext.accessControl()->filterFeatures( layer, fReq );
1917 QStringList attributes;
1918 for (
const QgsField &field : fields )
1920 attributes.append( field.name() );
1922 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1926 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1930 r2->startRender( renderContext, layer->
fields() );
1933 bool featureBBoxInitialized =
false;
1942 if ( featureCounter > nFeatures )
1957 bool render = r2->willRenderFeature( feature, renderContext );
1970 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1973 featureBBoxInitialized =
true;
1982 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
1991 int gmlVersion = mWmsParameters.infoFormatVersion();
1992 QString typeName = mContext.layerNickname( *layer );
1993 QDomElement elem = createFeatureGML(
1994 &feature, layer, infoDocument, outputCrs, mapSettings, typeName, withGeom, gmlVersion
1995#ifdef HAVE_SERVER_PYTHON_PLUGINS
2000 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2001 featureMemberElem.appendChild( elem );
2002 layerElement.appendChild( featureMemberElem );
2007 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2009 layerElement.appendChild( featureElement );
2015 writeAttributesTabLayout( editConfig, layer, fields, featureAttributes, infoDocument, featureElement, renderContext
2016#ifdef HAVE_SERVER_PYTHON_PLUGINS
2024 for (
int i = 0; i < featureAttributes.count(); ++i )
2026 writeVectorLayerAttribute( i, layer, fields, featureAttributes, infoDocument, featureElement, renderContext
2027#ifdef HAVE_SERVER_PYTHON_PLUGINS
2039 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2040 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2044 featureElement.appendChild( maptipElem );
2048 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2050 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2051 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2054 displayExpression.
prepare( &context );
2055 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2056 featureElement.appendChild( displayElem );
2062 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2063 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2068 featureElement.appendChild( bBoxElem );
2074 QgsGeometry geom = feature.
geometry();
2077 if ( layer->
crs() != outputCrs )
2079 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2084 if ( segmentizeWktGeometry )
2086 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2091 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2092 geom.
set( segmentizedGeom );
2096 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2097 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2098 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2099 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2100 featureElement.appendChild( geometryElement );
2107 r2->stopRender( renderContext );
2113 void QgsRenderer::writeAttributesTabGroup(
const QgsAttributeEditorElement *group, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &parentElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2115 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2118 QString groupName = container->
name();
2119 QDomElement nameElem;
2121 if ( !groupName.isEmpty() )
2123 nameElem = doc.createElement( groupName );
2124 parentElem.appendChild( nameElem );
2127 const QList<QgsAttributeEditorElement *> children = container->
children();
2128 for (
const QgsAttributeEditorElement *child : children )
2132 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2136 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2142 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2150 void QgsRenderer::writeAttributesTabLayout( QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2153 if ( !editorContainer )
2158 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2161 void QgsRenderer::writeVectorLayerAttribute(
int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes )
const
2163#ifndef HAVE_SERVER_PYTHON_PLUGINS
2164 Q_UNUSED( attributes );
2177#ifdef HAVE_SERVER_PYTHON_PLUGINS
2179 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2186 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2187 attributeElement.setAttribute( u
"name"_s, attributeName );
2190 featureElem.appendChild( attributeElement );
2193 bool QgsRenderer::featureInfoFromMeshLayer( QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version )
const
2196 Q_UNUSED( mapSettings )
2205 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2207 QList<QgsMeshDatasetIndex> datasetIndexList;
2216 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2218 if ( activeScalarGroup >= 0 )
2220 QgsMeshDatasetIndex indice;
2222 datasetIndexList.append( indice );
2225 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2228 for (
int groupIndex : allGroup )
2230 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2236 if ( activeScalarGroup >= 0 )
2238 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2241 for (
int groupIndex : allGroup )
2243 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2246 datasetIndexList.append( groupIndex );
2253 double scalarDoubleValue = 0.0;
2255 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2257 if ( !index.isValid() )
2261 QMap<QString, QString> derivedAttributes;
2263 QMap<QString, QString> attribute;
2267 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2268 scalarDoubleValue = scalarValue.
scalar();
2269 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2274 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2275 const double vectorX = vectorValue.
x();
2276 const double vectorY = vectorValue.
y();
2277 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2279 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2283 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2284 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2285 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2292 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2293 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2295 const QString resultName = groupMeta.
name();
2297 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2298 attributeElement.setAttribute( u
"name"_s, resultName );
2303 value = QString::number( scalarDoubleValue );
2306 attributeElement.setAttribute( u
"value"_s, value );
2307 layerElement.appendChild( attributeElement );
2311 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2312 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2315 value = range.
begin().toString( dateFormat );
2319 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2321 attributeElementTime.setAttribute( u
"value"_s, value );
2322 layerElement.appendChild( attributeElementTime );
2328 bool QgsRenderer::featureInfoFromRasterLayer( QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version )
const
2350 QgsRasterIdentifyResult identifyResult;
2353 const QgsRectangle extent { mapSettings.
extent() };
2366 if ( !identifyResult.
isValid() )
2369 QMap<int, QVariant> attributes = identifyResult.
results();
2375 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2376 int gmlVersion = mWmsParameters.infoFormatVersion();
2377 QString typeName = mContext.layerNickname( *layer );
2383 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2385 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2386 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2389 QDomElement elem = createFeatureGML(
2390 &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr
2392 layerElement.appendChild( elem );
2396 const auto values = identifyResult.
results();
2397 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2399 QVariant value = it.value();
2400 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2406 if ( value.userType() == QMetaType::Type::QString )
2414 for (
const QgsFeatureStore &featureStore : featureStoreList )
2417 for (
const QgsFeature &feature : storeFeatures )
2419 QDomElement elem = createFeatureGML(
2420 &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr
2422 layerElement.appendChild( elem );
2432 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2434 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2435 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2440 value = QString::number( it.value().toDouble() );
2443 attributeElement.setAttribute( u
"value"_s, value );
2444 layerElement.appendChild( attributeElement );
2449 const auto values = identifyResult.
results();
2450 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2452 QVariant value = it.value();
2453 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2459 if ( value.userType() == QMetaType::Type::QString )
2466 for (
const QgsFeatureStore &featureStore : featureStoreList )
2469 for (
const QgsFeature &feature : storeFeatures )
2471 for (
const auto &fld : feature.
fields() )
2473 const auto val { feature.
attribute( fld.name() ) };
2474 if ( val.isValid() )
2476 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2477 attributeElement.setAttribute( u
"name"_s, fld.name() );
2478 attributeElement.setAttribute( u
"value"_s, val.toString() );
2479 layerElement.appendChild( attributeElement );
2490 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2491 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2494 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2497 layerElement.appendChild( maptipElem );
2503 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2506 if ( filter.contains(
";"_L1 ) )
2511 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2512 groupStringList( tokens, u
"'"_s );
2513 groupStringList( tokens, u
"\""_s );
2515 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2518 if ( tokenIt->compare(
','_L1 ) == 0
2519 || tokenIt->compare(
'('_L1 ) == 0
2520 || tokenIt->compare(
')'_L1 ) == 0
2521 || tokenIt->compare(
'='_L1 ) == 0
2522 || tokenIt->compare(
"!="_L1 ) == 0
2523 || tokenIt->compare(
'<'_L1 ) == 0
2524 || tokenIt->compare(
"<="_L1 ) == 0
2525 || tokenIt->compare(
'>'_L1 ) == 0
2526 || tokenIt->compare(
">="_L1 ) == 0
2527 || tokenIt->compare(
'%'_L1 ) == 0
2528 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2529 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2530 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2531 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2532 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2533 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2534 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2535 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2536 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2537 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2538 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2545 ( void ) tokenIt->toDouble( &isNumeric );
2554 if ( *tokenIt ==
"''"_L1 )
2560 if ( tokenIt->size() > 2
2561 && ( *tokenIt )[0] == QChar(
'\'' )
2562 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2563 && ( *tokenIt )[1] != QChar(
'\'' )
2564 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2570 if ( tokenIt->size() > 2
2571 && ( *tokenIt )[0] == QChar(
'"' )
2572 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' )
2573 && ( *tokenIt )[1] != QChar(
'"' )
2574 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2585 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2588 bool groupActive =
false;
2589 int startGroup = -1;
2590 QString concatString;
2592 for (
int i = 0; i < list.size(); ++i )
2594 QString &str = list[i];
2595 if ( str.startsWith( groupString ) )
2599 concatString.clear();
2604 if ( i != startGroup )
2606 concatString.append(
" " );
2608 concatString.append( str );
2611 if ( str.endsWith( groupString ) )
2614 groupActive =
false;
2616 if ( startGroup != -1 )
2618 list[startGroup] = concatString;
2619 for (
int j = startGroup + 1; j <= endGroup; ++j )
2621 list.removeAt( startGroup + 1 );
2626 concatString.clear();
2632 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2634 QDomDocument SIAInfoDoc;
2635 QDomElement infoDocElement = doc.documentElement();
2636 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2637 SIAInfoDoc.appendChild( SIAInfoDocElement );
2639 QString currentAttributeName;
2640 QString currentAttributeValue;
2641 QDomElement currentAttributeElem;
2642 QString currentLayerName;
2643 QDomElement currentLayerElem;
2644 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2645 for (
int i = 0; i < layerNodeList.size(); ++i )
2647 currentLayerElem = layerNodeList.at( i ).toElement();
2648 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2650 QDomElement currentFeatureElem;
2652 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2653 if ( featureList.isEmpty() )
2656 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2657 QDomElement rasterLayerElem;
2658 if ( !attributeList.isEmpty() )
2660 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2662 for (
int j = 0; j < attributeList.size(); ++j )
2664 currentAttributeElem = attributeList.at( j ).toElement();
2665 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2666 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2667 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2668 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2669 outAttributeElem.appendChild( outAttributeText );
2670 rasterLayerElem.appendChild( outAttributeElem );
2672 if ( !attributeList.isEmpty() )
2674 SIAInfoDocElement.appendChild( rasterLayerElem );
2680 QSet<QString> layerPropertyAttributes;
2681 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2682 if ( !currentLayerId.isEmpty() )
2684 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2687 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2688 if ( !WMSPropertyAttributesString.isEmpty() )
2690 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2691 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2693 layerPropertyAttributes.insert( *propertyIt );
2699 QDomElement propertyRefChild;
2700 for (
int j = 0; j < featureList.size(); ++j )
2702 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2703 currentFeatureElem = featureList.at( j ).toElement();
2704 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2706 for (
int k = 0; k < attributeList.size(); ++k )
2708 currentAttributeElem = attributeList.at( k ).toElement();
2709 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2710 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2711 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2713 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2714 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2715 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2716 identifierElem.appendChild( identifierText );
2717 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2718 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2719 valueElem.appendChild( valueText );
2720 propertyElem.appendChild( identifierElem );
2721 propertyElem.appendChild( valueElem );
2722 if ( propertyRefChild.isNull() )
2724 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2725 propertyRefChild = propertyElem;
2729 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2734 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2735 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2736 SIAAttributeElem.appendChild( SIAAttributeText );
2737 SIAFeatureElem.appendChild( SIAAttributeElem );
2740 SIAInfoDocElement.appendChild( SIAFeatureElem );
2747 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2750 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2753 featureInfoString.append( QStringLiteral( R
"HTML(
2756 <title>Information</title>
2757 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2760 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2767 border: 1px solid black;
2768 border-collapse: collapse;
2789 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2792 for (
int i = 0; i < layerList.size(); ++i )
2794 const QDomElement layerElem = layerList.at( i ).toElement();
2797 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2798 const QDomElement currentFeatureElement;
2800 if ( !featureNodeList.isEmpty() )
2804 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2805 featureInfoString.append( featureInfoLayerTitleString );
2808 for (
int j = 0; j < featureNodeList.size(); ++j )
2810 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2813 featureInfoString.append( QStringLiteral( R
"HTML(
2818 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2819 for (
int k = 0; k < attributeNodeList.size(); ++k )
2821 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2822 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2823 QString value = attributeElement.attribute( u
"value"_s );
2824 if ( name !=
"maptip"_L1 )
2826 value = value.toHtmlEscaped();
2831 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2836 .arg( name, value );
2838 featureInfoString.append( featureInfoAttributeString );
2840 else if ( name ==
"maptip"_L1 )
2842 featureInfoString.append( QStringLiteral( R
"HTML(
2850 featureInfoString.append( QStringLiteral( R
"HTML(
2857 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2860 if ( !attributeNodeList.isEmpty() )
2864 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2865 featureInfoString.append( featureInfoLayerTitleString );
2867 featureInfoString.append( QStringLiteral( R
"HTML(
2871 for (
int j = 0; j < attributeNodeList.size(); ++j )
2873 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2874 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2875 QString value = attributeElement.attribute( u
"value"_s );
2876 if ( value.isEmpty() )
2878 value = u
"no data"_s;
2880 if ( name !=
"maptip"_L1 )
2882 value = value.toHtmlEscaped();
2887 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2892 .arg( name, value );
2895 featureInfoString.append( featureInfoAttributeString );
2897 else if ( name ==
"maptip"_L1 )
2899 featureInfoString.append( QStringLiteral( R
"HTML(
2907 featureInfoString.append( QStringLiteral( R
"HTML(
2917 featureInfoString.append( QStringLiteral( R
"HTML(
2921 return featureInfoString.toUtf8();
2924 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2926 QString featureInfoString;
2929 featureInfoString.append(
"GetFeatureInfo results\n" );
2930 featureInfoString.append(
"\n" );
2932 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2935 for (
int i = 0; i < layerList.size(); ++i )
2937 QDomElement layerElem = layerList.at( i ).toElement();
2939 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2942 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2943 QDomElement currentFeatureElement;
2945 if ( !featureNodeList.isEmpty() )
2947 for (
int j = 0; j < featureNodeList.size(); ++j )
2949 QDomElement featureElement = featureNodeList.at( j ).toElement();
2950 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
2953 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2954 for (
int k = 0; k < attributeNodeList.size(); ++k )
2956 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2957 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
2963 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2964 for (
int j = 0; j < attributeNodeList.size(); ++j )
2966 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2967 QString value = attributeElement.attribute( u
"value"_s );
2968 if ( value.isEmpty() )
2970 value = u
"no data"_s;
2972 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
2976 featureInfoString.append(
"\n" );
2979 return featureInfoString.toUtf8();
2982 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
2985 {
"type",
"FeatureCollection" },
2986 {
"features", json::array() },
2989 const bool withDisplayName = mWmsParameters.withDisplayName();
2991 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2992 for (
int i = 0; i < layerList.size(); ++i )
2994 const QDomElement layerElem = layerList.at( i ).toElement();
2995 const QString layerName = layerElem.attribute( u
"name"_s );
2997 QgsMapLayer *layer =
nullptr;
2998 for ( QgsMapLayer *l : layers )
3000 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3011 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3016 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3017 if ( featuresNode.isEmpty() )
3020 QMap<QgsFeatureId, QString> fidMap;
3021 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3023 for (
int j = 0; j < featuresNode.size(); ++j )
3025 const QDomElement featureNode = featuresNode.at( j ).toElement();
3026 const QString fid = featureNode.attribute( u
"id"_s );
3029 if ( expression.isEmpty() )
3031 feature = vl->
getFeature( fid.toLongLong() );
3035 QgsFeatureRequest request { QgsExpression( expression ) };
3040 fidMap.insert( feature.
id(), fid );
3045 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3046 for (
int k = 0; k < attrs.count(); k++ )
3048 const QDomElement elm = attrs.at( k ).toElement();
3049 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3051 wkt = elm.attribute(
"value" );
3056 if ( !wkt.isEmpty() )
3064 if ( withDisplayName )
3066 QString displayName;
3067 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3068 for (
int k = 0; k < attrs.count(); k++ )
3070 const QDomElement elm = attrs.at( k ).toElement();
3071 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3073 displayName = elm.attribute(
"value" );
3077 fidDisplayNameMap.insert( feature.
id(), displayName );
3080 features << feature;
3083 if ( !attributes.isEmpty() )
3086 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3087 for (
int k = 0; k < attributesNode.size(); ++k )
3089 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3090 const QString fieldName = attributeElement.attribute( u
"name"_s );
3091 attributes << feature.fieldNameIndex( fieldName );
3096 QgsJsonExporter exporter( vl );
3097 exporter.setAttributeDisplayName(
true );
3098 exporter.setAttributes( attributes );
3099 exporter.setIncludeGeometry( withGeometry );
3100 exporter.setTransformGeometries(
false );
3104 for (
const auto &feature : std::as_const( features ) )
3106 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3107 QVariantMap extraProperties;
3108 if ( withDisplayName )
3110 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3112 json[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id ) );
3117 auto properties = json::object();
3118 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3119 for (
int j = 0; j < attributesNode.size(); ++j )
3121 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3122 const QString name = attrElmt.attribute( u
"name"_s );
3124 QString value = attrElmt.attribute( u
"value"_s );
3125 if ( value.isEmpty() )
3130 properties[name.toStdString()] = value.toStdString();
3133 json[
"features"].push_back(
3134 { {
"type",
"Feature" },
3135 {
"id", layerName.toStdString() },
3136 {
"properties", properties }
3143 return QByteArray::fromStdString( json.dump( 2 ) );
3145 return QByteArray::fromStdString( json.dump() );
3149 QDomElement QgsRenderer::createFeatureGML(
3150 const QgsFeature *feat,
3151 QgsVectorLayer *layer,
3153 QgsCoordinateReferenceSystem &crs,
3154 const QgsMapSettings &mapSettings,
3155 const QString &typeName,
3158 QStringList *attributes
3162 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3169 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3171 QgsCoordinateTransform transform;
3172 if ( layer && layer->
crs() != crs )
3177 QgsGeometry geom = feat->
geometry();
3179 QgsExpressionContext expressionContext;
3186 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3200 catch ( QgsCsException &e )
3206 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3207 QDomElement boxElem;
3219 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3221 bbElem.appendChild( boxElem );
3222 typeNameElement.appendChild( bbElem );
3226 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3227 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3228 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3231 const QList<QgsAttributeEditorElement *> children = container->
children();
3232 for (
const QgsAttributeEditorElement *child : children )
3234 switch ( child->type() )
3238 if ( findAttributeInTree( attributeName, child ) )
3246 if ( child->name() == attributeName )
3254 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3255 if ( relationEditor )
3257 const QgsRelation &relation { relationEditor->
relation() };
3261 for (
const auto &idx : std::as_const( referencedFields ) )
3263 const QgsField f { layer->
fields().
at( idx ) };
3264 if ( f.
name() == attributeName )
3273 for (
const auto &idx : std::as_const( referencingFields ) )
3275 const QgsField f { layer->
fields().
at( idx ) };
3276 if ( f.
name() == attributeName )
3293 if ( withGeom && !geom.
isNull() )
3302 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3303 QDomElement gmlElem;
3313 if ( !gmlElem.isNull() )
3317 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3319 geomElem.appendChild( gmlElem );
3320 typeNameElement.appendChild( geomElem );
3325 QgsAttributes featureAttributes = feat->
attributes();
3326 QgsFields fields = feat->
fields();
3327 for (
int i = 0; i < fields.
count(); ++i )
3329 QString attributeName = fields.
at( i ).
name();
3336 if ( attributes && !attributes->contains( attributeName ) )
3341 if ( honorFormConfig )
3344 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3350 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3351 QString fieldTextString = featureAttributes.at( i ).toString();
3356 QDomText fieldText = doc.createTextNode( fieldTextString );
3357 fieldElem.appendChild( fieldText );
3358 typeNameElement.appendChild( fieldElem );
3369 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3370 QDomText maptipText = doc.createTextNode( fieldTextString );
3371 fieldElem.appendChild( maptipText );
3372 typeNameElement.appendChild( fieldElem );
3376 return typeNameElement;
3379 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3383 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3385 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3387 value = value.mid( 1, value.size() - 2 );
3392 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3396 return QgsRectangle();
3399 double mapUnitTolerance = 0.0;
3402 if ( !mWmsParameters.polygonTolerance().isEmpty()
3403 && mWmsParameters.polygonToleranceAsInt() > 0 )
3409 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3414 if ( !mWmsParameters.lineTolerance().isEmpty()
3415 && mWmsParameters.lineToleranceAsInt() > 0 )
3421 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3426 if ( !mWmsParameters.pointTolerance().isEmpty()
3427 && mWmsParameters.pointToleranceAsInt() > 0 )
3433 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3440 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3444 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3446 QList<QgsMapLayer *> highlightLayers;
3449 QString crs = mWmsParameters.crs();
3450 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3453 QDomDocument sldDoc;
3457 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3464 std::unique_ptr<QgsFeatureRenderer> renderer;
3465 QDomElement el = sldDoc.documentElement();
3475 QString url = typeName +
"?crs=" + crs;
3476 if ( !param.mLabel.isEmpty() )
3478 url +=
"&field=label:string";
3483 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3490 QgsFeature fet( layer->
fields() );
3491 if ( !param.mLabel.isEmpty() )
3493 fet.setAttribute( 0, param.mLabel );
3496 QgsPalLayerSettings palSettings;
3501 palSettings.
dist = param.mLabelDistance;
3510 switch ( param.mGeom.type() )
3521 QgsPointXY pt = param.mGeom.asPoint();
3523 QVariant x( pt.
x() );
3526 QVariant y( pt.
y() );
3538 QgsGeometry point = param.mGeom.pointOnSurface();
3539 QgsPointXY pt = point.
asPoint();
3543 QVariant x( pt.
x() );
3547 QVariant y( pt.
y() );
3551 QVariant hali(
"Center" );
3555 QVariant vali(
"Half" );
3567 QgsTextFormat textFormat;
3568 QgsTextBufferSettings bufferSettings;
3570 if ( param.mColor.isValid() )
3572 textFormat.
setColor( param.mColor );
3575 if ( param.mSize > 0 )
3577 textFormat.
setSize( param.mSize );
3585 if ( !param.mFont.isEmpty() )
3587 textFormat.
setFont( param.mFont );
3590 if ( param.mBufferColor.isValid() )
3592 bufferSettings.
setColor( param.mBufferColor );
3595 if ( param.mBufferSize > 0 )
3598 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3604 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3608 fet.setGeometry( param.mGeom );
3617 highlightLayers.append( layer.release() );
3621 mTemporaryLayers.append( highlightLayers );
3622 return highlightLayers;
3625 void QgsRenderer::removeTemporaryLayers()
3627 qDeleteAll( mTemporaryLayers );
3628 mTemporaryLayers.clear();
3631 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3633 QPainter *painter =
nullptr;
3635 QgsFeatureFilterProviderGroup filters;
3637#ifdef HAVE_SERVER_PYTHON_PLUGINS
3638 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3641 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3643 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3644 painter = renderJob.takePainter();
3646 logRenderingErrors( renderJob.errors() );
3648 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3650 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3652 QString layerWMSName;
3653 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3656 layerWMSName = mContext.layerNickname( *errorLayer );
3659 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3660 if ( !layerWMSName.isEmpty() )
3662 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3664 throw QgsException( errorMessage );
3670 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3672 if ( opacity >= 0 && opacity <= 255 )
3674 switch ( layer->
type() )
3678 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3683 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3691 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3692 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3693 rasterRenderer->
setOpacity( opacity / 255. );
3699 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3715 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3719 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3720 QStringList expList;
3721 for (
const QgsWmsParametersFilter &filter : filters )
3726 QDomDocument filterXml;
3728#if QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 )
3730 if ( !filterXml.setContent( filter.mFilter,
true, &errorMsg ) )
3735 QXmlStreamReader xmlReader( filter.mFilter );
3736 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3737 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3738 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3740 throw QgsBadRequestException(
QgsServiceException::QGIS_InvalidParameterValue, u
"Filter string rejected. Error %1:%2 : %3. The XML string was: %4"_s.arg( QString::number( result.errorLine ), QString::number( result.errorColumn ), result.errorMessage, filter.mFilter ) );
3743 QDomElement filterElem = filterXml.firstChildElement();
3748 expList << filterExp->dump();
3754 if ( !testFilterStringSafety( filter.mFilter ) )
3756 throw QgsSecurityException( QStringLiteral(
"The filter string %1"
3757 " has been rejected because of security reasons."
3758 " Note: Text strings have to be enclosed in single or double quotes."
3759 " A space between each word / special character is mandatory."
3760 " Allowed Keywords and special characters are"
3761 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3762 " Not allowed are semicolons in the filter expression." )
3764 filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' )
3768 QString newSubsetString = filter.mFilter;
3771 newSubsetString.prepend(
") AND (" );
3772 newSubsetString.append(
")" );
3773 newSubsetString.prepend( filteredLayer->
subsetString() );
3774 newSubsetString.prepend(
"(" );
3784 expList.append( dimensionFilter( filteredLayer ) );
3788 if ( expList.size() == 1 )
3792 else if ( expList.size() > 1 )
3794 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3796 if ( !exp.isEmpty() )
3798 auto expression = std::make_unique<QgsExpression>( exp );
3802 mFeatureFilter.setFilter( filteredLayer, *expression );
3809 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3811 QStringList expList;
3813 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3814 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3815 if ( wmsDims.isEmpty() )
3820 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3821 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3830 if ( fieldIndex == -1 )
3835 int endFieldIndex = -1;
3836 if ( !dim.endFieldName.isEmpty() )
3838 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3839 if ( endFieldIndex == -1 )
3845 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3849 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::AllValues )
3853 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
3855 defValue = dim.referenceValue;
3860 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3861 if ( endFieldIndex != -1 )
3863 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3866 QList<QVariant> values = qgis::setToList( uniqueValues );
3867 std::sort( values.begin(), values.end() );
3868 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
3870 defValue = values.first();
3872 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
3874 defValue = values.last();
3878 if ( endFieldIndex == -1 )
3884 QStringList expElems;
3889 expList << expElems.join(
' ' );
3895 QgsField dimField = layer->
fields().
at( fieldIndex );
3897 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3899 QStringList dimExplist;
3901 QStringList dimValues = dimParamValue.split(
',' );
3902 for (
int i = 0; i < dimValues.size(); ++i )
3904 QString dimValue = dimValues[i];
3906 if ( dimValue.size() > 1 )
3908 dimValue = dimValue.trimmed();
3911 if ( dimValue.contains(
'/' ) )
3913 QStringList rangeValues = dimValue.split(
'/' );
3915 if ( rangeValues.size() != 2 )
3920 QVariant rangeMin = QVariant( rangeValues[0] );
3921 QVariant rangeMax = QVariant( rangeValues[1] );
3932 QStringList expElems;
3933 if ( endFieldIndex == -1 )
3955 dimExplist << expElems.join(
' ' );
3959 QVariant dimVariant = QVariant( dimValue );
3965 if ( endFieldIndex == -1 )
3974 QStringList expElems;
3979 dimExplist << expElems.join(
' ' );
3984 if ( dimExplist.size() == 1 )
3986 expList << dimExplist;
3988 else if ( dimExplist.size() > 1 )
3990 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
3997 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4001 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4003 QgsFeatureRequest request;
4007 if ( selectedIds.empty() )
4018 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4020#ifdef HAVE_SERVER_PYTHON_PLUGINS
4027 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4030 QgsRectangle mapExtent = mapSettings.
extent();
4038 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4040 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4041 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4045 renderContext.
setFeedback( mContext.socketFeedback() );
4047 for ( QgsAnnotation *annotation : annotations )
4049 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4051 if ( !annotation || !annotation->isVisible() )
4057 if ( annotation->hasFixedMapPosition() )
4059 QgsPointXY mapPos = annotation->mapPosition();
4060 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4065 mapPos = coordTransform.transform( mapPos );
4067 catch (
const QgsCsException &e )
4073 offsetX = devicePos.
x();
4074 offsetY = devicePos.
y();
4078 const QPointF relativePos = annotation->relativePosition();
4079 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4080 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4084 painter->translate( offsetX, offsetY );
4085 annotation->render( renderContext );
4090 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4095 QImage *scaledImage =
nullptr;
4096 const int width = mWmsParameters.widthAsInt();
4097 const int height = mWmsParameters.heightAsInt();
4098 if ( width != image->width() || height != image->height() )
4100 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4108 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4109 for ( ; it != errors.constEnd(); ++it )
4111 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4112 if ( !it->layerID.isEmpty() )
4114 msg += QString(
" in layer %1" ).arg( it->layerID );
4120 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4127 QList<QgsLayoutItemMap *> mapList;
4131 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4132 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4134 logRenderingErrors( ( *mapIt )->renderingErrors() );
4137 if ( mContext.settings().ignoreRenderingErrors() )
4142 mapIt = mapList.constBegin();
4143 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4145 if ( !( *mapIt )->renderingErrors().isEmpty() )
4147 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4148 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4155 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4157 for (
auto layer : layers )
4159 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4161 if ( !mContext.layersToRender().contains( layer ) )
4166 if ( mContext.isExternalLayer( param.mNickname ) )
4170 setLayerOpacity( layer, param.mOpacity );
4177 setLayerSld( layer, mContext.sld( *layer ) );
4181 setLayerStyle( layer, mContext.style( *layer ) );
4186 setLayerOpacity( layer, param.mOpacity );
4191 setLayerFilter( layer, param.mFilter );
4196 setLayerAccessControlFilter( layer );
4201 setLayerSelection( layer, param.mSelection );
4204 if ( settings && mContext.updateExtent() )
4206 updateExtent( layer, *settings );
4212 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4216 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4218 if ( style.isEmpty() )
4230 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4235 QString sldStyleName =
"__sld_style";
4236 while ( styles.contains( sldStyleName ) )
4238 sldStyleName.append(
'@' );
4246 QgsLegendSettings QgsRenderer::legendSettings()
4249 QgsLegendSettings settings = mWmsParameters.legendSettings();
4251 if ( !mWmsParameters.bbox().isEmpty() )
4253 QgsMapSettings mapSettings;
4255 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4256 configureMapSettings( tmp.get(), mapSettings );
static QString version()
Version string.
@ MapOrientation
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
@ AboveLine
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
@ Millimeters
Millimeters.
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ VisibleLayers
Synchronize to map layers. The legend will include layers which are included in the linked map only.
@ AllProjectLayers
Synchronize to all project layers.
@ Manual
No automatic synchronization of legend layers. The legend will be manually populated.
@ DragAndDrop
"Drag and drop" layout. Needs to be configured.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ NoFlags
No flags are set.
@ Warning
Warning message.
@ Critical
Critical/error message.
@ Info
Information message.
QFlags< LabelLinePlacementFlag > LabelLinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
@ ShowRuleDetails
If set, the rule expression of a rule based renderer legend item will be added to the JSON.
@ IdentifyValue
Numerical values.
@ IdentifyFeature
WMS GML -> feature.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Use antialiasing while drawing.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
static const double DEFAULT_SEARCH_RADIUS_MM
Identify search radius in mm.
QFlags< LegendJsonRenderFlag > LegendJsonRenderFlags
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
RasterIdentifyFormat
Raster identify formats.
@ Feature
WMS GML/JSON -> feature.
@ Value
Numerical pixel value.
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
@ AllowOverlapIfRequired
Avoids overlapping labels when possible, but permit overlaps if labels for features cannot otherwise ...
@ Reverse
Reverse/inverse transform (from destination to source).
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ RecordProfile
Enable run-time profiling while rendering.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ DisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ DrawSelection
Draw selection.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
QList< QgsAnnotation * > annotations() const
Returns a list of all annotations contained in the manager.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QString name() const
Returns the name of this element.
const QgsRelation & relation() const
Gets the id of the relation which shall be embedded.
Exception thrown in case of malformed requests.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Qgis::DistanceUnit mapUnits
bool hasAxisInverted() const
Returns whether the axis order is inverted for the CRS compared to the order east/north (longitude/la...
A server filter to apply a dimension filter to a request.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
@ FlagHairlineWidthExport
@ FlagNoMText
Export text as TEXT elements. If not set, text will be exported as MTEXT elements.
Defines a QGIS exception class.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
QString expression() const
Returns the original, unmodified expression string.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString replaceExpressionText(const QString &action, const QgsExpressionContext *context, const QgsDistanceArea *distanceArea=nullptr)
This function replaces each expression between [% and %] in the string with the result of its evaluat...
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
QVariant evaluate()
Evaluate the feature and return the result.
bool isValid() const
Checks if this expression is valid.
A filter filter provider grouping several filter providers.
QgsFeatureFilterProviderGroup & addProvider(const QgsFeatureFilterProvider *provider)
Add another filter provider to the group.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
static QgsFeatureRenderer * loadSld(const QDomNode &node, Qgis::GeometryType geomType, QString &errorMessage)
Create a new renderer according to the information contained in the UserStyle element of a SLD style ...
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
Qgis::FeatureRequestFlags flags() const
Returns the flags which affect how features are fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Qgis::FieldConfigurationFlags configurationFlags
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
static void addCrsInfo(json &value, const QgsCoordinateReferenceSystem &crs)
Add crs information entry in json object regarding old GeoJSON specification format if it differs fro...
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
void removeChildrenGroupWithoutLayers()
Remove all child group nodes without layers.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
@ RuleKey
Rule key of the node (QString).
virtual QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const
Draws symbol on the left side of the item.
A model representing the layer tree, including layers and groups of layers.
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
QgsLayerTreeModelLegendNode * findLegendNode(const QString &layerId, const QString &ruleKey) const
Searches through the layer tree to find a legend node with a matching layer ID and rule key.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
bool beginRender() override
Called when rendering begins, before iteration commences.
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
bool first()
Seeks to the first feature, returning false if no feature was found.
QgsLayout * layout() override
Returns the layout associated with the iterator.
bool enabled() const
Returns whether the atlas generation is enabled.
int count() const override
Returns the number of features to iterate over.
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
Handles rendering and exports of layouts to various formats.
ExportResult exportToSvg(const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings)
Exports the layout as an SVG to the filePath, using the specified export settings.
ExportResult exportToImage(const QString &filePath, const QgsLayoutExporter::ImageExportSettings &settings)
Exports the layout to the filePath, using the specified export settings.
ExportResult exportToPdf(const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings)
Exports the layout as a PDF to the filePath, using the specified export settings.
@ ManualHtml
HTML content is manually set for the item.
@ Url
Using this mode item fetches its content via a url.
Layout graphical items for displaying a map.
double scale() const
Returns the map scale.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
QString id() const
Returns the item's ID name.
Manages storage of a set of layouts.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
double length() const
Returns the length of the measurement.
int pageCount() const
Returns the number of pages in the collection.
Stores information relating to the current rendering settings for a layout.
void setFeatureFilterProvider(QgsFeatureFilterProvider *featureFilterProvider)
Sets feature filter provider to featureFilterProvider.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
static QVector< double > predefinedScales(const QgsLayout *layout)
Returns a list of predefined scales associated with a layout.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Handles automatic layout and rendering of legends.
QSizeF minimumSize(QgsRenderContext *renderContext=nullptr)
Runs the layout algorithm and returns the minimum size required for the legend.
QJsonObject exportLegendToJson(const QgsRenderContext &context)
Renders the legend in a json object.
Q_DECL_DEPRECATED void drawLegend(QPainter *painter)
Draws the legend with given painter.
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
Q_DECL_DEPRECATED void setMapScale(double scale)
Sets the legend map scale.
Q_DECL_DEPRECATED void setMapUnitsPerPixel(double mapUnitsPerPixel)
Sets the mmPerMapUnit calculated by mapUnitsPerPixel mostly taken from the map settings.
void setJsonRenderFlags(const Qgis::LegendJsonRenderFlags &jsonRenderFlags)
Sets the JSON export flags to jsonRenderFlags.
void setWmsLegendSize(QSizeF s)
Sets the desired size (in millimeters) of WMS legend graphics shown in the legend.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual bool readSld(const QDomNode &node, QString &errorMessage)
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QList< QgsMapRendererJob::Error > Errors
Contains configuration for rendering maps.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QColor selectionColor() const
Returns the color that is used for drawing of selected vector features.
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QList< QgsMapThemeCollection::MapThemeLayerRecord > layerRecords() const
Returns a list of records for all visible layer belonging to the theme.
QgsMapThemeCollection::MapThemeRecord mapThemeState(const QString &name) const
Returns the recorded state of a map theme.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
void updateTriangularMesh(const QgsCoordinateTransform &transform=QgsCoordinateTransform())
Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh.
QgsMeshDatasetIndex staticVectorDatasetIndex(int group=-1) const
Returns the static vector dataset index that is rendered if the temporal properties is not active.
QList< int > enabledDatasetGroupsIndexes() const
Returns the list of indexes of enables dataset groups handled by the layer.
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset metadata.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetIndex datasetIndexAtTime(const QgsDateTimeRange &timeRange, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the time range.
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsMeshDatasetIndex activeScalarDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active scalar group depending on the time range.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshDatasetIndex staticScalarDatasetIndex(int group=-1) const
Returns the static scalar dataset index that is rendered if the temporal properties is not active.
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
static QDomElement rectangleToGMLEnvelope(const QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static QDomElement geometryToGML(const QgsGeometry &geometry, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
static QDomElement rectangleToGMLBox(const QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
Qgis::LabelPlacement placement
Label placement mode.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
int priority
Label priority.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
double dist
Distance from feature to the label.
Property
Data definable properties.
@ PositionX
X-coordinate data defined label position.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top).
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right).
QString fieldName
Name of field (or an expression) to use for label text.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsPrintLayout * clone() const override
Creates a clone of the layout.
Describes the version of a project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsMapThemeCollection * mapThemeCollection
QgsProjectMetadata metadata
QgsCoordinateTransformContext transformContext
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, Qgis::RasterIdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
bool isValid() const
Returns true if valid.
QMap< int, QVariant > results() const
Returns the identify results.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QString bandName(int bandNoInt) const
Returns the name of a band given its number.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
QList< int > referencedFields
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QList< int > referencingFields
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setDistanceArea(const QgsDistanceArea &distanceArea)
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly during rendering to check if rendering should ...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
Scoped object for temporary scaling of a QgsRenderContext for millimeter based rendering.
static QgsDateTimeRange parseTemporalDateTimeInterval(const QString &interval)
Parses a datetime interval and returns a QgsDateTimeRange.
Exception base class for server exceptions.
static QString getExpressionFromServerFid(const QString &serverFid, const QgsVectorDataProvider *provider)
Returns the expression feature id based on primary keys.
static QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
static QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
static QString wmsFeatureInfoSchema(const QgsProject &project)
Returns the schema URL for XML GetFeatureInfo request.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static bool wmsHTMLFeatureInfoUseOnlyMaptip(const QgsProject &project)
Returns if only the maptip should be used for HTML feature info response so that the HTML response to...
static QString wmsFeatureInfoDocumentElementNs(const QgsProject &project)
Returns the document element namespace for XML GetFeatureInfo request.
static QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
static bool wmsFeatureInfoSegmentizeWktGeometry(const QgsProject &project)
Returns if the geometry has to be segmentize in GetFeatureInfo request.
static bool wmsFeatureInfoUseAttributeFormSettings(const QgsProject &project)
Returns if feature form settings should be considered for the format of the feature info response.
static QHash< QString, QString > wmsFeatureInfoLayerAliasMap(const QgsProject &project)
Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
static bool wmsFeatureInfoAddWktGeometry(const QgsProject &project)
Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
static double wmsDefaultMapUnitsPerMm(const QgsProject &project)
Returns the default number of map units per millimeters in case of the scale is not given.
static QString wmsFeatureInfoDocumentElement(const QgsProject &project)
Returns the document element name for XML GetFeatureInfo request.
static int wmsMaxAtlasFeatures(const QgsProject &project)
Returns the maximum number of atlas features which can be printed in a request.
const QList< QgsServerWmsDimensionProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
@ Hidden
Hide task from GUI.
bool isActive() const
Returns true if the temporal property is active.
void setIsActive(bool active)
Sets whether the temporal property is active.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
bool isInstant() const
Returns true if the range consists only of a single instant.
void setColor(const QColor &color)
Sets the color for the buffer.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
void setSize(double size)
Sets the size of the buffer.
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setSize(double size)
Sets the size for rendered text.
void setFont(const QFont &font)
Sets the font used for rendering text.
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Represents a vector layer which manages a vector based dataset.
void setLabeling(QgsAbstractVectorLayerLabeling *labeling)
Sets labeling configuration.
Q_INVOKABLE QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider,...
void setLabelsEnabled(bool enabled)
Sets whether labels should be enabled for the layer.
Q_INVOKABLE void selectByExpression(const QString &expression, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, QgsExpressionContext *context=nullptr)
Selects matching features using an expression.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
void setRenderer(QgsFeatureRenderer *r)
Sets the feature renderer which will be invoked to represent this layer in 2D map views.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection)
Selects matching features using a list of feature IDs.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
virtual bool setSubsetString(const QString &subset)
Sets the string (typically sql) used to define a subset of the layer.
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
QgsEditFormConfig editFormConfig
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const final
Calculates a list of unique values contained within an attribute in the layer.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Implementation of legend node interface for displaying WMS legend entries.
Exception thrown in case of malformed request.
QgsRenderer(const QgsWmsRenderContext &context)
Constructor for QgsRenderer.
QHash< QgsVectorLayer *, SymbolSet > HitTest
QByteArray getPrint()
Returns printed page as binary.
HitTest symbols()
Returns the hit test according to the current context.
std::unique_ptr< QgsDxfExport > getDxf()
Returns the map as DXF data.
QSet< QString > SymbolSet
void configureLayers(QList< QgsMapLayer * > &layers, QgsMapSettings *settings=nullptr)
Configures layers for rendering optionally considering the map settings.
std::unique_ptr< QgsMapRendererTask > getPdf(const QString &tmpFileName)
Returns a configured pdf export task.
QByteArray getFeatureInfo(const QString &version="1.3.0")
Creates an xml document that describes the result of the getFeatureInfo request.
QImage * getLegendGraphics(QgsLayerTreeModel &model)
Returns the map legend as an image (or nullptr in case of error).
std::unique_ptr< QImage > getMap()
Returns the map as an image (or nullptr in case of error).
QJsonObject getLegendGraphicsAsJson(QgsLayerTreeModel &model, const Qgis::LegendJsonRenderFlags &jsonRenderFlags=Qgis::LegendJsonRenderFlags())
Returns the map legend as a JSON object.
Exception class for WMS service exceptions.
ExceptionCode
Exception codes as defined in OGC scpecifications for WMS 1.1.1 and WMS 1.3.0.
@ QGIS_InvalidParameterValue
@ QGIS_MissingParameterValue
WMS parameter received from the client.
bool transparentAsBool() const
Returns TRANSPARENT parameter as a bool or its default value if not defined.
QString formatAsString() const
Returns FORMAT parameter as a string.
QgsWmsParametersComposerMap composerMapParameters(int mapId) const
Returns the requested parameters for a composer map parameter.
DxfFormatOption
Options for DXF format.
QColor backgroundColorAsColor() const
Returns BGCOLOR parameter as a QColor or its default value if not defined.
Format format() const
Returns format.
Format
Output format for the response.
Rendering context for the WMS renderer.
QList< QgsMapLayer * > layersToRender() const
Returns a list of all layers to actually render according to the current configuration.
void setScaleDenominator(double scaleDenominator)
Sets a custom scale denominator.
Median cut implementation.
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
#define FID_TO_STRING(fid)
QVector< QgsFeatureStore > QgsFeatureStoreList
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
QgsAbstractMetadataBase::KeywordMap keywords
Metadata keyword map.
QString creator
Metadata creator tag.
QString author
Metadata author tag.
QString subject
Metadata subject tag.
QString title
Metadata title tag.
QDateTime creationDateTime
Metadata creation datetime.
QString producer
Metadata producer tag.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO32000 extension format georeferencing should be used.
Layers and optional attribute index to split into multiple layers using attribute value as layer name...
QPainter * painter
Painter.
Q_NOWARN_DEPRECATED_POP QgsRenderContext * context
Render context, if available.
Contains settings relating to exporting layouts to raster images.
QList< int > pages
List of specific pages to export, or an empty list to export all pages.
QSize imageSize
Manual size in pixels for output image.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
Contains settings relating to exporting layouts to PDF.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO3200 extension format georeferencing should be used.
bool forceVectorOutput
Set to true to force vector object exports, even when the resultant appearance will differ from the l...
bool rasterizeWholeImage
Set to true to force whole layout to be rasterized while exporting.
QStringList exportThemes
Optional list of map themes to export as Geospatial PDF layer groups.
bool appendGeoreference
Indicates whether PDF export should append georeference data.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
bool writeGeoPdf
true if geospatial PDF files should be created, instead of normal PDF files.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
bool simplifyGeometries
Indicates whether vector geometries should be simplified to avoid redundant extraneous detail,...
Qgis::TextRenderFormat textRenderFormat
Text rendering format, which controls how text should be rendered in the export (e....
Contains settings relating to exporting layouts to SVG.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
QList< QgsWmsParametersLayer > mLayers
QList< QgsWmsParametersHighlightLayer > mHighlightLayers