23#include <nlohmann/json.hpp>
88#include <QTemporaryFile>
90#include <QXmlStreamReader>
92using namespace Qt::StringLiterals;
119 : mContext( context )
121 mProject = mContext.project();
123 mWmsParameters = mContext.parameters();
124 mWmsParameters.dump();
129 removeTemporaryLayers();
135 std::unique_ptr<QgsWmsRestorer> restorer;
136 restorer = std::make_unique<QgsWmsRestorer>( mContext );
139 QList<QgsMapLayer *> layers = mContext.layersToRender();
142 const qreal dpmm = mContext.dotsPerMm();
147 const auto layersToRender = mContext.layersToRender();
148 for (
const auto &layer : std::as_const( layersToRender ) )
151 if ( layer->dataProvider()->name() ==
"wms"_L1 )
155 const auto image { layerNode->getLegendGraphicBlocking() };
156 if ( !image.isNull() )
159 if ( mContext.isValidWidthHeight( image.width(), image.height() ) )
161 const double w = image.width() / dpmm;
162 const double h = image.height() / dpmm;
163 const QSizeF newWmsSize { w, h };
176 if ( !mWmsParameters.bbox().isEmpty() )
180 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
181 configureMapSettings( tmp.get(), mapSettings );
187 context = configureDefaultRenderContext();
191 std::unique_ptr<QImage> image;
192 const QSizeF minSize = renderer.
minimumSize( &context );
193 const QSize size(
static_cast<int>( minSize.width() * dpmm ),
static_cast<int>( minSize.height() * dpmm ) );
194 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
198 image.reset( createImage( size ) );
201 QPainter painter( image.get() );
204 if ( painter.renderHints() & QPainter::SmoothPixmapTransform )
206 if ( painter.renderHints() & QPainter::LosslessImageRendering )
216 return image.release();
222 std::unique_ptr<QgsWmsRestorer> restorer;
223 restorer = std::make_unique<QgsWmsRestorer>( mContext );
226 QList<QgsMapLayer *> layers = mContext.layersToRender();
230 const QSize size( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() );
232 if ( !mContext.isValidWidthHeight( size.width(), size.height() ) )
236 std::unique_ptr<QImage> image( createImage( size ) );
239 const qreal dpmm = mContext.dotsPerMm();
240 std::unique_ptr<QPainter> painter;
241 painter = std::make_unique<QPainter>( image.get() );
242 painter->setRenderHint( QPainter::Antialiasing,
true );
243 painter->scale( dpmm, dpmm );
254 nodeModel.
drawSymbol( settings, &ctx, size.height() / dpmm );
257 return image.release();
263 std::unique_ptr<QgsWmsRestorer> restorer;
264 restorer = std::make_unique<QgsWmsRestorer>( mContext );
267 QList<QgsMapLayer *> layers = mContext.layersToRender();
283 std::unique_ptr<QgsWmsRestorer> restorer;
284 restorer = std::make_unique<QgsWmsRestorer>( mContext );
287 QList<QgsMapLayer *> layers = mContext.layersToRender();
296 QJsonObject jsonSymbol {
legendNode.exportSymbolToJson( settings, renderContext ) };
303 if ( vLayer->renderer() )
307 const QString ruleExp { vLayer->renderer()->legendKeyToExpression( ruleKey, vLayer, ok ) };
310 jsonSymbol[u
"rule"_s] = ruleExp;
319 void QgsRenderer::runHitTest(
const QgsMapSettings &mapSettings, HitTest &hitTest )
const
323 for (
const QString &
id : mapSettings.
layerIds() )
340 runHitTestLayer( vl, usedSymbols, context );
344 void QgsRenderer::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols, QgsRenderContext &context )
const
346 std::unique_ptr<QgsFeatureRenderer> r( vl->
renderer()->
clone() );
348 r->startRender( context, vl->
fields() );
350 QgsFeatureRequest request( context.
extent() );
352 QgsFeatureIterator fi = vl->
getFeatures( request );
356 if ( moreSymbolsPerFeature )
358 for ( QgsSymbol *s : r->originalSymbolsForFeature( f, context ) )
364 r->stopRender( context );
370 if ( !mContext.isValidWidthHeight() )
376 std::unique_ptr<QgsWmsRestorer> restorer;
377 restorer = std::make_unique<QgsWmsRestorer>( mContext );
382 QList<QgsMapLayer *> layers = mContext.layersToRender();
386 std::unique_ptr<QPainter> painter;
387 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
390 configureMapSettings( image.get(), mapSettings );
397 runHitTest( mapSettings,
symbols );
405 std::unique_ptr<QgsWmsRestorer> restorer;
406 restorer = std::make_unique<QgsWmsRestorer>( mContext );
409 const QString templateName = mWmsParameters.composerTemplate();
410 if ( templateName.isEmpty() )
433 std::unique_ptr<QgsPrintLayout> layout( sourceLayout->
clone() );
437 QStringList atlasPk = mWmsParameters.atlasPk();
438 if ( !atlasPk.isEmpty() )
440 atlas = layout->atlas();
441 if ( !atlas || !atlas->
enabled() )
454 if ( atlasPk.size() == 1 && atlasPk.at( 0 ) ==
"*"_L1 )
458 if ( atlas->
count() > maxAtlasFeatures )
466 if ( pkIndexes.size() == 0 )
468 QgsDebugMsgLevel( u
"Atlas print: layer %1 has no primary key attributes"_s.arg( cLayer->
name() ), 2 );
472 const int pkIndexesSize { std::max<int>( pkIndexes.size(), 1 ) };
474 QStringList pkAttributeNames;
475 for (
int pkIndex : std::as_const( pkIndexes ) )
477 pkAttributeNames.append( cLayer->
fields().
at( pkIndex ).
name() );
480 const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
481 if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() )
487 if ( nAtlasFeatures > maxAtlasFeatures )
491 QString(
"%1 atlas features have been requested, but the project configuration only allows printing %2 atlas features at a time" ).arg( nAtlasFeatures ).arg( maxAtlasFeatures )
495 QString filterString;
496 int currentAtlasPk = 0;
498 for (
int i = 0; i < nAtlasFeatures; ++i )
502 filterString.append(
" OR " );
505 filterString.append(
"( " );
508 if ( pkAttributeNames.isEmpty() )
510 filterString.append( u
"$id = %1"_s.arg( atlasPk.at( currentAtlasPk ) ) );
515 for (
int j = 0; j < pkIndexes.size(); ++j )
519 filterString.append(
" AND " );
526 filterString.append(
" )" );
534 if ( !errorString.isEmpty() )
536 throw QgsException( u
"An error occurred during the Atlas print: %1"_s.arg( errorString ) );
544 QList<QgsMapLayer *> layers = mContext.layersToRender();
548 auto image = std::make_unique<QImage>();
549 configureMapSettings( image.get(), mapSettings );
555 configurePrintLayout( layout.get(), mapSettings, atlas );
559 const QList<QgsMapLayer *> lyrs = mapSettings.
layers();
561#ifdef HAVE_SERVER_PYTHON_PLUGINS
562 mContext.accessControl()->resolveFilterFeatures( lyrs );
566 QHash<const QgsVectorLayer *, QStringList> fltrs;
571 fltrs.insert( vl, dimensionFilter( vl ) );
583 QTemporaryFile tempOutputFile( QDir::tempPath() +
'/' + u
"XXXXXX.%1"_s.arg( extension ) );
584 if ( !tempOutputFile.open() )
586 throw QgsException( u
"Could not open temporary file for the GetPrint request."_s );
594 if ( !mWmsParameters.dpi().isEmpty() )
597 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
599 exportSettings.
dpi = dpi;
612 atlasSvgExport.
exportToSvg( tempOutputFile.fileName(), exportSettings );
618 exporter.
exportToSvg( tempOutputFile.fileName(), exportSettings );
627 double dpi( layout->renderContext().dpi() );
628 if ( !mWmsParameters.dpi().isEmpty() )
631 double _dpi = mWmsParameters.dpi().toDouble( &ok );
635 exportSettings.
dpi = dpi;
641 QgsLayoutSize layoutSize( layout->pageCollection()->page( 0 )->sizeWithUnits() );
646 const QSize imageSize = QSize(
static_cast<int>( width.
length() * dpi / 25.4 ),
static_cast<int>( height.
length() * dpi / 25.4 ) );
648 const QString paramWidth = mWmsParameters.width();
649 const QString paramHeight = mWmsParameters.height();
654 if ( !paramWidth.isEmpty() && !paramHeight.isEmpty() )
656 exportSettings.
imageSize = QSize( paramWidth.toInt(), paramHeight.toInt() );
658 else if ( !paramWidth.isEmpty() && paramHeight.isEmpty() )
660 exportSettings.
imageSize = QSize( paramWidth.toInt(),
static_cast<double>( paramWidth.toInt() ) / imageSize.width() * imageSize.height() );
662 else if ( paramWidth.isEmpty() && !paramHeight.isEmpty() )
664 exportSettings.
imageSize = QSize(
static_cast<double>( paramHeight.toInt() ) / imageSize.height() * imageSize.width(), paramHeight.toInt() );
672 exportSettings.
pages.append( 0 );
680 atlasPngExport.
exportToImage( tempOutputFile.fileName(), exportSettings );
684 throw QgsServiceException( u
"Bad request"_s, u
"Atlas error: empty atlas."_s, QString(), 400 );
690 exporter.
exportToImage( tempOutputFile.fileName(), exportSettings );
698 if ( !mWmsParameters.dpi().isEmpty() )
701 double dpi( mWmsParameters.dpi().toDouble( &ok ) );
703 exportSettings.
dpi = dpi;
708 exportSettings.
rasterizeWholeImage = layout->customProperty( u
"rasterize"_s,
false ).toBool();
710 QVector<qreal> requestMapScales = mWmsParameters.pdfPredefinedMapScales();
711 if ( requestMapScales.size() > 0 )
720 QStringList exportThemes = mWmsParameters.pdfExportMapThemes();
721 if ( exportThemes.size() > 0 )
725 exportSettings.
writeGeoPdf = mWmsParameters.writeGeospatialPdf();
731 if ( mWmsParameters.pdfLosslessImageCompression() )
735 if ( mWmsParameters.pdfDisableTiledRasterRendering() )
748 exporter.
exportToPdf( tempOutputFile.fileName(), exportSettings );
758 handlePrintErrors( atlas->
layout() );
762 handlePrintErrors( layout.get() );
765 return tempOutputFile.readAll();
772 QList<QgsLayoutItemMap *> maps;
778 for (
const auto &map : std::as_const( maps ) )
784 if ( cMapParams.
mLayers.isEmpty() )
789 if ( !atlas || !map->atlasDriven() )
795 c->removeLayoutItem( map );
804 QgsRectangle r( cMapParams.
mExtent );
812 if ( cMapParams.
mScale > 0 )
814 map->setScale(
static_cast<double>( cMapParams.
mScale ) );
820 map->setMapRotation( cMapParams.
mRotation );
824 if ( !map->keepLayerSet() )
826 QList<QgsMapLayer *> layerSet;
828 for (
const auto &layer : std::as_const( cMapParams.
mLayers ) )
830 if ( mContext.isValidGroup( layer.mNickname ) )
832 QList<QgsMapLayer *> layersFromGroup;
834 const QList<QgsMapLayer *> cLayersFromGroup = mContext.layersFromGroup( layer.mNickname );
835 for ( QgsMapLayer *layerFromGroup : cLayersFromGroup )
837 if ( !layerFromGroup )
842 layersFromGroup.push_front( layerFromGroup );
845 if ( !layersFromGroup.isEmpty() )
847 layerSet.append( layersFromGroup );
852 QgsMapLayer *mlayer = mContext.layer( layer.mNickname );
859 setLayerStyle( mlayer, layer.mStyle );
864 std::reverse( layerSet.begin(), layerSet.end() );
869 QMap<QString, QString> layersStyle;
870 if ( map->followVisibilityPreset() )
880 const QString presetName = map->followVisibilityPresetName();
881 if ( layerSet.isEmpty() )
884 const QgsExpressionContext ex { map->createExpressionContext() };
885 layerSet = map->layersToRender( &ex );
888 map->setFollowVisibilityPreset(
false );
892 for (
const auto &layerMapThemeRecord : std::as_const( mapThemeRecords ) )
894 if ( layerSet.contains( layerMapThemeRecord.layer() ) )
896 layersStyle.insert( layerMapThemeRecord.layer()->id(), layerMapThemeRecord.layer()->styleManager()->style( layerMapThemeRecord.currentStyle ).xmlData() );
902 const QList<QgsMapLayer *> highlights = highlightLayers( cMapParams.
mHighlightLayers );
903 for (
const auto &hl : std::as_const( highlights ) )
905 layerSet.prepend( hl );
908 map->setLayers( layerSet );
909 map->setKeepLayerSet(
true );
913 if ( !layersStyle.isEmpty() )
915 map->setLayerStyleOverrides( layersStyle );
916 map->setKeepLayerStyles(
true );
923 map->grid()->setIntervalX(
static_cast<double>( cMapParams.
mGridX ) );
924 map->grid()->setIntervalY(
static_cast<double>( cMapParams.
mGridY ) );
929 QList<QgsLayoutItemLabel *> labels;
930 c->layoutItems<QgsLayoutItemLabel>( labels );
931 for (
const auto &label : std::as_const( labels ) )
934 const QString labelId = label->id();
935 const QString labelParam = mWmsParameters.layoutParameter( labelId, ok );
940 if ( labelParam.isEmpty() )
944 c->removeItem( label );
949 label->setText( labelParam );
953 QList<QgsLayoutItemHtml *> htmls;
954 c->layoutObjects<QgsLayoutItemHtml>( htmls );
955 for (
const auto &html : std::as_const( htmls ) )
957 if ( html->frameCount() == 0 )
960 QgsLayoutFrame *htmlFrame = html->frame( 0 );
962 const QString htmlId = htmlFrame->
id();
963 const QString htmlValue = mWmsParameters.layoutParameter( htmlId, ok );
973 if ( htmlValue.isEmpty() )
975 c->removeMultiFrame( html );
982 QUrl newUrl( htmlValue );
983 html->setUrl( newUrl );
987 html->setHtml( htmlValue );
994 QList<QgsLayoutItemLegend *> legends;
995 c->layoutItems<QgsLayoutItemLegend>( legends );
996 for (
const auto &legend : std::as_const( legends ) )
998 switch ( legend->syncMode() )
1005 const QgsLayoutItemMap *map = legend->linkedMap();
1014 QgsLegendModel *model = legend->model();
1015 QStringList layerSet;
1016 QList<QgsMapLayer *> mapLayers;
1017 if ( map->
layers().isEmpty() )
1021 mapLayers = mProject->mapLayers(
true ).values();
1025 mapLayers = map->
layers();
1027 const QList<QgsMapLayer *> layerList = mapLayers;
1028 for (
const auto &layer : layerList )
1029 layerSet << layer->id();
1032 QgsLayerTree *root = model->
rootGroup();
1039 for (
const auto &layerId : layerIds )
1041 QgsLayerTreeLayer *nodeLayer = root->
findLayer( layerId );
1046 if ( !layerSet.contains( layerId ) )
1048 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1052 QgsMapLayer *layer = nodeLayer->
layer();
1055 qobject_cast<QgsLayerTreeGroup *>( nodeLayer->
parent() )->removeChildNode( nodeLayer );
1073 if ( !mContext.isValidWidthHeight() )
1078 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1084 std::unique_ptr<QgsWmsRestorer> restorer;
1085 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1088 QList<QgsMapLayer *> layers = mContext.layersToRender();
1095 std::unique_ptr<QPainter> painter;
1096 std::unique_ptr<QImage> image( createImage( mContext.mapSize() ) );
1099 configureMapSettings( image.get(), mapSettings );
1105 QPainter *renderedPainter = layersRendering( mapSettings, image.get() );
1106 if ( !renderedPainter )
1111 painter.reset( renderedPainter );
1114 annotationsRendering( painter.get(), mapSettings );
1120 QImage *scaledImage = scaleImage( image.get() );
1122 image.reset( scaledImage );
1125 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
1135 QList<QgsMapLayer *> layers = mContext.layersToRender();
1139 const QStringList attributes = mWmsParameters.dxfLayerAttributes();
1140 QList<QgsDxfExport::DxfLayer> dxfLayers;
1152 int layerAttribute = -1;
1153 if ( attributes.size() > layerIdx )
1162 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1164 QString crs = mWmsParameters.crs();
1165 if ( crs.compare( u
"CRS:84"_s, Qt::CaseInsensitive ) == 0 )
1167 crs = u
"EPSG:4326"_s;
1170 else if ( crs.isEmpty() )
1172 crs = u
"EPSG:4326"_s;
1206 auto dxf = std::make_unique<QgsDxfExport>();
1207 dxf->setExtent( mapExtent );
1208 dxf->setDestinationCrs( outputCRS );
1209 dxf->addLayers( dxfLayers );
1210 dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
1211 dxf->setSymbologyExport( mWmsParameters.dxfMode() );
1214 dxf->setSymbologyScale( mWmsParameters.dxfScale() );
1217 dxf->setForce2d( mWmsParameters.isForce2D() );
1219 if ( mWmsParameters.noMText() )
1222 if ( mWmsParameters.exportLinesWithZeroWidth() )
1227 dxf->setFlags( flags );
1236 QList<QgsMapLayer *> layers = mContext.layersToRender();
1240 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1242 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1246 if ( mWmsParameters.pdfExportMetadata() )
1257 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1258 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, u
"PDF"_s,
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1259 if ( mWmsParameters.pdfAppendGeoreference() )
1261 pdf->setSaveWorldFile(
true );
1269 if ( i < 0 || i > mapSettings.
outputSize().width() )
1276 if ( j < 0 || j > mapSettings.
outputSize().height() )
1293 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1299 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1300 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1301 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1302 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1304 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1308 if ( mWmsParameters.j().isEmpty() )
1321 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1324 std::unique_ptr<QgsWmsRestorer> restorer;
1325 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1329 bool mandatoryCrsParam =
true;
1330 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1332 mandatoryCrsParam =
false;
1338 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1343 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1355#ifdef HAVE_SERVER_PYTHON_PLUGINS
1356 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1359 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1364 ba = convertFeatureInfoToText( result );
1366 ba = convertFeatureInfoToHtml( result );
1368 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1370 ba = result.toByteArray();
1375 QImage *QgsRenderer::createImage(
const QSize &size )
const
1377 std::unique_ptr<QImage> image;
1385 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1390 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1395 if ( image->isNull() )
1397 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1400 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1401 image->setDotsPerMeterX( dpm );
1402 image->setDotsPerMeterY( dpm );
1404 return image.release();
1407 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1411 throw QgsException( u
"configureMapSettings: no paint device"_s );
1414 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1417 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1420 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1421 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1426 QString crs = mWmsParameters.crs();
1427 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1429 crs = QString(
"EPSG:4326" );
1432 else if ( crs.isEmpty() && !mandatoryCrsParam )
1434 crs = QString(
"EPSG:4326" );
1437 QgsCoordinateReferenceSystem outputCRS;
1444 QgsWmsParameter parameter;
1446 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1457 throw QgsBadRequestException( code, parameter );
1467 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1475 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1481 bool transparent = mWmsParameters.transparentAsBool();
1482 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1489 else if ( backgroundColor.isValid() )
1495 QgsExpressionContext context = mProject->createExpressionContext();
1512 if ( mContext.settings().logProfile() )
1522 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1523 if ( !timeString.isEmpty() )
1525 bool isValidTemporalRange {
true };
1528 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1539 catch (
const QgsServerApiBadRequestException &ex )
1541 isValidTemporalRange =
false;
1546 if ( isValidTemporalRange )
1555 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1561 QgsDistanceArea distanceArea = QgsDistanceArea();
1562 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1568 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1570 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1572 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1574 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1576 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1578 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1580 int featureCount = mWmsParameters.featureCountAsInt();
1581 if ( featureCount < 1 )
1586 int i = mWmsParameters.iAsInt();
1587 int j = mWmsParameters.jAsInt();
1588 if ( xyDefined && !ijDefined )
1590 i = mWmsParameters.xAsInt();
1591 j = mWmsParameters.yAsInt();
1593 int width = mWmsParameters.widthAsInt();
1594 int height = mWmsParameters.heightAsInt();
1595 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1597 i *= ( outputImage->width() /
static_cast<double>( width ) );
1598 j *= ( outputImage->height() /
static_cast<double>( height ) );
1602 std::unique_ptr<QgsRectangle> featuresRect;
1603 std::unique_ptr<QgsGeometry> filterGeom;
1604 std::unique_ptr<QgsPointXY> infoPoint;
1606 if ( i != -1 && j != -1 )
1608 infoPoint = std::make_unique<QgsPointXY>();
1609 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1611 else if ( filtersDefined )
1613 featuresRect = std::make_unique<QgsRectangle>();
1616 if ( filterGeomDefined )
1618 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1621 QDomDocument result;
1622 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1623 result.appendChild( header );
1625 QDomElement getFeatureInfoElement;
1629 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1630 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1631 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1632 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1633 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1634 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1635 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1636 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1637 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 );
1642 if ( featureInfoElemName.isEmpty() )
1644 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1647 if ( featureInfoElemNs.isEmpty() )
1649 getFeatureInfoElement = result.createElement( featureInfoElemName );
1653 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1657 if ( !featureInfoSchema.isEmpty() )
1659 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1660 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1663 result.appendChild( getFeatureInfoElement );
1673 for (
const QString &queryLayer : queryLayers )
1675 bool validLayer =
false;
1676 bool queryableLayer =
true;
1677 for ( QgsMapLayer *layer : std::as_const( layers ) )
1679 if ( queryLayer == mContext.layerNickname( *layer ) )
1683 if ( !queryableLayer )
1688 QDomElement layerElement;
1691 layerElement = getFeatureInfoElement;
1695 layerElement = result.createElement( u
"Layer"_s );
1696 QString layerName = queryLayer;
1699 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1700 if ( layerAliasIt != layerAliasMap.constEnd() )
1702 layerName = layerAliasIt.value();
1705 layerElement.setAttribute( u
"name"_s, layerName );
1706 const QString layerTitle = layer->serverProperties()->title();
1707 if ( !layerTitle.isEmpty() )
1709 layerElement.setAttribute( u
"title"_s, layerTitle );
1713 layerElement.setAttribute( u
"title"_s, layerName );
1715 getFeatureInfoElement.appendChild( layerElement );
1718 layerElement.setAttribute( u
"id"_s, layer->id() );
1724 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1727 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1733 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1749 layerElement = result.createElement( u
"gml:featureMember"_s );
1750 getFeatureInfoElement.appendChild( layerElement );
1752 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1756 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1764 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1768 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1771 param.mValue = queryLayer;
1774 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1777 param.mValue = queryLayer;
1779 bool hasGroupAndQueryable {
false };
1780 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1783 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1784 for (
const QString &ql : constNicks )
1786 if ( mContext.layerGroups().contains( ql ) )
1788 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1789 for (
const QgsMapLayer *ml : constLayers )
1791 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1797 hasGroupAndQueryable =
true;
1806 if ( !hasGroupAndQueryable )
1813 if ( featuresRect && !featuresRect->isNull() )
1817 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1818 QDomElement boxElem;
1819 int gmlVersion = mWmsParameters.infoFormatVersion();
1820 if ( gmlVersion < 3 )
1832 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1834 bBoxElem.appendChild( boxElem );
1835 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1839 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1841 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1842 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1843 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1844 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1845 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1851 convertFeatureInfoToSia2045( result );
1857 bool QgsRenderer::featureInfoFromVectorLayer(
1858 QgsVectorLayer *layer,
1859 const QgsPointXY *infoPoint,
1861 QDomDocument &infoDocument,
1862 QDomElement &layerElement,
1863 const QgsMapSettings &mapSettings,
1864 QgsRenderContext &renderContext,
1865 const QString &version,
1866 QgsRectangle *featureBBox,
1867 QgsGeometry *filterGeom
1875 QgsFeatureRequest fReq;
1878 std::unique_ptr<QgsGeometry> layerFilterGeom;
1881 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1886 QgsRectangle mapRect = mapSettings.
extent();
1890 QgsRectangle searchRect;
1895 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1897 else if ( layerFilterGeom )
1899 searchRect = layerFilterGeom->boundingBox();
1901 else if ( !mWmsParameters.bbox().isEmpty() )
1903 searchRect = layerRect;
1909 QgsAttributes featureAttributes;
1910 int featureCounter = 0;
1912 const QgsFields fields = layer->
fields();
1929 if ( layerFilterGeom )
1931 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1935 mFeatureFilter.filterFeatures( layer, fReq );
1938#ifdef HAVE_SERVER_PYTHON_PLUGINS
1940 mContext.accessControl()->filterFeatures( layer, fReq );
1943 QStringList attributes;
1944 for (
const QgsField &field : fields )
1946 attributes.append( field.name() );
1948 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1952 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1956 r2->startRender( renderContext, layer->
fields() );
1959 bool featureBBoxInitialized =
false;
1968 if ( featureCounter > nFeatures )
1983 bool render = r2->willRenderFeature( feature, renderContext );
1996 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1999 featureBBoxInitialized =
true;
2008 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
2017 int gmlVersion = mWmsParameters.infoFormatVersion();
2018 QString typeName = mContext.layerNickname( *layer );
2019 QDomElement elem = createFeatureGML(
2028#ifdef HAVE_SERVER_PYTHON_PLUGINS
2033 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2034 featureMemberElem.appendChild( elem );
2035 layerElement.appendChild( featureMemberElem );
2040 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2042 layerElement.appendChild( featureElement );
2048 writeAttributesTabLayout(
2056#ifdef HAVE_SERVER_PYTHON_PLUGINS
2064 for (
int i = 0; i < featureAttributes.count(); ++i )
2066 writeVectorLayerAttribute(
2074#ifdef HAVE_SERVER_PYTHON_PLUGINS
2086 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2087 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2091 featureElement.appendChild( maptipElem );
2095 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2097 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2098 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2101 displayExpression.
prepare( &context );
2102 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2103 featureElement.appendChild( displayElem );
2109 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2110 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2115 featureElement.appendChild( bBoxElem );
2121 QgsGeometry geom = feature.
geometry();
2124 if ( layer->
crs() != outputCrs )
2126 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2131 if ( segmentizeWktGeometry )
2133 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2138 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2139 geom.
set( segmentizedGeom );
2143 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2144 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2145 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2146 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2147 featureElement.appendChild( geometryElement );
2154 r2->stopRender( renderContext );
2160 void QgsRenderer::writeAttributesTabGroup(
2161 const QgsAttributeEditorElement *group,
2162 QgsVectorLayer *layer,
2163 const QgsFields &fields,
2164 QgsAttributes &featureAttributes,
2166 QDomElement &parentElem,
2167 QgsRenderContext &renderContext,
2168 QStringList *attributes
2171 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2174 QString groupName = container->
name();
2175 QDomElement nameElem;
2177 if ( !groupName.isEmpty() )
2179 nameElem = doc.createElement( groupName );
2180 parentElem.appendChild( nameElem );
2183 const QList<QgsAttributeEditorElement *> children = container->
children();
2184 for (
const QgsAttributeEditorElement *child : children )
2188 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2192 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2198 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2206 void QgsRenderer::writeAttributesTabLayout(
2207 QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2211 if ( !editorContainer )
2216 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2219 void QgsRenderer::writeVectorLayerAttribute(
2220 int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2223#ifndef HAVE_SERVER_PYTHON_PLUGINS
2224 Q_UNUSED( attributes );
2237#ifdef HAVE_SERVER_PYTHON_PLUGINS
2239 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2246 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2247 attributeElement.setAttribute( u
"name"_s, attributeName );
2250 featureElem.appendChild( attributeElement );
2253 bool QgsRenderer::featureInfoFromMeshLayer(
2254 QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2258 Q_UNUSED( mapSettings )
2267 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2269 QList<QgsMeshDatasetIndex> datasetIndexList;
2278 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2280 if ( activeScalarGroup >= 0 )
2282 QgsMeshDatasetIndex indice;
2284 datasetIndexList.append( indice );
2287 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2290 for (
int groupIndex : allGroup )
2292 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2298 if ( activeScalarGroup >= 0 )
2300 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2303 for (
int groupIndex : allGroup )
2305 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2308 datasetIndexList.append( groupIndex );
2315 double scalarDoubleValue = 0.0;
2317 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2319 if ( !index.isValid() )
2323 QMap<QString, QString> derivedAttributes;
2325 QMap<QString, QString> attribute;
2329 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2330 scalarDoubleValue = scalarValue.
scalar();
2331 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2336 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2337 const double vectorX = vectorValue.
x();
2338 const double vectorY = vectorValue.
y();
2339 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2341 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2345 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2346 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2347 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2354 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2355 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2357 const QString resultName = groupMeta.
name();
2359 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2360 attributeElement.setAttribute( u
"name"_s, resultName );
2365 value = QString::number( scalarDoubleValue );
2368 attributeElement.setAttribute( u
"value"_s, value );
2369 layerElement.appendChild( attributeElement );
2373 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2374 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2377 value = range.
begin().toString( dateFormat );
2381 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2383 attributeElementTime.setAttribute( u
"value"_s, value );
2384 layerElement.appendChild( attributeElementTime );
2390 bool QgsRenderer::featureInfoFromRasterLayer(
2391 QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2412 QgsRasterIdentifyResult identifyResult;
2415 const QgsRectangle extent { mapSettings.
extent() };
2419 throw QgsBadRequestException(
2430 if ( !identifyResult.
isValid() )
2433 QMap<int, QVariant> attributes = identifyResult.
results();
2439 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2440 int gmlVersion = mWmsParameters.infoFormatVersion();
2441 QString typeName = mContext.layerNickname( *layer );
2447 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2449 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2450 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2453 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2454 layerElement.appendChild( elem );
2458 const auto values = identifyResult.
results();
2459 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2461 QVariant value = it.value();
2462 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2468 if ( value.userType() == QMetaType::Type::QString )
2476 for (
const QgsFeatureStore &featureStore : featureStoreList )
2479 for (
const QgsFeature &feature : storeFeatures )
2481 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2482 layerElement.appendChild( elem );
2492 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2494 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2495 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2500 value = QString::number( it.value().toDouble() );
2503 attributeElement.setAttribute( u
"value"_s, value );
2504 layerElement.appendChild( attributeElement );
2509 const auto values = identifyResult.
results();
2510 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2512 QVariant value = it.value();
2513 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2519 if ( value.userType() == QMetaType::Type::QString )
2526 for (
const QgsFeatureStore &featureStore : featureStoreList )
2529 for (
const QgsFeature &feature : storeFeatures )
2531 for (
const auto &fld : feature.
fields() )
2533 const auto val { feature.
attribute( fld.name() ) };
2534 if ( val.isValid() )
2536 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2537 attributeElement.setAttribute( u
"name"_s, fld.name() );
2538 attributeElement.setAttribute( u
"value"_s, val.toString() );
2539 layerElement.appendChild( attributeElement );
2550 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2551 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2554 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2557 layerElement.appendChild( maptipElem );
2563 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2566 if ( filter.contains(
";"_L1 ) )
2571 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2572 groupStringList( tokens, u
"'"_s );
2573 groupStringList( tokens, u
"\""_s );
2575 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2578 if ( tokenIt->compare(
','_L1 ) == 0
2579 || tokenIt->compare(
'('_L1 ) == 0
2580 || tokenIt->compare(
')'_L1 ) == 0
2581 || tokenIt->compare(
'='_L1 ) == 0
2582 || tokenIt->compare(
"!="_L1 ) == 0
2583 || tokenIt->compare(
'<'_L1 ) == 0
2584 || tokenIt->compare(
"<="_L1 ) == 0
2585 || tokenIt->compare(
'>'_L1 ) == 0
2586 || tokenIt->compare(
">="_L1 ) == 0
2587 || tokenIt->compare(
'%'_L1 ) == 0
2588 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2589 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2590 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2591 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2592 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2593 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2594 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2595 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2596 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2597 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2598 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2605 ( void ) tokenIt->toDouble( &isNumeric );
2614 if ( *tokenIt ==
"''"_L1 )
2620 if ( tokenIt->size() > 2
2621 && ( *tokenIt )[0] == QChar(
'\'' )
2622 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2623 && ( *tokenIt )[1] != QChar(
'\'' )
2624 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2630 if ( tokenIt->size() > 2 && ( *tokenIt )[0] == QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' ) && ( *tokenIt )[1] != QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2641 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2644 bool groupActive =
false;
2645 int startGroup = -1;
2646 QString concatString;
2648 for (
int i = 0; i < list.size(); ++i )
2650 QString &str = list[i];
2651 if ( str.startsWith( groupString ) )
2655 concatString.clear();
2660 if ( i != startGroup )
2662 concatString.append(
" " );
2664 concatString.append( str );
2667 if ( str.endsWith( groupString ) )
2670 groupActive =
false;
2672 if ( startGroup != -1 )
2674 list[startGroup] = concatString;
2675 for (
int j = startGroup + 1; j <= endGroup; ++j )
2677 list.removeAt( startGroup + 1 );
2682 concatString.clear();
2688 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2690 QDomDocument SIAInfoDoc;
2691 QDomElement infoDocElement = doc.documentElement();
2692 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2693 SIAInfoDoc.appendChild( SIAInfoDocElement );
2695 QString currentAttributeName;
2696 QString currentAttributeValue;
2697 QDomElement currentAttributeElem;
2698 QString currentLayerName;
2699 QDomElement currentLayerElem;
2700 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2701 for (
int i = 0; i < layerNodeList.size(); ++i )
2703 currentLayerElem = layerNodeList.at( i ).toElement();
2704 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2706 QDomElement currentFeatureElem;
2708 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2709 if ( featureList.isEmpty() )
2712 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2713 QDomElement rasterLayerElem;
2714 if ( !attributeList.isEmpty() )
2716 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2718 for (
int j = 0; j < attributeList.size(); ++j )
2720 currentAttributeElem = attributeList.at( j ).toElement();
2721 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2722 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2723 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2724 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2725 outAttributeElem.appendChild( outAttributeText );
2726 rasterLayerElem.appendChild( outAttributeElem );
2728 if ( !attributeList.isEmpty() )
2730 SIAInfoDocElement.appendChild( rasterLayerElem );
2736 QSet<QString> layerPropertyAttributes;
2737 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2738 if ( !currentLayerId.isEmpty() )
2740 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2743 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2744 if ( !WMSPropertyAttributesString.isEmpty() )
2746 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2747 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2749 layerPropertyAttributes.insert( *propertyIt );
2755 QDomElement propertyRefChild;
2756 for (
int j = 0; j < featureList.size(); ++j )
2758 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2759 currentFeatureElem = featureList.at( j ).toElement();
2760 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2762 for (
int k = 0; k < attributeList.size(); ++k )
2764 currentAttributeElem = attributeList.at( k ).toElement();
2765 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2766 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2767 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2769 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2770 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2771 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2772 identifierElem.appendChild( identifierText );
2773 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2774 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2775 valueElem.appendChild( valueText );
2776 propertyElem.appendChild( identifierElem );
2777 propertyElem.appendChild( valueElem );
2778 if ( propertyRefChild.isNull() )
2780 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2781 propertyRefChild = propertyElem;
2785 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2790 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2791 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2792 SIAAttributeElem.appendChild( SIAAttributeText );
2793 SIAFeatureElem.appendChild( SIAAttributeElem );
2796 SIAInfoDocElement.appendChild( SIAFeatureElem );
2803 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2806 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2809 featureInfoString.append( QStringLiteral( R
"HTML(
2812 <title>Information</title>
2813 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2816 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2823 border: 1px solid black;
2824 border-collapse: collapse;
2845 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2848 for (
int i = 0; i < layerList.size(); ++i )
2850 const QDomElement layerElem = layerList.at( i ).toElement();
2853 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2854 const QDomElement currentFeatureElement;
2856 if ( !featureNodeList.isEmpty() )
2860 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2861 featureInfoString.append( featureInfoLayerTitleString );
2864 for (
int j = 0; j < featureNodeList.size(); ++j )
2866 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2869 featureInfoString.append( QStringLiteral( R
"HTML(
2874 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2875 for (
int k = 0; k < attributeNodeList.size(); ++k )
2877 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2878 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2879 QString value = attributeElement.attribute( u
"value"_s );
2880 if ( name !=
"maptip"_L1 )
2882 value = value.toHtmlEscaped();
2887 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2892 .arg( name, value );
2894 featureInfoString.append( featureInfoAttributeString );
2896 else if ( name ==
"maptip"_L1 )
2898 featureInfoString.append( QStringLiteral( R
"HTML(
2906 featureInfoString.append( QStringLiteral( R
"HTML(
2913 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2916 if ( !attributeNodeList.isEmpty() )
2920 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2921 featureInfoString.append( featureInfoLayerTitleString );
2923 featureInfoString.append( QStringLiteral( R
"HTML(
2927 for (
int j = 0; j < attributeNodeList.size(); ++j )
2929 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2930 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2931 QString value = attributeElement.attribute( u
"value"_s );
2932 if ( value.isEmpty() )
2934 value = u
"no data"_s;
2936 if ( name !=
"maptip"_L1 )
2938 value = value.toHtmlEscaped();
2943 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2948 .arg( name, value );
2951 featureInfoString.append( featureInfoAttributeString );
2953 else if ( name ==
"maptip"_L1 )
2955 featureInfoString.append( QStringLiteral( R
"HTML(
2963 featureInfoString.append( QStringLiteral( R
"HTML(
2973 featureInfoString.append( QStringLiteral( R
"HTML(
2977 return featureInfoString.toUtf8();
2980 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2982 QString featureInfoString;
2985 featureInfoString.append(
"GetFeatureInfo results\n" );
2986 featureInfoString.append(
"\n" );
2988 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2991 for (
int i = 0; i < layerList.size(); ++i )
2993 QDomElement layerElem = layerList.at( i ).toElement();
2995 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2998 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2999 QDomElement currentFeatureElement;
3001 if ( !featureNodeList.isEmpty() )
3003 for (
int j = 0; j < featureNodeList.size(); ++j )
3005 QDomElement featureElement = featureNodeList.at( j ).toElement();
3006 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
3009 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
3010 for (
int k = 0; k < attributeNodeList.size(); ++k )
3012 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
3013 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
3019 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
3020 for (
int j = 0; j < attributeNodeList.size(); ++j )
3022 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
3023 QString value = attributeElement.attribute( u
"value"_s );
3024 if ( value.isEmpty() )
3026 value = u
"no data"_s;
3028 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
3032 featureInfoString.append(
"\n" );
3035 return featureInfoString.toUtf8();
3038 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
3040 json jsonCollection {
3041 {
"type",
"FeatureCollection" },
3042 {
"features", json::array() },
3046 const bool withDisplayName = mWmsParameters.withDisplayName();
3048 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
3049 for (
int i = 0; i < layerList.size(); ++i )
3051 const QDomElement layerElem = layerList.at( i ).toElement();
3052 const QString layerName = layerElem.attribute( u
"name"_s );
3054 QgsMapLayer *layer =
nullptr;
3055 for ( QgsMapLayer *l : layers )
3057 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3068 QStringList requestedWmsNames = mContext.acceptableLayersToRender().value( layer );
3069 requestedWmsNames.removeAll( layerName );
3070 QString requestedWmsName;
3071 if ( !requestedWmsNames.isEmpty() )
3073 requestedWmsName = requestedWmsNames.first();
3078 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3083 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3084 if ( featuresNode.isEmpty() )
3087 QMap<QgsFeatureId, QString> fidMap;
3088 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3090 for (
int j = 0; j < featuresNode.size(); ++j )
3092 const QDomElement featureNode = featuresNode.at( j ).toElement();
3093 const QString fid = featureNode.attribute( u
"id"_s );
3096 if ( expression.isEmpty() )
3098 feature = vl->
getFeature( fid.toLongLong() );
3102 QgsFeatureRequest request { QgsExpression( expression ) };
3107 fidMap.insert( feature.
id(), fid );
3112 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3113 for (
int k = 0; k < attrs.count(); k++ )
3115 const QDomElement elm = attrs.at( k ).toElement();
3116 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3118 wkt = elm.attribute(
"value" );
3123 if ( !wkt.isEmpty() )
3131 if ( withDisplayName )
3133 QString displayName;
3134 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3135 for (
int k = 0; k < attrs.count(); k++ )
3137 const QDomElement elm = attrs.at( k ).toElement();
3138 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3140 displayName = elm.attribute(
"value" );
3144 fidDisplayNameMap.insert( feature.
id(), displayName );
3147 features << feature;
3150 if ( !attributes.isEmpty() )
3153 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3154 for (
int k = 0; k < attributesNode.size(); ++k )
3156 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3157 const QString fieldName = attributeElement.attribute( u
"name"_s );
3158 attributes << feature.fieldNameIndex( fieldName );
3163 QgsJsonExporter exporter( vl );
3164 exporter.setAttributeDisplayName(
true );
3165 exporter.setAttributes( attributes );
3166 exporter.setIncludeGeometry( withGeometry );
3170 exporter.setTransformGeometries(
false );
3171 exporter.setDestinationCrs( destCRS );
3173 exporter.setSourceCrs( destCRS );
3177 for (
const auto &feature : std::as_const( features ) )
3179 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3180 QVariantMap extraProperties;
3181 if ( withDisplayName )
3183 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3185 QVariantMap extraMembers;
3189 if ( !requestedWmsName.isEmpty() )
3194 jsonCollection[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id, extraMembers ) );
3199 auto properties = json::object();
3200 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3201 for (
int j = 0; j < attributesNode.size(); ++j )
3203 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3204 const QString name = attrElmt.attribute( u
"name"_s );
3206 QString value = attrElmt.attribute( u
"value"_s );
3207 if ( value.isEmpty() )
3212 properties[name.toStdString()] = value.toStdString();
3215 json jsonFeature = { {
"type",
"Feature" }, {
MEMBERNAME_FEATURETYPE, layerName.toStdString() }, {
"id", layerName.toStdString() }, {
"properties", properties } };
3217 if ( !requestedWmsName.isEmpty() )
3221 jsonCollection[
"features"].push_back( jsonFeature );
3226 return QByteArray::fromStdString( jsonCollection.dump( 2 ) );
3228 return QByteArray::fromStdString( jsonCollection.dump() );
3232 QDomElement QgsRenderer::createFeatureGML(
3233 const QgsFeature *feat, QgsVectorLayer *layer, QDomDocument &doc, QgsCoordinateReferenceSystem &crs,
const QgsMapSettings &mapSettings,
const QString &typeName,
bool withGeom,
int version, QStringList *attributes
3237 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3244 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3246 QgsCoordinateTransform transform;
3247 if ( layer && layer->
crs() != crs )
3252 QgsGeometry geom = feat->
geometry();
3254 QgsExpressionContext expressionContext;
3260 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3274 catch ( QgsCsException &e )
3280 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3281 QDomElement boxElem;
3293 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3295 bbElem.appendChild( boxElem );
3296 typeNameElement.appendChild( bbElem );
3300 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3301 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3302 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3305 const QList<QgsAttributeEditorElement *> children = container->
children();
3306 for (
const QgsAttributeEditorElement *child : children )
3308 switch ( child->type() )
3312 if ( findAttributeInTree( attributeName, child ) )
3320 if ( child->name() == attributeName )
3328 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3329 if ( relationEditor )
3331 const QgsRelation &relation { relationEditor->
relation() };
3335 for (
const auto &idx : std::as_const( referencedFields ) )
3337 const QgsField f { layer->
fields().
at( idx ) };
3338 if ( f.
name() == attributeName )
3347 for (
const auto &idx : std::as_const( referencingFields ) )
3349 const QgsField f { layer->
fields().
at( idx ) };
3350 if ( f.
name() == attributeName )
3367 if ( withGeom && !geom.
isNull() )
3376 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3377 QDomElement gmlElem;
3387 if ( !gmlElem.isNull() )
3391 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3393 geomElem.appendChild( gmlElem );
3394 typeNameElement.appendChild( geomElem );
3399 QgsAttributes featureAttributes = feat->
attributes();
3400 QgsFields fields = feat->
fields();
3401 for (
int i = 0; i < fields.
count(); ++i )
3403 QString attributeName = fields.
at( i ).
name();
3410 if ( attributes && !attributes->contains( attributeName ) )
3415 if ( honorFormConfig )
3418 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3424 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3429 fieldElem.setAttribute(
"xsi:nil"_L1,
"true"_L1 );
3433 QString fieldTextString = featureAttributes.at( i ).toString();
3438 QDomText fieldText = doc.createTextNode( fieldTextString );
3439 fieldElem.appendChild( fieldText );
3441 typeNameElement.appendChild( fieldElem );
3452 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3453 QDomText maptipText = doc.createTextNode( fieldTextString );
3454 fieldElem.appendChild( maptipText );
3455 typeNameElement.appendChild( fieldElem );
3459 return typeNameElement;
3462 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3466 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3468 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3470 value = value.mid( 1, value.size() - 2 );
3475 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3479 return QgsRectangle();
3482 double mapUnitTolerance = 0.0;
3485 if ( !mWmsParameters.polygonTolerance().isEmpty() && mWmsParameters.polygonToleranceAsInt() > 0 )
3491 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3496 if ( !mWmsParameters.lineTolerance().isEmpty() && mWmsParameters.lineToleranceAsInt() > 0 )
3502 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3507 if ( !mWmsParameters.pointTolerance().isEmpty() && mWmsParameters.pointToleranceAsInt() > 0 )
3513 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3520 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3524 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3526 QList<QgsMapLayer *> highlightLayers;
3529 QString crs = mWmsParameters.crs();
3530 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3533 QDomDocument sldDoc;
3537 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3544 std::unique_ptr<QgsFeatureRenderer> renderer;
3545 QDomElement el = sldDoc.documentElement();
3555 QString url = typeName +
"?crs=" + crs;
3556 if ( !param.mLabel.isEmpty() )
3558 url +=
"&field=label:string";
3563 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3570 QgsFeature fet( layer->
fields() );
3571 if ( !param.mLabel.isEmpty() )
3573 fet.setAttribute( 0, param.mLabel );
3576 QgsPalLayerSettings palSettings;
3581 palSettings.
dist = param.mLabelDistance;
3590 switch ( param.mGeom.type() )
3601 QgsPointXY pt = param.mGeom.asPoint();
3603 QVariant x( pt.
x() );
3606 QVariant y( pt.
y() );
3618 QgsGeometry point = param.mGeom.pointOnSurface();
3619 QgsPointXY pt = point.
asPoint();
3623 QVariant x( pt.
x() );
3627 QVariant y( pt.
y() );
3631 QVariant hali(
"Center" );
3635 QVariant vali(
"Half" );
3647 QgsTextFormat textFormat;
3648 QgsTextBufferSettings bufferSettings;
3650 if ( param.mColor.isValid() )
3652 textFormat.
setColor( param.mColor );
3655 if ( param.mSize > 0 )
3657 textFormat.
setSize( param.mSize );
3665 if ( !param.mFont.isEmpty() )
3667 textFormat.
setFont( param.mFont );
3670 if ( param.mBufferColor.isValid() )
3672 bufferSettings.
setColor( param.mBufferColor );
3675 if ( param.mBufferSize > 0 )
3678 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3681 if ( param.mFrameSize > 0 )
3683 QgsTextBackgroundSettings background;
3685 background.
setSize( QSize( param.mFrameSize, param.mFrameSize ) );
3689 background.
setFillColor( param.mFrameBackgroundColor );
3696 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3700 fet.setGeometry( param.mGeom );
3709 highlightLayers.append( layer.release() );
3713 mTemporaryLayers.append( highlightLayers );
3714 return highlightLayers;
3717 void QgsRenderer::removeTemporaryLayers()
3719 qDeleteAll( mTemporaryLayers );
3720 mTemporaryLayers.clear();
3723 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3725 QPainter *painter =
nullptr;
3727 QgsFeatureFilterProviderGroup filters;
3729#ifdef HAVE_SERVER_PYTHON_PLUGINS
3730 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3733 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3735 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3736 painter = renderJob.takePainter();
3738 logRenderingErrors( renderJob.errors() );
3740 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3742 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3744 QString layerWMSName;
3745 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3748 layerWMSName = mContext.layerNickname( *errorLayer );
3751 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3752 if ( !layerWMSName.isEmpty() )
3754 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3756 throw QgsException( errorMessage );
3762 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3764 if ( opacity >= 0 && opacity <= 255 )
3766 switch ( layer->
type() )
3770 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3775 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3783 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3784 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3785 rasterRenderer->
setOpacity( opacity / 255. );
3791 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3807 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3811 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3812 QStringList expList;
3813 for (
const QgsWmsParametersFilter &filter : filters )
3818 QDomDocument filterXml;
3820 QXmlStreamReader xmlReader( filter.mFilter );
3821 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3822 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3823 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3825 throw QgsBadRequestException(
3827 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 )
3831 QDomElement filterElem = filterXml.firstChildElement();
3836 expList << filterExp->dump();
3842 if ( !testFilterStringSafety( filter.mFilter ) )
3844 throw QgsSecurityException(
3846 "The filter string %1"
3847 " has been rejected because of security reasons."
3848 " Note: Text strings have to be enclosed in single or double quotes."
3849 " A space between each word / special character is mandatory."
3850 " Allowed Keywords and special characters are"
3851 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3852 " Not allowed are semicolons in the filter expression."
3854 .arg( filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' ) )
3858 QString newSubsetString = filter.mFilter;
3861 newSubsetString.prepend(
") AND (" );
3862 newSubsetString.append(
")" );
3863 newSubsetString.prepend( filteredLayer->
subsetString() );
3864 newSubsetString.prepend(
"(" );
3874 expList.append( dimensionFilter( filteredLayer ) );
3878 if ( expList.size() == 1 )
3882 else if ( expList.size() > 1 )
3884 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3886 if ( !exp.isEmpty() )
3888 auto expression = std::make_unique<QgsExpression>( exp );
3892 mFeatureFilter.setFilter( filteredLayer, *expression );
3899 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3901 QStringList expList;
3903 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3904 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3905 if ( wmsDims.isEmpty() )
3910 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3911 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3920 if ( fieldIndex == -1 )
3925 int endFieldIndex = -1;
3926 if ( !dim.endFieldName.isEmpty() )
3928 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3929 if ( endFieldIndex == -1 )
3935 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3945 defValue = dim.referenceValue();
3950 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3951 if ( endFieldIndex != -1 )
3953 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3956 QList<QVariant> values = qgis::setToList( uniqueValues );
3957 std::sort( values.begin(), values.end() );
3960 defValue = values.first();
3964 defValue = values.last();
3968 if ( endFieldIndex == -1 )
3974 QStringList expElems;
3983 expList << expElems.join(
' ' );
3989 QgsField dimField = layer->
fields().
at( fieldIndex );
3991 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3993 QStringList dimExplist;
3995 QStringList dimValues = dimParamValue.split(
',' );
3996 for (
int i = 0; i < dimValues.size(); ++i )
3998 QString dimValue = dimValues[i];
4000 if ( dimValue.size() > 1 )
4002 dimValue = dimValue.trimmed();
4005 if ( dimValue.contains(
'/' ) )
4007 QStringList rangeValues = dimValue.split(
'/' );
4009 if ( rangeValues.size() != 2 )
4014 QVariant rangeMin = QVariant( rangeValues[0] );
4015 QVariant rangeMax = QVariant( rangeValues[1] );
4026 QStringList expElems;
4027 if ( endFieldIndex == -1 )
4062 dimExplist << expElems.join(
' ' );
4066 QVariant dimVariant = QVariant( dimValue );
4072 if ( endFieldIndex == -1 )
4081 QStringList expElems;
4090 dimExplist << expElems.join(
' ' );
4095 if ( dimExplist.size() == 1 )
4097 expList << dimExplist;
4099 else if ( dimExplist.size() > 1 )
4101 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
4108 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4112 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4114 QgsFeatureRequest request;
4118 if ( selectedIds.empty() )
4129 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4131#ifdef HAVE_SERVER_PYTHON_PLUGINS
4138 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4141 QgsRectangle mapExtent = mapSettings.
extent();
4149 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4151 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4152 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4156 renderContext.
setFeedback( mContext.socketFeedback() );
4158 for ( QgsAnnotation *annotation : annotations )
4160 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4162 if ( !annotation || !annotation->isVisible() )
4168 if ( annotation->hasFixedMapPosition() )
4170 QgsPointXY mapPos = annotation->mapPosition();
4171 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4176 mapPos = coordTransform.transform( mapPos );
4178 catch (
const QgsCsException &e )
4184 offsetX = devicePos.
x();
4185 offsetY = devicePos.
y();
4189 const QPointF relativePos = annotation->relativePosition();
4190 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4191 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4195 painter->translate( offsetX, offsetY );
4196 annotation->render( renderContext );
4201 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4206 QImage *scaledImage =
nullptr;
4207 const int width = mWmsParameters.widthAsInt();
4208 const int height = mWmsParameters.heightAsInt();
4209 if ( width != image->width() || height != image->height() )
4211 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4219 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4220 for ( ; it != errors.constEnd(); ++it )
4222 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4223 if ( !it->layerID.isEmpty() )
4225 msg += QString(
" in layer %1" ).arg( it->layerID );
4231 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4238 QList<QgsLayoutItemMap *> mapList;
4242 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4243 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4245 logRenderingErrors( ( *mapIt )->renderingErrors() );
4248 if ( mContext.settings().ignoreRenderingErrors() )
4253 mapIt = mapList.constBegin();
4254 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4256 if ( !( *mapIt )->renderingErrors().isEmpty() )
4258 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4259 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4266 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4268 for (
auto layer : layers )
4270 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4272 if ( !mContext.layersToRender().contains( layer ) )
4277 if ( mContext.isExternalLayer( param.mNickname ) )
4281 setLayerOpacity( layer, param.mOpacity );
4288 setLayerSld( layer, mContext.sld( *layer ) );
4292 setLayerStyle( layer, mContext.style( *layer ) );
4297 setLayerOpacity( layer, param.mOpacity );
4302 setLayerFilter( layer, param.mFilter );
4307 setLayerAccessControlFilter( layer );
4312 setLayerSelection( layer, param.mSelection );
4315 if ( settings && mContext.updateExtent() )
4317 updateExtent( layer, *settings );
4323 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4327 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4329 if ( style.isEmpty() )
4341 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4346 QString sldStyleName =
"__sld_style";
4347 while ( styles.contains( sldStyleName ) )
4349 sldStyleName.append(
'@' );
4357 QgsLegendSettings QgsRenderer::legendSettings()
4360 QgsLegendSettings settings = mWmsParameters.legendSettings();
4362 if ( !mWmsParameters.bbox().isEmpty() )
4364 QgsMapSettings mapSettings;
4366 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4367 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
@ MinValue
Display minimum value of the dimension.
@ AllValues
Display all values of the dimension.
@ MaxValue
Display maximum value of the dimension.
@ ReferenceValue
Display a reference value.
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
Export all lines with minimum width and don't fill polygons.
@ 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 std::unique_ptr< 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, Qgis::GeoJsonProfile profile=Qgis::GeoJsonProfile::Legacy)
Add crs information entry in json object regarding old GeoJSON specification format if it differs fro...
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
void removeChildrenGroupWithoutLayers()
Remove all child group nodes without layers.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
@ RuleKey
Rule key of the node (QString).
virtual QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const
Draws symbol on the left side of the item.
A model representing the layer tree, including layers and groups of layers.
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
QgsLayerTreeModelLegendNode * findLegendNode(const QString &layerId, const QString &ruleKey) const
Searches through the layer tree to find a legend node with a matching layer ID and rule key.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
bool beginRender() override
Called when rendering begins, before iteration commences.
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
bool first()
Seeks to the first feature, returning false if no feature was found.
QgsLayout * layout() override
Returns the layout associated with the iterator.
bool enabled() const
Returns whether the atlas generation is enabled.
int count() const override
Returns the number of features to iterate over.
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
Handles rendering and exports of layouts to various formats.
ExportResult exportToSvg(const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings)
Exports the layout as an SVG to the filePath, using the specified export settings.
ExportResult exportToImage(const QString &filePath, const QgsLayoutExporter::ImageExportSettings &settings)
Exports the layout to the filePath, using the specified export settings.
ExportResult exportToPdf(const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings)
Exports the layout as a PDF to the filePath, using the specified export settings.
@ ManualHtml
HTML content is manually set for the item.
@ Url
Using this mode item fetches its content via a url.
Layout graphical items for displaying a map.
double scale() const
Returns the map scale.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
QString id() const
Returns the item's ID name.
Manages storage of a set of layouts.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
double length() const
Returns the length of the measurement.
int pageCount() const
Returns the number of pages in the collection.
Stores information relating to the current rendering settings for a layout.
void setFeatureFilterProvider(QgsFeatureFilterProvider *featureFilterProvider)
Sets feature filter provider to featureFilterProvider.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
static QVector< double > predefinedScales(const QgsLayout *layout)
Returns a list of predefined scales associated with a layout.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Handles automatic layout and rendering of legends.
QSizeF minimumSize(QgsRenderContext *renderContext=nullptr)
Runs the layout algorithm and returns the minimum size required for the legend.
QJsonObject exportLegendToJson(const QgsRenderContext &context)
Renders the legend in a json object.
Q_DECL_DEPRECATED void drawLegend(QPainter *painter)
Draws the legend with given painter.
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
Q_DECL_DEPRECATED void setMapScale(double scale)
Sets the legend map scale.
Q_DECL_DEPRECATED void setMapUnitsPerPixel(double mapUnitsPerPixel)
Sets the mmPerMapUnit calculated by mapUnitsPerPixel mostly taken from the map settings.
void setJsonRenderFlags(const Qgis::LegendJsonRenderFlags &jsonRenderFlags)
Sets the JSON export flags to jsonRenderFlags.
void setWmsLegendSize(QSizeF s)
Sets the desired size (in millimeters) of WMS legend graphics shown in the legend.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual bool readSld(const QDomNode &node, QString &errorMessage)
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QList< QgsMapRendererJob::Error > Errors
Contains configuration for rendering maps.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for scale calculations for the map.
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
void setSelectiveMaskingSourceSets(const QVector< QgsSelectiveMaskingSourceSet > &sets)
Sets a list of all selective masking source sets defined for the map.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
QColor selectionColor() const
Returns the color that is used for drawing of selected vector features.
void setExtentBuffer(double buffer)
Sets the buffer in map units to use around the visible extent for rendering symbols whose correspondi...
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
QString ellipsoid() const
Returns ellipsoid's acronym.
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QList< QgsMapThemeCollection::MapThemeLayerRecord > layerRecords() const
Returns a list of records for all visible layer belonging to the theme.
QgsMapThemeCollection::MapThemeRecord mapThemeState(const QString &name) const
Returns the recorded state of a map theme.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
double y() const
Returns y value.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
QgsMeshRendererSettings rendererSettings() const
Returns renderer settings.
QgsMeshDatasetIndex activeVectorDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active vector group depending on the time range If the temporal properties...
void updateTriangularMesh(const QgsCoordinateTransform &transform=QgsCoordinateTransform())
Gets native mesh and updates (creates if it doesn't exist) the base triangular mesh.
QgsMeshDatasetIndex staticVectorDatasetIndex(int group=-1) const
Returns the static vector dataset index that is rendered if the temporal properties is not active.
QList< int > enabledDatasetGroupsIndexes() const
Returns the list of indexes of enables dataset groups handled by the layer.
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset metadata.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMeshDatasetIndex datasetIndexAtTime(const QgsDateTimeRange &timeRange, int datasetGroupIndex) const
Returns dataset index from datasets group depending on the time range.
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsMeshDatasetIndex activeScalarDatasetAtTime(const QgsDateTimeRange &timeRange, int group=-1) const
Returns dataset index from active scalar group depending on the time range.
QgsTriangularMesh * triangularMesh(double minimumTriangleSize=0) const
Returns triangular mesh (nullptr before rendering or calling to updateMesh).
QgsMeshDatasetIndex staticScalarDatasetIndex(int group=-1) const
Returns the static scalar dataset index that is rendered if the temporal properties is not active.
QString formatTime(double hours)
Returns (date) time in hours formatted to human readable form.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
int activeVectorDatasetGroup() const
Returns the active vector dataset group.
int activeScalarDatasetGroup() const
Returns the active scalar dataset group.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
static QDomElement rectangleToGMLEnvelope(const QgsRectangle *env, QDomDocument &doc, int precision=17)
Exports the rectangle to GML3 Envelope.
static QDomElement geometryToGML(const QgsGeometry &geometry, QDomDocument &doc, QgsOgcUtils::GMLVersion gmlVersion, const QString &srsName, bool invertAxisOrientation, const QString &gmlIdBase, int precision=17)
Exports the geometry to GML.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
static QDomElement rectangleToGMLBox(const QgsRectangle *box, QDomDocument &doc, int precision=17)
Exports the rectangle to GML2 Box.
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
Qgis::LabelPlacement placement
Label placement mode.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
int priority
Label priority.
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
double dist
Distance from feature to the label.
Property
Data definable properties.
@ PositionX
X-coordinate data defined label position.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top).
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right).
QString fieldName
Name of field (or an expression) to use for label text.
void setY(double y)
Sets the y value of the point.
void setX(double x)
Sets the x value of the point.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
QgsPrintLayout * clone() const override
Creates a clone of the layout.
Describes the version of a project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsMapThemeCollection * mapThemeCollection
QgsProjectMetadata metadata
QgsCoordinateTransformContext transformContext
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, Qgis::RasterIdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
bool isValid() const
Returns true if valid.
QMap< int, QVariant > results() const
Returns the identify results.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QString bandName(int bandNoInt) const
Returns the name of a band given its number.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
A rectangle specified with double values.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
QList< int > referencedFields
QgsVectorLayer * referencedLayer
QgsVectorLayer * referencingLayer
QList< int > referencingFields
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
void setDistanceArea(const QgsDistanceArea &distanceArea)
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
void setFeedback(QgsFeedback *feedback)
Attach a feedback object that can be queried regularly during rendering to check if rendering should ...
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Scoped object for temporary scaling of a QgsRenderContext for millimeter based rendering.
static QgsDateTimeRange parseTemporalDateTimeInterval(const QString &interval)
Parses a datetime interval and returns a QgsDateTimeRange.
Exception base class for server exceptions.
static QString getExpressionFromServerFid(const QString &serverFid, const QgsVectorDataProvider *provider)
Returns the expression feature id based on primary keys.
static QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
static QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
static QString wmsFeatureInfoSchema(const QgsProject &project)
Returns the schema URL for XML GetFeatureInfo request.
static bool wmsInfoFormatSia2045(const QgsProject &project)
Returns if the info format is SIA20145.
static bool wmsHTMLFeatureInfoUseOnlyMaptip(const QgsProject &project)
Returns if only the maptip should be used for HTML feature info response so that the HTML response to...
static QString wmsFeatureInfoDocumentElementNs(const QgsProject &project)
Returns the document element namespace for XML GetFeatureInfo request.
static QStringList wmsRestrictedComposers(const QgsProject &project)
Returns the restricted composer list.
static bool wmsFeatureInfoSegmentizeWktGeometry(const QgsProject &project)
Returns if the geometry has to be segmentize in GetFeatureInfo request.
static bool wmsFeatureInfoUseAttributeFormSettings(const QgsProject &project)
Returns if feature form settings should be considered for the format of the feature info response.
static QHash< QString, QString > wmsFeatureInfoLayerAliasMap(const QgsProject &project)
Returns the mapping between layer name and wms layer name for GetFeatureInfo request.
static bool wmsFeatureInfoAddWktGeometry(const QgsProject &project)
Returns if the geometry is displayed as Well Known Text in GetFeatureInfo request.
static double wmsDefaultMapUnitsPerMm(const QgsProject &project)
Returns the default number of map units per millimeters in case of the scale is not given.
static QString wmsFeatureInfoDocumentElement(const QgsProject &project)
Returns the document element name for XML GetFeatureInfo request.
static int wmsMaxAtlasFeatures(const QgsProject &project)
Returns the maximum number of atlas features which can be printed in a request.
const QList< QgsServerWmsDimensionProperties::WmsDimensionInfo > wmsDimensions() const
Returns the QGIS Server WMS Dimension list.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
@ Hidden
Hide task from GUI.
bool isActive() const
Returns true if the temporal property is active.
void setIsActive(bool active)
Sets whether the temporal property is active.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
bool isInstant() const
Returns true if the range consists only of a single instant.
void setStrokeColor(const QColor &color)
Sets the color used for outlining the background shape.
@ ShapeRectangle
Rectangle.
void setFillColor(const QColor &color)
Sets the color used for filing the background shape.
void setType(ShapeType type)
Sets the type of background shape to draw (e.g., square, ellipse, SVG).
void setEnabled(bool enabled)
Sets whether the text background will be drawn.
void setSize(QSizeF size)
Sets the size of the background shape.
void setStrokeWidth(double width)
Sets the width of the shape's stroke (stroke).
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.
void setBackground(const QgsTextBackgroundSettings &backgroundSettings)
Sets the text's background settings.q.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Represents a vector layer which manages a vector based dataset.
void setLabeling(QgsAbstractVectorLayerLabeling *labeling)
Sets labeling configuration.
Q_INVOKABLE QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
void updateFields()
Will regenerate the fields property of this layer by obtaining all fields from the dataProvider,...
void setLabelsEnabled(bool enabled)
Sets whether labels should be enabled for the layer.
Q_INVOKABLE void selectByExpression(const QString &expression, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, QgsExpressionContext *context=nullptr)
Selects matching features using an expression.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
void setRenderer(QgsFeatureRenderer *r)
Sets the feature renderer which will be invoked to represent this layer in 2D map views.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QString displayExpression
QgsEditorWidgetSetup editorWidgetSetup(int index) const
Returns the editor widget setup for the field at the specified index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE void selectByIds(const QgsFeatureIds &ids, Qgis::SelectBehavior behavior=Qgis::SelectBehavior::SetSelection, bool validateIds=false)
Selects matching features using a list of feature IDs.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
virtual bool setSubsetString(const QString &subset)
Sets the string (typically sql) used to define a subset of the layer.
QgsAttributeList primaryKeyAttributes() const
Returns the list of attributes which make up the layer's primary keys.
QgsEditFormConfig editFormConfig
Q_INVOKABLE QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const final
Calculates a list of unique values contained within an attribute in the layer.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Q_INVOKABLE bool isCurvedType(Qgis::WkbType type)
Returns true if the WKB type is a curved type or can contain curved geometries.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
Implementation of legend node interface for displaying WMS legend entries.
Exception thrown in case of malformed request.
QgsRenderer(const QgsWmsRenderContext &context)
Constructor for QgsRenderer.
QHash< QgsVectorLayer *, SymbolSet > HitTest
QByteArray getPrint()
Returns printed page as binary.
HitTest symbols()
Returns the hit test according to the current context.
std::unique_ptr< QgsDxfExport > getDxf()
Returns the map as DXF data.
QSet< QString > SymbolSet
void configureLayers(QList< QgsMapLayer * > &layers, QgsMapSettings *settings=nullptr)
Configures layers for rendering optionally considering the map settings.
std::unique_ptr< QgsMapRendererTask > getPdf(const QString &tmpFileName)
Returns a configured pdf export task.
QByteArray getFeatureInfo(const QString &version="1.3.0")
Creates an xml document that describes the result of the getFeatureInfo request.
QImage * getLegendGraphics(QgsLayerTreeModel &model)
Returns the map legend as an image (or nullptr in case of error).
std::unique_ptr< QImage > getMap()
Returns the map as an image (or nullptr in case of error).
QJsonObject getLegendGraphicsAsJson(QgsLayerTreeModel &model, const Qgis::LegendJsonRenderFlags &jsonRenderFlags=Qgis::LegendJsonRenderFlags())
Returns the map legend as a JSON object.
Exception class for WMS service exceptions.
ExceptionCode
Exception codes as defined in OGC scpecifications for WMS 1.1.1 and WMS 1.3.0.
@ QGIS_InvalidParameterValue
@ QGIS_MissingParameterValue
WMS parameter received from the client.
bool transparentAsBool() const
Returns TRANSPARENT parameter as a bool or its default value if not defined.
QString formatAsString() const
Returns FORMAT parameter as a string.
QgsWmsParametersComposerMap composerMapParameters(int mapId) const
Returns the requested parameters for a composer map parameter.
DxfFormatOption
Options for DXF format.
QColor backgroundColorAsColor() const
Returns BGCOLOR parameter as a QColor or its default value if not defined.
Format format() const
Returns format.
Format
Output format for the response.
Rendering context for the WMS renderer.
QList< QgsMapLayer * > layersToRender() const
Returns a list of all layers to actually render according to the current configuration.
void setScaleDenominator(double scaleDenominator)
Sets a custom scale denominator.
Median cut implementation.
constexpr const char * MEMBERNAME_QGIS_REQUESTEDWMSNAME
QgsLayerTreeModelLegendNode * legendNode(const QString &rule, QgsLayerTreeModel &model)
constexpr const char * MEMBERNAME_FEATURETYPE
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define Q_NOWARN_DEPRECATED_POP
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
#define Q_NOWARN_DEPRECATED_PUSH
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
#define FID_TO_STRING(fid)
QVector< QgsFeatureStore > QgsFeatureStoreList
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
QgsAbstractMetadataBase::KeywordMap keywords
Metadata keyword map.
QString creator
Metadata creator tag.
QString author
Metadata author tag.
QString subject
Metadata subject tag.
QString title
Metadata title tag.
QDateTime creationDateTime
Metadata creation datetime.
QString producer
Metadata producer tag.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO32000 extension format georeferencing should be used.
Encapsulates the properties of a vector layer containing features that will be exported to the DXF fi...
QPainter * painter
Painter.
Q_NOWARN_DEPRECATED_POP QgsRenderContext * context
Render context, if available.
Contains settings relating to exporting layouts to raster images.
QList< int > pages
List of specific pages to export, or an empty list to export all pages.
QSize imageSize
Manual size in pixels for output image.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
Contains settings relating to exporting layouts to PDF.
bool useIso32000ExtensionFormatGeoreferencing
true if ISO3200 extension format georeferencing should be used.
bool forceVectorOutput
Set to true to force vector object exports, even when the resultant appearance will differ from the l...
bool rasterizeWholeImage
Set to true to force whole layout to be rasterized while exporting.
QStringList exportThemes
Optional list of map themes to export as Geospatial PDF layer groups.
bool appendGeoreference
Indicates whether PDF export should append georeference data.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
bool writeGeoPdf
true if geospatial PDF files should be created, instead of normal PDF files.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
bool simplifyGeometries
Indicates whether vector geometries should be simplified to avoid redundant extraneous detail,...
Qgis::TextRenderFormat textRenderFormat
Text rendering format, which controls how text should be rendered in the export (e....
Contains settings relating to exporting layouts to SVG.
Qgis::LayoutRenderFlags flags
Layout context flags, which control how the export will be created.
double dpi
Resolution to export layout at. If dpi <= 0 the default layout dpi will be used.
QVector< qreal > predefinedMapScales
A list of predefined scales to use with the layout.
QList< QgsWmsParametersLayer > mLayers
QList< QgsWmsParametersHighlightLayer > mHighlightLayers