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 );
1235 ms.
setExtent( mWmsParameters.bboxAsRectangle() );
1236 ms.
setLayers( mContext.layersToRender() );
1238 ms.
setOutputSize( QSize( mWmsParameters.widthAsInt(), mWmsParameters.heightAsInt() ) );
1242 if ( mWmsParameters.pdfExportMetadata() )
1253 const bool geospatialPdf = mWmsParameters.pdfAppendGeoreference();
1254 auto pdf = std::make_unique<QgsMapRendererTask>( ms, tmpFileName, u
"PDF"_s,
false,
QgsTask::Hidden, geospatialPdf, pdfExportDetails );
1255 if ( mWmsParameters.pdfAppendGeoreference() )
1257 pdf->setSaveWorldFile(
true );
1265 if ( i < 0 || i > mapSettings.
outputSize().width() )
1272 if ( j < 0 || j > mapSettings.
outputSize().height() )
1289 if ( mWmsParameters.queryLayersNickname().isEmpty() )
1295 const bool ijDefined = !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty();
1296 const bool xyDefined = !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty();
1297 const bool filtersDefined = !mWmsParameters.filters().isEmpty();
1298 const bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1300 if ( !ijDefined && !xyDefined && !filtersDefined && !filterGeomDefined )
1304 if ( mWmsParameters.j().isEmpty() )
1317 std::unique_ptr<QImage> outputImage( createImage( mContext.mapSize() ) );
1320 std::unique_ptr<QgsWmsRestorer> restorer;
1321 restorer = std::make_unique<QgsWmsRestorer>( mContext );
1325 bool mandatoryCrsParam =
true;
1326 if ( filtersDefined && !ijDefined && !xyDefined && mWmsParameters.crs().isEmpty() )
1328 mandatoryCrsParam =
false;
1334 configureMapSettings( outputImage.get(), mapSettings, mandatoryCrsParam );
1339 const double scaleDenominator = scaleCalc.
calculate( mWmsParameters.bboxAsRectangle(), outputImage->width() );
1351#ifdef HAVE_SERVER_PYTHON_PLUGINS
1352 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
1355 QDomDocument result = featureInfoDocument( layers, mapSettings, outputImage.get(), version );
1360 ba = convertFeatureInfoToText( result );
1362 ba = convertFeatureInfoToHtml( result );
1364 ba = convertFeatureInfoToJson( layers, result, mapSettings.
destinationCrs() );
1366 ba = result.toByteArray();
1371 QImage *QgsRenderer::createImage(
const QSize &size )
const
1373 std::unique_ptr<QImage> image;
1381 image = std::make_unique<QImage>( size, QImage::Format_ARGB32_Premultiplied );
1386 image = std::make_unique<QImage>( size, QImage::Format_RGB32 );
1391 if ( image->isNull() )
1393 throw QgsException( u
"createImage: image could not be created, check for out of memory conditions"_s );
1396 const int dpm =
static_cast<int>( mContext.dotsPerMm() * 1000.0 );
1397 image->setDotsPerMeterX( dpm );
1398 image->setDotsPerMeterY( dpm );
1400 return image.release();
1403 void QgsRenderer::configureMapSettings(
const QPaintDevice *paintDevice, QgsMapSettings &mapSettings,
bool mandatoryCrsParam )
1407 throw QgsException( u
"configureMapSettings: no paint device"_s );
1410 mapSettings.
setOutputSize( QSize( paintDevice->width(), paintDevice->height() ) );
1413 mapSettings.
setOutputDpi( mContext.dotsPerMm() * 25.4 );
1416 QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
1417 if ( !mWmsParameters.bbox().isEmpty() && mapExtent.
isEmpty() )
1422 QString crs = mWmsParameters.crs();
1423 if ( crs.compare(
"CRS:84", Qt::CaseInsensitive ) == 0 )
1425 crs = QString(
"EPSG:4326" );
1428 else if ( crs.isEmpty() && !mandatoryCrsParam )
1430 crs = QString(
"EPSG:4326" );
1433 QgsCoordinateReferenceSystem outputCRS;
1440 QgsWmsParameter parameter;
1442 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
1453 throw QgsBadRequestException( code, parameter );
1463 if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.
hasAxisInverted() )
1471 mapSettings.
setExtentBuffer( mContext.mapTileBuffer( paintDevice->width() ) );
1477 bool transparent = mWmsParameters.transparentAsBool();
1478 QColor backgroundColor = mWmsParameters.backgroundColorAsColor();
1485 else if ( backgroundColor.isValid() )
1491 QgsExpressionContext context = mProject->createExpressionContext();
1508 if ( mContext.settings().logProfile() )
1518 const QString timeString { mWmsParameters.dimensionValues().value( u
"TIME"_s, QString() ) };
1519 if ( !timeString.isEmpty() )
1521 bool isValidTemporalRange {
true };
1524 const QDateTime dt { QDateTime::fromString( timeString, Qt::DateFormat::ISODateWithMs ) };
1535 catch (
const QgsServerApiBadRequestException &ex )
1537 isValidTemporalRange =
false;
1542 if ( isValidTemporalRange )
1551 QgsRenderContext QgsRenderer::configureDefaultRenderContext( QPainter *painter )
1557 QgsDistanceArea distanceArea = QgsDistanceArea();
1558 distanceArea.
setSourceCrs( QgsCoordinateReferenceSystem( mWmsParameters.crs() ), mProject->transformContext() );
1564 QDomDocument QgsRenderer::featureInfoDocument( QList<QgsMapLayer *> &layers,
const QgsMapSettings &mapSettings,
const QImage *outputImage,
const QString &version )
const
1566 const QStringList queryLayers = mContext.flattenedQueryLayers( mContext.parameters().queryLayersNickname() );
1568 bool ijDefined = ( !mWmsParameters.i().isEmpty() && !mWmsParameters.j().isEmpty() );
1570 bool xyDefined = ( !mWmsParameters.x().isEmpty() && !mWmsParameters.y().isEmpty() );
1572 bool filtersDefined = !mWmsParameters.filters().isEmpty();
1574 bool filterGeomDefined = !mWmsParameters.filterGeom().isEmpty();
1576 int featureCount = mWmsParameters.featureCountAsInt();
1577 if ( featureCount < 1 )
1582 int i = mWmsParameters.iAsInt();
1583 int j = mWmsParameters.jAsInt();
1584 if ( xyDefined && !ijDefined )
1586 i = mWmsParameters.xAsInt();
1587 j = mWmsParameters.yAsInt();
1589 int width = mWmsParameters.widthAsInt();
1590 int height = mWmsParameters.heightAsInt();
1591 if ( ( i != -1 && j != -1 && width != 0 && height != 0 ) && ( width != outputImage->width() || height != outputImage->height() ) )
1593 i *= ( outputImage->width() /
static_cast<double>( width ) );
1594 j *= ( outputImage->height() /
static_cast<double>( height ) );
1598 std::unique_ptr<QgsRectangle> featuresRect;
1599 std::unique_ptr<QgsGeometry> filterGeom;
1600 std::unique_ptr<QgsPointXY> infoPoint;
1602 if ( i != -1 && j != -1 )
1604 infoPoint = std::make_unique<QgsPointXY>();
1605 infoPointToMapCoordinates( i, j, infoPoint.get(), mapSettings );
1607 else if ( filtersDefined )
1609 featuresRect = std::make_unique<QgsRectangle>();
1612 if ( filterGeomDefined )
1614 filterGeom = std::make_unique<QgsGeometry>(
QgsGeometry::fromWkt( mWmsParameters.filterGeom() ) );
1617 QDomDocument result;
1618 const QDomNode header = result.createProcessingInstruction( u
"xml"_s, u
"version=\"1.0\" encoding=\"UTF-8\""_s );
1619 result.appendChild( header );
1621 QDomElement getFeatureInfoElement;
1625 getFeatureInfoElement = result.createElement( u
"wfs:FeatureCollection"_s );
1626 getFeatureInfoElement.setAttribute( u
"xmlns:wfs"_s, u
"http://www.opengis.net/wfs"_s );
1627 getFeatureInfoElement.setAttribute( u
"xmlns:ogc"_s, u
"http://www.opengis.net/ogc"_s );
1628 getFeatureInfoElement.setAttribute( u
"xmlns:gml"_s, u
"http://www.opengis.net/gml"_s );
1629 getFeatureInfoElement.setAttribute( u
"xmlns:ows"_s, u
"http://www.opengis.net/ows"_s );
1630 getFeatureInfoElement.setAttribute( u
"xmlns:xlink"_s, u
"http://www.w3.org/1999/xlink"_s );
1631 getFeatureInfoElement.setAttribute( u
"xmlns:qgs"_s, u
"http://qgis.org/gml"_s );
1632 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1633 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 );
1638 if ( featureInfoElemName.isEmpty() )
1640 featureInfoElemName = u
"GetFeatureInfoResponse"_s;
1643 if ( featureInfoElemNs.isEmpty() )
1645 getFeatureInfoElement = result.createElement( featureInfoElemName );
1649 getFeatureInfoElement = result.createElementNS( featureInfoElemNs, featureInfoElemName );
1653 if ( !featureInfoSchema.isEmpty() )
1655 getFeatureInfoElement.setAttribute( u
"xmlns:xsi"_s, u
"http://www.w3.org/2001/XMLSchema-instance"_s );
1656 getFeatureInfoElement.setAttribute( u
"xsi:schemaLocation"_s, featureInfoSchema );
1659 result.appendChild( getFeatureInfoElement );
1669 for (
const QString &queryLayer : queryLayers )
1671 bool validLayer =
false;
1672 bool queryableLayer =
true;
1673 for ( QgsMapLayer *layer : std::as_const( layers ) )
1675 if ( queryLayer == mContext.layerNickname( *layer ) )
1679 if ( !queryableLayer )
1684 QDomElement layerElement;
1687 layerElement = getFeatureInfoElement;
1691 layerElement = result.createElement( u
"Layer"_s );
1692 QString layerName = queryLayer;
1695 QHash<QString, QString>::const_iterator layerAliasIt = layerAliasMap.constFind( layerName );
1696 if ( layerAliasIt != layerAliasMap.constEnd() )
1698 layerName = layerAliasIt.value();
1701 layerElement.setAttribute( u
"name"_s, layerName );
1702 const QString layerTitle = layer->serverProperties()->title();
1703 if ( !layerTitle.isEmpty() )
1705 layerElement.setAttribute( u
"title"_s, layerTitle );
1709 layerElement.setAttribute( u
"title"_s, layerName );
1711 getFeatureInfoElement.appendChild( layerElement );
1714 layerElement.setAttribute( u
"id"_s, layer->id() );
1720 QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
1723 ( void ) featureInfoFromVectorLayer( vectorLayer, infoPoint.get(), featureCount, result, layerElement, mapSettings, renderContext, version, featuresRect.get(), filterGeom.get() );
1729 QgsRasterLayer *rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
1745 layerElement = result.createElement( u
"gml:featureMember"_s );
1746 getFeatureInfoElement.appendChild( layerElement );
1748 ( void ) featureInfoFromRasterLayer( rasterLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1752 QgsMeshLayer *meshLayer = qobject_cast<QgsMeshLayer *>( layer );
1760 ( void ) featureInfoFromMeshLayer( meshLayer, mapSettings, &layerInfoPoint, renderContext, result, layerElement, version );
1764 if ( !validLayer && !mContext.isValidLayer( queryLayer ) && !mContext.isValidGroup( queryLayer ) )
1767 param.mValue = queryLayer;
1770 else if ( ( validLayer && !queryableLayer ) || ( !validLayer && mContext.isValidGroup( queryLayer ) ) )
1773 param.mValue = queryLayer;
1775 bool hasGroupAndQueryable {
false };
1776 if ( !mContext.parameters().queryLayersNickname().contains( queryLayer ) )
1779 const QStringList constNicks { mContext.parameters().queryLayersNickname() };
1780 for (
const QString &ql : constNicks )
1782 if ( mContext.layerGroups().contains( ql ) )
1784 const QList<QgsMapLayer *> constLayers { mContext.layerGroups()[ql] };
1785 for (
const QgsMapLayer *ml : constLayers )
1787 if ( ( !ml->serverProperties()->shortName().isEmpty() && ml->serverProperties()->shortName() == queryLayer ) || ( ml->name() == queryLayer ) )
1793 hasGroupAndQueryable =
true;
1802 if ( !hasGroupAndQueryable )
1809 if ( featuresRect && !featuresRect->isNull() )
1813 QDomElement bBoxElem = result.createElement( u
"gml:boundedBy"_s );
1814 QDomElement boxElem;
1815 int gmlVersion = mWmsParameters.infoFormatVersion();
1816 if ( gmlVersion < 3 )
1828 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
1830 bBoxElem.appendChild( boxElem );
1831 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1835 QDomElement bBoxElem = result.createElement( u
"BoundingBox"_s );
1837 bBoxElem.setAttribute( u
"minx"_s,
qgsDoubleToString( featuresRect->xMinimum(), 8 ) );
1838 bBoxElem.setAttribute( u
"maxx"_s,
qgsDoubleToString( featuresRect->xMaximum(), 8 ) );
1839 bBoxElem.setAttribute( u
"miny"_s,
qgsDoubleToString( featuresRect->yMinimum(), 8 ) );
1840 bBoxElem.setAttribute( u
"maxy"_s,
qgsDoubleToString( featuresRect->yMaximum(), 8 ) );
1841 getFeatureInfoElement.insertBefore( bBoxElem, QDomNode() );
1847 convertFeatureInfoToSia2045( result );
1853 bool QgsRenderer::featureInfoFromVectorLayer(
1854 QgsVectorLayer *layer,
1855 const QgsPointXY *infoPoint,
1857 QDomDocument &infoDocument,
1858 QDomElement &layerElement,
1859 const QgsMapSettings &mapSettings,
1860 QgsRenderContext &renderContext,
1861 const QString &version,
1862 QgsRectangle *featureBBox,
1863 QgsGeometry *filterGeom
1871 QgsFeatureRequest fReq;
1874 std::unique_ptr<QgsGeometry> layerFilterGeom;
1877 layerFilterGeom = std::make_unique<QgsGeometry>( *filterGeom );
1882 QgsRectangle mapRect = mapSettings.
extent();
1886 QgsRectangle searchRect;
1891 searchRect = featureInfoSearchRect( layer, mapSettings, renderContext, *infoPoint );
1893 else if ( layerFilterGeom )
1895 searchRect = layerFilterGeom->boundingBox();
1897 else if ( !mWmsParameters.bbox().isEmpty() )
1899 searchRect = layerRect;
1905 QgsAttributes featureAttributes;
1906 int featureCounter = 0;
1908 const QgsFields fields = layer->
fields();
1925 if ( layerFilterGeom )
1927 fReq.
setFilterExpression( QString(
"intersects( $geometry, geom_from_wkt('%1') )" ).arg( layerFilterGeom->asWkt() ) );
1931 mFeatureFilter.filterFeatures( layer, fReq );
1934#ifdef HAVE_SERVER_PYTHON_PLUGINS
1936 mContext.accessControl()->filterFeatures( layer, fReq );
1939 QStringList attributes;
1940 for (
const QgsField &field : fields )
1942 attributes.append( field.name() );
1944 attributes = mContext.accessControl()->layerAttributes( layer, attributes );
1948 QgsFeatureIterator fit = layer->
getFeatures( fReq );
1952 r2->startRender( renderContext, layer->
fields() );
1955 bool featureBBoxInitialized =
false;
1964 if ( featureCounter > nFeatures )
1979 bool render = r2->willRenderFeature( feature, renderContext );
1992 if ( !featureBBoxInitialized && featureBBox->
isEmpty() )
1995 featureBBoxInitialized =
true;
2004 QgsCoordinateReferenceSystem outputCrs = layer->
crs();
2013 int gmlVersion = mWmsParameters.infoFormatVersion();
2014 QString typeName = mContext.layerNickname( *layer );
2015 QDomElement elem = createFeatureGML(
2024#ifdef HAVE_SERVER_PYTHON_PLUGINS
2029 QDomElement featureMemberElem = infoDocument.createElement( u
"gml:featureMember"_s );
2030 featureMemberElem.appendChild( elem );
2031 layerElement.appendChild( featureMemberElem );
2036 QDomElement featureElement = infoDocument.createElement( u
"Feature"_s );
2038 layerElement.appendChild( featureElement );
2044 writeAttributesTabLayout(
2052#ifdef HAVE_SERVER_PYTHON_PLUGINS
2060 for (
int i = 0; i < featureAttributes.count(); ++i )
2062 writeVectorLayerAttribute(
2070#ifdef HAVE_SERVER_PYTHON_PLUGINS
2082 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2083 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2087 featureElement.appendChild( maptipElem );
2091 if ( displayExpression.
isValid() && mWmsParameters.withDisplayName() )
2093 QDomElement displayElem = infoDocument.createElement( u
"Attribute"_s );
2094 displayElem.setAttribute( u
"name"_s, u
"displayName"_s );
2097 displayExpression.
prepare( &context );
2098 displayElem.setAttribute( u
"value"_s, displayExpression.
evaluate( &context ).toString() );
2099 featureElement.appendChild( displayElem );
2105 QDomElement bBoxElem = infoDocument.createElement( u
"BoundingBox"_s );
2106 bBoxElem.setAttribute( version ==
"1.1.1"_L1 ?
"SRS" :
"CRS", outputCrs.
authid() );
2111 featureElement.appendChild( bBoxElem );
2117 QgsGeometry geom = feature.
geometry();
2120 if ( layer->
crs() != outputCrs )
2122 QgsCoordinateTransform transform = mapSettings.
layerTransform( layer );
2127 if ( segmentizeWktGeometry )
2129 const QgsAbstractGeometry *abstractGeom = geom.
constGet();
2134 QgsAbstractGeometry *segmentizedGeom = abstractGeom->
segmentize();
2135 geom.
set( segmentizedGeom );
2139 QDomElement geometryElement = infoDocument.createElement( u
"Attribute"_s );
2140 geometryElement.setAttribute( u
"name"_s, u
"geometry"_s );
2141 geometryElement.setAttribute( u
"value"_s, geom.
asWkt( mContext.precision() ) );
2142 geometryElement.setAttribute( u
"type"_s, u
"derived"_s );
2143 featureElement.appendChild( geometryElement );
2150 r2->stopRender( renderContext );
2156 void QgsRenderer::writeAttributesTabGroup(
2157 const QgsAttributeEditorElement *group,
2158 QgsVectorLayer *layer,
2159 const QgsFields &fields,
2160 QgsAttributes &featureAttributes,
2162 QDomElement &parentElem,
2163 QgsRenderContext &renderContext,
2164 QStringList *attributes
2167 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
2170 QString groupName = container->
name();
2171 QDomElement nameElem;
2173 if ( !groupName.isEmpty() )
2175 nameElem = doc.createElement( groupName );
2176 parentElem.appendChild( nameElem );
2179 const QList<QgsAttributeEditorElement *> children = container->
children();
2180 for (
const QgsAttributeEditorElement *child : children )
2184 writeAttributesTabGroup( child, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext );
2188 const QgsAttributeEditorField *editorField =
dynamic_cast<const QgsAttributeEditorField *
>( child );
2194 writeVectorLayerAttribute( idx, layer, fields, featureAttributes, doc, nameElem.isNull() ? parentElem : nameElem, renderContext, attributes );
2202 void QgsRenderer::writeAttributesTabLayout(
2203 QgsEditFormConfig &config, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2207 if ( !editorContainer )
2212 writeAttributesTabGroup( editorContainer, layer, fields, featureAttributes, doc, featureElem, renderContext, attributes );
2215 void QgsRenderer::writeVectorLayerAttribute(
2216 int attributeIndex, QgsVectorLayer *layer,
const QgsFields &fields, QgsAttributes &featureAttributes, QDomDocument &doc, QDomElement &featureElem, QgsRenderContext &renderContext, QStringList *attributes
2219#ifndef HAVE_SERVER_PYTHON_PLUGINS
2220 Q_UNUSED( attributes );
2233#ifdef HAVE_SERVER_PYTHON_PLUGINS
2235 if ( attributes && !attributes->contains( fields.
at( attributeIndex ).
name() ) )
2242 QDomElement attributeElement = doc.createElement( u
"Attribute"_s );
2243 attributeElement.setAttribute( u
"name"_s, attributeName );
2246 featureElem.appendChild( attributeElement );
2249 bool QgsRenderer::featureInfoFromMeshLayer(
2250 QgsMeshLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2254 Q_UNUSED( mapSettings )
2263 const QString dateFormat = u
"yyyy-MM-ddTHH:mm:ss"_s;
2265 QList<QgsMeshDatasetIndex> datasetIndexList;
2274 layerRange =
static_cast<QgsMeshLayerTemporalProperties *
>( layer->
temporalProperties() )->timeExtent();
2276 if ( activeScalarGroup >= 0 )
2278 QgsMeshDatasetIndex indice;
2280 datasetIndexList.append( indice );
2283 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2286 for (
int groupIndex : allGroup )
2288 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2294 if ( activeScalarGroup >= 0 )
2296 if ( activeVectorGroup >= 0 && activeVectorGroup != activeScalarGroup )
2299 for (
int groupIndex : allGroup )
2301 if ( groupIndex != activeScalarGroup && groupIndex != activeVectorGroup )
2304 datasetIndexList.append( groupIndex );
2311 double scalarDoubleValue = 0.0;
2313 for (
const QgsMeshDatasetIndex &index : datasetIndexList )
2315 if ( !index.isValid() )
2319 QMap<QString, QString> derivedAttributes;
2321 QMap<QString, QString> attribute;
2325 const QgsMeshDatasetValue scalarValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2326 scalarDoubleValue = scalarValue.
scalar();
2327 attribute.insert( u
"Scalar Value"_s, std::isnan( scalarDoubleValue ) ? u
"no data"_s : QLocale().toString( scalarDoubleValue ) );
2332 const QgsMeshDatasetValue vectorValue = layer->
datasetValue( index, *infoPoint, searchRadius );
2333 const double vectorX = vectorValue.
x();
2334 const double vectorY = vectorValue.
y();
2335 if ( std::isnan( vectorX ) || std::isnan( vectorY ) )
2337 attribute.insert( u
"Vector Value"_s, u
"no data"_s );
2341 attribute.insert( u
"Vector Magnitude"_s, QLocale().toString( vectorValue.
scalar() ) );
2342 derivedAttributes.insert( u
"Vector x-component"_s, QLocale().toString( vectorY ) );
2343 derivedAttributes.insert( u
"Vector y-component"_s, QLocale().toString( vectorX ) );
2350 derivedAttributes.insert( u
"Time Step"_s, layer->
formatTime( meta.
time() ) );
2351 derivedAttributes.insert( u
"Source"_s, groupMeta.
uri() );
2353 const QString resultName = groupMeta.
name();
2355 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2356 attributeElement.setAttribute( u
"name"_s, resultName );
2361 value = QString::number( scalarDoubleValue );
2364 attributeElement.setAttribute( u
"value"_s, value );
2365 layerElement.appendChild( attributeElement );
2369 QDomElement attributeElementTime = infoDocument.createElement( u
"Attribute"_s );
2370 attributeElementTime.setAttribute( u
"name"_s, u
"Time"_s );
2373 value = range.
begin().toString( dateFormat );
2377 value = range.
begin().toString( dateFormat ) +
'/' + range.
end().toString( dateFormat );
2379 attributeElementTime.setAttribute( u
"value"_s, value );
2380 layerElement.appendChild( attributeElementTime );
2386 bool QgsRenderer::featureInfoFromRasterLayer(
2387 QgsRasterLayer *layer,
const QgsMapSettings &mapSettings,
const QgsPointXY *infoPoint,
const QgsRenderContext &renderContext, QDomDocument &infoDocument, QDomElement &layerElement,
const QString &version
2408 QgsRasterIdentifyResult identifyResult;
2411 const QgsRectangle extent { mapSettings.
extent() };
2415 throw QgsBadRequestException(
2426 if ( !identifyResult.
isValid() )
2429 QMap<int, QVariant> attributes = identifyResult.
results();
2435 QgsCoordinateReferenceSystem layerCrs = layer->
crs();
2436 int gmlVersion = mWmsParameters.infoFormatVersion();
2437 QString typeName = mContext.layerNickname( *layer );
2443 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2445 fields.
append( QgsField( layer->
bandName( it.key() ), QMetaType::Type::Double ) );
2446 feature.
setAttribute( index++, QString::number( it.value().toDouble() ) );
2449 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2450 layerElement.appendChild( elem );
2454 const auto values = identifyResult.
results();
2455 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2457 QVariant value = it.value();
2458 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2464 if ( value.userType() == QMetaType::Type::QString )
2472 for (
const QgsFeatureStore &featureStore : featureStoreList )
2475 for (
const QgsFeature &feature : storeFeatures )
2477 QDomElement elem = createFeatureGML( &feature,
nullptr, infoDocument, layerCrs, mapSettings, typeName,
false, gmlVersion,
nullptr );
2478 layerElement.appendChild( elem );
2488 for (
auto it = attributes.constBegin(); it != attributes.constEnd(); ++it )
2490 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2491 attributeElement.setAttribute( u
"name"_s, layer->
bandName( it.key() ) );
2496 value = QString::number( it.value().toDouble() );
2499 attributeElement.setAttribute( u
"value"_s, value );
2500 layerElement.appendChild( attributeElement );
2505 const auto values = identifyResult.
results();
2506 for (
auto it = values.constBegin(); it != values.constEnd(); ++it )
2508 QVariant value = it.value();
2509 if ( value.userType() == QMetaType::Type::Bool && !value.toBool() )
2515 if ( value.userType() == QMetaType::Type::QString )
2522 for (
const QgsFeatureStore &featureStore : featureStoreList )
2525 for (
const QgsFeature &feature : storeFeatures )
2527 for (
const auto &fld : feature.
fields() )
2529 const auto val { feature.
attribute( fld.name() ) };
2530 if ( val.isValid() )
2532 QDomElement attributeElement = infoDocument.createElement( u
"Attribute"_s );
2533 attributeElement.setAttribute( u
"name"_s, fld.name() );
2534 attributeElement.setAttribute( u
"value"_s, val.toString() );
2535 layerElement.appendChild( attributeElement );
2546 QDomElement maptipElem = infoDocument.createElement( u
"Attribute"_s );
2547 maptipElem.setAttribute( u
"name"_s, u
"maptip"_s );
2550 scope->
addVariable( QgsExpressionContextScope::StaticVariable( u
"layer_cursor_point"_s, QVariant::fromValue(
QgsGeometry::fromPointXY( QgsPointXY( infoPoint->
x(), infoPoint->
y() ) ) ) ) );
2553 layerElement.appendChild( maptipElem );
2559 bool QgsRenderer::testFilterStringSafety(
const QString &filter )
const
2562 if ( filter.contains(
";"_L1 ) )
2567 QStringList tokens = filter.split(
' ', Qt::SkipEmptyParts );
2568 groupStringList( tokens, u
"'"_s );
2569 groupStringList( tokens, u
"\""_s );
2571 for (
auto tokenIt = tokens.constBegin(); tokenIt != tokens.constEnd(); ++tokenIt )
2574 if ( tokenIt->compare(
','_L1 ) == 0
2575 || tokenIt->compare(
'('_L1 ) == 0
2576 || tokenIt->compare(
')'_L1 ) == 0
2577 || tokenIt->compare(
'='_L1 ) == 0
2578 || tokenIt->compare(
"!="_L1 ) == 0
2579 || tokenIt->compare(
'<'_L1 ) == 0
2580 || tokenIt->compare(
"<="_L1 ) == 0
2581 || tokenIt->compare(
'>'_L1 ) == 0
2582 || tokenIt->compare(
">="_L1 ) == 0
2583 || tokenIt->compare(
'%'_L1 ) == 0
2584 || tokenIt->compare(
"IS"_L1, Qt::CaseInsensitive ) == 0
2585 || tokenIt->compare(
"NOT"_L1, Qt::CaseInsensitive ) == 0
2586 || tokenIt->compare(
"NULL"_L1, Qt::CaseInsensitive ) == 0
2587 || tokenIt->compare(
"AND"_L1, Qt::CaseInsensitive ) == 0
2588 || tokenIt->compare(
"OR"_L1, Qt::CaseInsensitive ) == 0
2589 || tokenIt->compare(
"IN"_L1, Qt::CaseInsensitive ) == 0
2590 || tokenIt->compare(
"LIKE"_L1, Qt::CaseInsensitive ) == 0
2591 || tokenIt->compare(
"ILIKE"_L1, Qt::CaseInsensitive ) == 0
2592 || tokenIt->compare(
"DMETAPHONE"_L1, Qt::CaseInsensitive ) == 0
2593 || tokenIt->compare(
"SOUNDEX"_L1, Qt::CaseInsensitive ) == 0
2594 || mContext.settings().allowedExtraSqlTokens().contains( *tokenIt, Qt::CaseSensitivity::CaseInsensitive ) )
2601 ( void ) tokenIt->toDouble( &isNumeric );
2610 if ( *tokenIt ==
"''"_L1 )
2616 if ( tokenIt->size() > 2
2617 && ( *tokenIt )[0] == QChar(
'\'' )
2618 && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'\'' )
2619 && ( *tokenIt )[1] != QChar(
'\'' )
2620 && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'\'' ) )
2626 if ( tokenIt->size() > 2 && ( *tokenIt )[0] == QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 1] == QChar(
'"' ) && ( *tokenIt )[1] != QChar(
'"' ) && ( *tokenIt )[tokenIt->size() - 2] != QChar(
'"' ) )
2637 void QgsRenderer::groupStringList( QStringList &list,
const QString &groupString )
2640 bool groupActive =
false;
2641 int startGroup = -1;
2642 QString concatString;
2644 for (
int i = 0; i < list.size(); ++i )
2646 QString &str = list[i];
2647 if ( str.startsWith( groupString ) )
2651 concatString.clear();
2656 if ( i != startGroup )
2658 concatString.append(
" " );
2660 concatString.append( str );
2663 if ( str.endsWith( groupString ) )
2666 groupActive =
false;
2668 if ( startGroup != -1 )
2670 list[startGroup] = concatString;
2671 for (
int j = startGroup + 1; j <= endGroup; ++j )
2673 list.removeAt( startGroup + 1 );
2678 concatString.clear();
2684 void QgsRenderer::convertFeatureInfoToSia2045( QDomDocument &doc )
const
2686 QDomDocument SIAInfoDoc;
2687 QDomElement infoDocElement = doc.documentElement();
2688 QDomElement SIAInfoDocElement = SIAInfoDoc.importNode( infoDocElement,
false ).toElement();
2689 SIAInfoDoc.appendChild( SIAInfoDocElement );
2691 QString currentAttributeName;
2692 QString currentAttributeValue;
2693 QDomElement currentAttributeElem;
2694 QString currentLayerName;
2695 QDomElement currentLayerElem;
2696 QDomNodeList layerNodeList = infoDocElement.elementsByTagName( u
"Layer"_s );
2697 for (
int i = 0; i < layerNodeList.size(); ++i )
2699 currentLayerElem = layerNodeList.at( i ).toElement();
2700 currentLayerName = currentLayerElem.attribute( u
"name"_s );
2702 QDomElement currentFeatureElem;
2704 QDomNodeList featureList = currentLayerElem.elementsByTagName( u
"Feature"_s );
2705 if ( featureList.isEmpty() )
2708 QDomNodeList attributeList = currentLayerElem.elementsByTagName( u
"Attribute"_s );
2709 QDomElement rasterLayerElem;
2710 if ( !attributeList.isEmpty() )
2712 rasterLayerElem = SIAInfoDoc.createElement( currentLayerName );
2714 for (
int j = 0; j < attributeList.size(); ++j )
2716 currentAttributeElem = attributeList.at( j ).toElement();
2717 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2718 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2719 QDomElement outAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2720 QDomText outAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2721 outAttributeElem.appendChild( outAttributeText );
2722 rasterLayerElem.appendChild( outAttributeElem );
2724 if ( !attributeList.isEmpty() )
2726 SIAInfoDocElement.appendChild( rasterLayerElem );
2732 QSet<QString> layerPropertyAttributes;
2733 QString currentLayerId = currentLayerElem.attribute( u
"id"_s );
2734 if ( !currentLayerId.isEmpty() )
2736 QgsMapLayer *currentLayer = mProject->mapLayer( currentLayerId );
2739 QString WMSPropertyAttributesString = currentLayer->
customProperty( u
"WMSPropertyAttributes"_s ).toString();
2740 if ( !WMSPropertyAttributesString.isEmpty() )
2742 QStringList propertyList = WMSPropertyAttributesString.split( u
"//"_s );
2743 for (
auto propertyIt = propertyList.constBegin(); propertyIt != propertyList.constEnd(); ++propertyIt )
2745 layerPropertyAttributes.insert( *propertyIt );
2751 QDomElement propertyRefChild;
2752 for (
int j = 0; j < featureList.size(); ++j )
2754 QDomElement SIAFeatureElem = SIAInfoDoc.createElement( currentLayerName );
2755 currentFeatureElem = featureList.at( j ).toElement();
2756 QDomNodeList attributeList = currentFeatureElem.elementsByTagName( u
"Attribute"_s );
2758 for (
int k = 0; k < attributeList.size(); ++k )
2760 currentAttributeElem = attributeList.at( k ).toElement();
2761 currentAttributeName = currentAttributeElem.attribute( u
"name"_s );
2762 currentAttributeValue = currentAttributeElem.attribute( u
"value"_s );
2763 if ( layerPropertyAttributes.contains( currentAttributeName ) )
2765 QDomElement propertyElem = SIAInfoDoc.createElement( u
"property"_s );
2766 QDomElement identifierElem = SIAInfoDoc.createElement( u
"identifier"_s );
2767 QDomText identifierText = SIAInfoDoc.createTextNode( currentAttributeName );
2768 identifierElem.appendChild( identifierText );
2769 QDomElement valueElem = SIAInfoDoc.createElement( u
"value"_s );
2770 QDomText valueText = SIAInfoDoc.createTextNode( currentAttributeValue );
2771 valueElem.appendChild( valueText );
2772 propertyElem.appendChild( identifierElem );
2773 propertyElem.appendChild( valueElem );
2774 if ( propertyRefChild.isNull() )
2776 SIAFeatureElem.insertBefore( propertyElem, QDomNode() );
2777 propertyRefChild = propertyElem;
2781 SIAFeatureElem.insertAfter( propertyElem, propertyRefChild );
2786 QDomElement SIAAttributeElem = SIAInfoDoc.createElement( currentAttributeName );
2787 QDomText SIAAttributeText = SIAInfoDoc.createTextNode( currentAttributeValue );
2788 SIAAttributeElem.appendChild( SIAAttributeText );
2789 SIAFeatureElem.appendChild( SIAAttributeElem );
2792 SIAInfoDocElement.appendChild( SIAFeatureElem );
2799 QByteArray QgsRenderer::convertFeatureInfoToHtml(
const QDomDocument &doc )
const
2802 QString featureInfoString = u
" <!DOCTYPE html>"_s;
2805 featureInfoString.append( QStringLiteral( R
"HTML(
2808 <title>Information</title>
2809 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
2812 font-family: "Open Sans", "Calluna Sans", "Gill Sans MT", "Calibri", "Trebuchet MS", sans-serif;
2819 border: 1px solid black;
2820 border-collapse: collapse;
2841 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2844 for (
int i = 0; i < layerList.size(); ++i )
2846 const QDomElement layerElem = layerList.at( i ).toElement();
2849 const QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2850 const QDomElement currentFeatureElement;
2852 if ( !featureNodeList.isEmpty() )
2856 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2857 featureInfoString.append( featureInfoLayerTitleString );
2860 for (
int j = 0; j < featureNodeList.size(); ++j )
2862 const QDomElement featureElement = featureNodeList.at( j ).toElement();
2865 featureInfoString.append( QStringLiteral( R
"HTML(
2870 const QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
2871 for (
int k = 0; k < attributeNodeList.size(); ++k )
2873 const QDomElement attributeElement = attributeNodeList.at( k ).toElement();
2874 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2875 QString value = attributeElement.attribute( u
"value"_s );
2876 if ( name !=
"maptip"_L1 )
2878 value = value.toHtmlEscaped();
2883 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2888 .arg( name, value );
2890 featureInfoString.append( featureInfoAttributeString );
2892 else if ( name ==
"maptip"_L1 )
2894 featureInfoString.append( QStringLiteral( R
"HTML(
2902 featureInfoString.append( QStringLiteral( R
"HTML(
2909 const QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
2912 if ( !attributeNodeList.isEmpty() )
2916 const QString featureInfoLayerTitleString = u
" <div class='layer-title'>%1</div>"_s.arg( layerElem.attribute( u
"title"_s ).toHtmlEscaped() );
2917 featureInfoString.append( featureInfoLayerTitleString );
2919 featureInfoString.append( QStringLiteral( R
"HTML(
2923 for (
int j = 0; j < attributeNodeList.size(); ++j )
2925 const QDomElement attributeElement = attributeNodeList.at( j ).toElement();
2926 const QString name = attributeElement.attribute( u
"name"_s ).toHtmlEscaped();
2927 QString value = attributeElement.attribute( u
"value"_s );
2928 if ( value.isEmpty() )
2930 value = u
"no data"_s;
2932 if ( name !=
"maptip"_L1 )
2934 value = value.toHtmlEscaped();
2939 const QString featureInfoAttributeString = QStringLiteral( R
"HTML(
2944 .arg( name, value );
2947 featureInfoString.append( featureInfoAttributeString );
2949 else if ( name ==
"maptip"_L1 )
2951 featureInfoString.append( QStringLiteral( R
"HTML(
2959 featureInfoString.append( QStringLiteral( R
"HTML(
2969 featureInfoString.append( QStringLiteral( R
"HTML(
2973 return featureInfoString.toUtf8();
2976 QByteArray QgsRenderer::convertFeatureInfoToText(
const QDomDocument &doc )
const
2978 QString featureInfoString;
2981 featureInfoString.append(
"GetFeatureInfo results\n" );
2982 featureInfoString.append(
"\n" );
2984 QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
2987 for (
int i = 0; i < layerList.size(); ++i )
2989 QDomElement layerElem = layerList.at( i ).toElement();
2991 featureInfoString.append(
"Layer '" + layerElem.attribute( u
"name"_s ) +
"'\n" );
2994 QDomNodeList featureNodeList = layerElem.elementsByTagName( u
"Feature"_s );
2995 QDomElement currentFeatureElement;
2997 if ( !featureNodeList.isEmpty() )
2999 for (
int j = 0; j < featureNodeList.size(); ++j )
3001 QDomElement featureElement = featureNodeList.at( j ).toElement();
3002 featureInfoString.append(
"Feature " + featureElement.attribute( u
"id"_s ) +
"\n" );
3005 QDomNodeList attributeNodeList = featureElement.elementsByTagName( u
"Attribute"_s );
3006 for (
int k = 0; k < attributeNodeList.size(); ++k )
3008 QDomElement attributeElement = attributeNodeList.at( k ).toElement();
3009 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + attributeElement.attribute( u
"value"_s ) +
"'\n" );
3015 QDomNodeList attributeNodeList = layerElem.elementsByTagName( u
"Attribute"_s );
3016 for (
int j = 0; j < attributeNodeList.size(); ++j )
3018 QDomElement attributeElement = attributeNodeList.at( j ).toElement();
3019 QString value = attributeElement.attribute( u
"value"_s );
3020 if ( value.isEmpty() )
3022 value = u
"no data"_s;
3024 featureInfoString.append( attributeElement.attribute( u
"name"_s ) +
" = '" + value +
"'\n" );
3028 featureInfoString.append(
"\n" );
3031 return featureInfoString.toUtf8();
3034 QByteArray QgsRenderer::convertFeatureInfoToJson(
const QList<QgsMapLayer *> &layers,
const QDomDocument &doc,
const QgsCoordinateReferenceSystem &destCRS )
const
3036 json jsonCollection {
3037 {
"type",
"FeatureCollection" },
3038 {
"features", json::array() },
3042 const bool withDisplayName = mWmsParameters.withDisplayName();
3044 const QDomNodeList layerList = doc.elementsByTagName( u
"Layer"_s );
3045 for (
int i = 0; i < layerList.size(); ++i )
3047 const QDomElement layerElem = layerList.at( i ).toElement();
3048 const QString layerName = layerElem.attribute( u
"name"_s );
3050 QgsMapLayer *layer =
nullptr;
3051 for ( QgsMapLayer *l : layers )
3053 if ( mContext.layerNickname( *l ).compare( layerName ) == 0 )
3064 QStringList requestedWmsNames = mContext.acceptableLayersToRender().value( layer );
3065 requestedWmsNames.removeAll( layerName );
3066 QString requestedWmsName;
3067 if ( !requestedWmsNames.isEmpty() )
3069 requestedWmsName = requestedWmsNames.first();
3074 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3079 const QDomNodeList featuresNode = layerElem.elementsByTagName( u
"Feature"_s );
3080 if ( featuresNode.isEmpty() )
3083 QMap<QgsFeatureId, QString> fidMap;
3084 QMap<QgsFeatureId, QString> fidDisplayNameMap;
3086 for (
int j = 0; j < featuresNode.size(); ++j )
3088 const QDomElement featureNode = featuresNode.at( j ).toElement();
3089 const QString fid = featureNode.attribute( u
"id"_s );
3092 if ( expression.isEmpty() )
3094 feature = vl->
getFeature( fid.toLongLong() );
3098 QgsFeatureRequest request { QgsExpression( expression ) };
3103 fidMap.insert( feature.
id(), fid );
3108 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3109 for (
int k = 0; k < attrs.count(); k++ )
3111 const QDomElement elm = attrs.at( k ).toElement();
3112 if ( elm.attribute( u
"name"_s ).compare(
"geometry" ) == 0 )
3114 wkt = elm.attribute(
"value" );
3119 if ( !wkt.isEmpty() )
3127 if ( withDisplayName )
3129 QString displayName;
3130 const QDomNodeList attrs = featureNode.elementsByTagName(
"Attribute" );
3131 for (
int k = 0; k < attrs.count(); k++ )
3133 const QDomElement elm = attrs.at( k ).toElement();
3134 if ( elm.attribute( u
"name"_s ).compare(
"displayName" ) == 0 )
3136 displayName = elm.attribute(
"value" );
3140 fidDisplayNameMap.insert( feature.
id(), displayName );
3143 features << feature;
3146 if ( !attributes.isEmpty() )
3149 const QDomNodeList attributesNode = featureNode.elementsByTagName( u
"Attribute"_s );
3150 for (
int k = 0; k < attributesNode.size(); ++k )
3152 const QDomElement attributeElement = attributesNode.at( k ).toElement();
3153 const QString fieldName = attributeElement.attribute( u
"name"_s );
3154 attributes << feature.fieldNameIndex( fieldName );
3159 QgsJsonExporter exporter( vl );
3160 exporter.setAttributeDisplayName(
true );
3161 exporter.setAttributes( attributes );
3162 exporter.setIncludeGeometry( withGeometry );
3163 exporter.setTransformGeometries(
false );
3167 for (
const auto &feature : std::as_const( features ) )
3169 const QString
id = u
"%1.%2"_s.arg( layerName ).arg( fidMap.value( feature.id() ) );
3170 QVariantMap extraProperties;
3171 if ( withDisplayName )
3173 extraProperties.insert( u
"display_name"_s, fidDisplayNameMap.value( feature.id() ) );
3175 QVariantMap extraMembers;
3179 if ( !requestedWmsName.isEmpty() )
3184 jsonCollection[
"features"].push_back( exporter.exportFeatureToJsonObject( feature, extraProperties,
id, extraMembers ) );
3189 auto properties = json::object();
3190 const QDomNodeList attributesNode = layerElem.elementsByTagName( u
"Attribute"_s );
3191 for (
int j = 0; j < attributesNode.size(); ++j )
3193 const QDomElement attrElmt = attributesNode.at( j ).toElement();
3194 const QString name = attrElmt.attribute( u
"name"_s );
3196 QString value = attrElmt.attribute( u
"value"_s );
3197 if ( value.isEmpty() )
3202 properties[name.toStdString()] = value.toStdString();
3205 json jsonFeature = { {
"type",
"Feature" }, {
MEMBERNAME_FEATURETYPE, layerName.toStdString() }, {
"id", layerName.toStdString() }, {
"properties", properties } };
3207 if ( !requestedWmsName.isEmpty() )
3211 jsonCollection[
"features"].push_back( jsonFeature );
3216 return QByteArray::fromStdString( jsonCollection.dump( 2 ) );
3218 return QByteArray::fromStdString( jsonCollection.dump() );
3222 QDomElement QgsRenderer::createFeatureGML(
3223 const QgsFeature *feat, QgsVectorLayer *layer, QDomDocument &doc, QgsCoordinateReferenceSystem &crs,
const QgsMapSettings &mapSettings,
const QString &typeName,
bool withGeom,
int version, QStringList *attributes
3227 QDomElement typeNameElement = doc.createElement(
"qgs:" + typeName );
3234 typeNameElement.setAttribute( u
"fid"_s, u
"%1.%2"_s.arg( typeName, fid ) );
3236 QgsCoordinateTransform transform;
3237 if ( layer && layer->
crs() != crs )
3242 QgsGeometry geom = feat->
geometry();
3244 QgsExpressionContext expressionContext;
3250 QgsEditFormConfig editConfig { layer ? layer->
editFormConfig() : QgsEditFormConfig() };
3264 catch ( QgsCsException &e )
3270 QDomElement bbElem = doc.createElement( u
"gml:boundedBy"_s );
3271 QDomElement boxElem;
3283 boxElem.setAttribute( u
"srsName"_s, crs.
authid() );
3285 bbElem.appendChild( boxElem );
3286 typeNameElement.appendChild( bbElem );
3290 std::function<bool(
const QString &,
const QgsAttributeEditorElement * )> findAttributeInTree;
3291 findAttributeInTree = [&findAttributeInTree, &layer](
const QString &attributeName,
const QgsAttributeEditorElement *group ) ->
bool {
3292 const QgsAttributeEditorContainer *container =
dynamic_cast<const QgsAttributeEditorContainer *
>( group );
3295 const QList<QgsAttributeEditorElement *> children = container->
children();
3296 for (
const QgsAttributeEditorElement *child : children )
3298 switch ( child->type() )
3302 if ( findAttributeInTree( attributeName, child ) )
3310 if ( child->name() == attributeName )
3318 const QgsAttributeEditorRelation *relationEditor =
static_cast<const QgsAttributeEditorRelation *
>( child );
3319 if ( relationEditor )
3321 const QgsRelation &relation { relationEditor->
relation() };
3325 for (
const auto &idx : std::as_const( referencedFields ) )
3327 const QgsField f { layer->
fields().
at( idx ) };
3328 if ( f.
name() == attributeName )
3337 for (
const auto &idx : std::as_const( referencingFields ) )
3339 const QgsField f { layer->
fields().
at( idx ) };
3340 if ( f.
name() == attributeName )
3357 if ( withGeom && !geom.
isNull() )
3366 QDomElement geomElem = doc.createElement( u
"qgs:geometry"_s );
3367 QDomElement gmlElem;
3377 if ( !gmlElem.isNull() )
3381 gmlElem.setAttribute( u
"srsName"_s, crs.
authid() );
3383 geomElem.appendChild( gmlElem );
3384 typeNameElement.appendChild( geomElem );
3389 QgsAttributes featureAttributes = feat->
attributes();
3390 QgsFields fields = feat->
fields();
3391 for (
int i = 0; i < fields.
count(); ++i )
3393 QString attributeName = fields.
at( i ).
name();
3400 if ( attributes && !attributes->contains( attributeName ) )
3405 if ( honorFormConfig )
3408 if ( !editorContainer || !findAttributeInTree( attributeName, editorContainer ) )
3414 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ) );
3415 QString fieldTextString = featureAttributes.at( i ).toString();
3420 QDomText fieldText = doc.createTextNode( fieldTextString );
3421 fieldElem.appendChild( fieldText );
3422 typeNameElement.appendChild( fieldElem );
3433 QDomElement fieldElem = doc.createElement( u
"qgs:maptip"_s );
3434 QDomText maptipText = doc.createTextNode( fieldTextString );
3435 fieldElem.appendChild( maptipText );
3436 typeNameElement.appendChild( fieldElem );
3440 return typeNameElement;
3443 QString QgsRenderer::replaceValueMapAndRelation( QgsVectorLayer *vl,
int idx,
const QVariant &attributeVal )
3447 QString value( fieldFormatter->
representValue( vl, idx, setup.
config(), QVariant(), attributeVal ) );
3449 if ( setup.
config().value( u
"AllowMulti"_s ).toBool() && value.startsWith(
'{'_L1 ) && value.endsWith(
'}'_L1 ) )
3451 value = value.mid( 1, value.size() - 2 );
3456 QgsRectangle QgsRenderer::featureInfoSearchRect( QgsVectorLayer *ml,
const QgsMapSettings &mapSettings,
const QgsRenderContext &rct,
const QgsPointXY &infoPoint )
const
3460 return QgsRectangle();
3463 double mapUnitTolerance = 0.0;
3466 if ( !mWmsParameters.polygonTolerance().isEmpty() && mWmsParameters.polygonToleranceAsInt() > 0 )
3472 mapUnitTolerance = mapSettings.
extent().
width() / 400.0;
3477 if ( !mWmsParameters.lineTolerance().isEmpty() && mWmsParameters.lineToleranceAsInt() > 0 )
3483 mapUnitTolerance = mapSettings.
extent().
width() / 200.0;
3488 if ( !mWmsParameters.pointTolerance().isEmpty() && mWmsParameters.pointToleranceAsInt() > 0 )
3494 mapUnitTolerance = mapSettings.
extent().
width() / 100.0;
3501 QgsRectangle mapRectangle( infoPoint.
x() - mapUnitTolerance, infoPoint.
y() - mapUnitTolerance, infoPoint.
x() + mapUnitTolerance, infoPoint.
y() + mapUnitTolerance );
3505 QList<QgsMapLayer *> QgsRenderer::highlightLayers( QList<QgsWmsParametersHighlightLayer> params )
3507 QList<QgsMapLayer *> highlightLayers;
3510 QString crs = mWmsParameters.crs();
3511 for (
const QgsWmsParametersHighlightLayer ¶m : params )
3514 QDomDocument sldDoc;
3518 if ( !sldDoc.setContent( param.mSld,
true, &errorMsg, &errorLine, &errorColumn ) )
3525 std::unique_ptr<QgsFeatureRenderer> renderer;
3526 QDomElement el = sldDoc.documentElement();
3536 QString url = typeName +
"?crs=" + crs;
3537 if ( !param.mLabel.isEmpty() )
3539 url +=
"&field=label:string";
3544 auto layer = std::make_unique<QgsVectorLayer>( url, param.mName,
"memory"_L1, options );
3551 QgsFeature fet( layer->
fields() );
3552 if ( !param.mLabel.isEmpty() )
3554 fet.setAttribute( 0, param.mLabel );
3557 QgsPalLayerSettings palSettings;
3562 palSettings.
dist = param.mLabelDistance;
3571 switch ( param.mGeom.type() )
3582 QgsPointXY pt = param.mGeom.asPoint();
3584 QVariant x( pt.
x() );
3587 QVariant y( pt.
y() );
3599 QgsGeometry point = param.mGeom.pointOnSurface();
3600 QgsPointXY pt = point.
asPoint();
3604 QVariant x( pt.
x() );
3608 QVariant y( pt.
y() );
3612 QVariant hali(
"Center" );
3616 QVariant vali(
"Half" );
3628 QgsTextFormat textFormat;
3629 QgsTextBufferSettings bufferSettings;
3631 if ( param.mColor.isValid() )
3633 textFormat.
setColor( param.mColor );
3636 if ( param.mSize > 0 )
3638 textFormat.
setSize( param.mSize );
3646 if ( !param.mFont.isEmpty() )
3648 textFormat.
setFont( param.mFont );
3651 if ( param.mBufferColor.isValid() )
3653 bufferSettings.
setColor( param.mBufferColor );
3656 if ( param.mBufferSize > 0 )
3659 bufferSettings.
setSize(
static_cast<double>( param.mBufferSize ) );
3662 if ( param.mFrameSize > 0 )
3664 QgsTextBackgroundSettings background;
3666 background.
setSize( QSize( param.mFrameSize, param.mFrameSize ) );
3670 background.
setFillColor( param.mFrameBackgroundColor );
3677 QgsVectorLayerSimpleLabeling *simpleLabeling =
new QgsVectorLayerSimpleLabeling( palSettings );
3681 fet.setGeometry( param.mGeom );
3690 highlightLayers.append( layer.release() );
3694 mTemporaryLayers.append( highlightLayers );
3695 return highlightLayers;
3698 void QgsRenderer::removeTemporaryLayers()
3700 qDeleteAll( mTemporaryLayers );
3701 mTemporaryLayers.clear();
3704 QPainter *QgsRenderer::layersRendering(
const QgsMapSettings &mapSettings, QImage *image )
const
3706 QPainter *painter =
nullptr;
3708 QgsFeatureFilterProviderGroup filters;
3710#ifdef HAVE_SERVER_PYTHON_PLUGINS
3711 mContext.accessControl()->resolveFilterFeatures( mapSettings.
layers() );
3714 QgsMapRendererJobProxy renderJob( mContext.settings().parallelRendering(), mContext.settings().maxThreads(), &filters );
3716 renderJob.render( mapSettings, image, mContext.socketFeedback() );
3717 painter = renderJob.takePainter();
3719 logRenderingErrors( renderJob.errors() );
3721 if ( !renderJob.errors().isEmpty() && !mContext.settings().ignoreRenderingErrors() )
3723 const QgsMapRendererJob::Error e = renderJob.errors().at( 0 );
3725 QString layerWMSName;
3726 QgsMapLayer *errorLayer = mProject->mapLayer( e.
layerID );
3729 layerWMSName = mContext.layerNickname( *errorLayer );
3732 QString errorMessage = u
"Rendering error : '%1'"_s.arg( e.
message );
3733 if ( !layerWMSName.isEmpty() )
3735 errorMessage = u
"Rendering error : '%1' in layer '%2'"_s.arg( e.
message, layerWMSName );
3737 throw QgsException( errorMessage );
3743 void QgsRenderer::setLayerOpacity( QgsMapLayer *layer,
int opacity )
const
3745 if ( opacity >= 0 && opacity <= 255 )
3747 switch ( layer->
type() )
3751 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
3756 QgsAbstractVectorLayerLabeling *labeling { vl->
labeling() };
3764 QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
3765 QgsRasterRenderer *rasterRenderer = rl->
renderer();
3766 rasterRenderer->
setOpacity( opacity / 255. );
3772 QgsVectorTileLayer *vl = qobject_cast<QgsVectorTileLayer *>( layer );
3788 void QgsRenderer::setLayerFilter( QgsMapLayer *layer,
const QList<QgsWmsParametersFilter> &filters )
3792 QgsVectorLayer *filteredLayer = qobject_cast<QgsVectorLayer *>( layer );
3793 QStringList expList;
3794 for (
const QgsWmsParametersFilter &filter : filters )
3799 QDomDocument filterXml;
3801 QXmlStreamReader xmlReader( filter.mFilter );
3802 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"fes"_s, u
"http://www.opengis.net/fes/2.0"_s ) );
3803 xmlReader.addExtraNamespaceDeclaration( QXmlStreamNamespaceDeclaration( u
"ogc"_s, u
"http://www.opengis.net/ogc"_s ) );
3804 if ( QDomDocument::ParseResult result = filterXml.setContent( &xmlReader, QDomDocument::ParseOption::UseNamespaceProcessing ); !result )
3806 throw QgsBadRequestException(
3808 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 )
3812 QDomElement filterElem = filterXml.firstChildElement();
3817 expList << filterExp->dump();
3823 if ( !testFilterStringSafety( filter.mFilter ) )
3825 throw QgsSecurityException(
3827 "The filter string %1"
3828 " has been rejected because of security reasons."
3829 " Note: Text strings have to be enclosed in single or double quotes."
3830 " A space between each word / special character is mandatory."
3831 " Allowed Keywords and special characters are"
3832 " IS,NOT,NULL,AND,OR,IN,=,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX%2."
3833 " Not allowed are semicolons in the filter expression."
3835 .arg( filter.mFilter, mContext.settings().allowedExtraSqlTokens().isEmpty() ? QString() : mContext.settings().allowedExtraSqlTokens().join(
',' ).prepend(
',' ) )
3839 QString newSubsetString = filter.mFilter;
3842 newSubsetString.prepend(
") AND (" );
3843 newSubsetString.append(
")" );
3844 newSubsetString.prepend( filteredLayer->
subsetString() );
3845 newSubsetString.prepend(
"(" );
3855 expList.append( dimensionFilter( filteredLayer ) );
3859 if ( expList.size() == 1 )
3863 else if ( expList.size() > 1 )
3865 exp = u
"( %1 )"_s.arg( expList.join(
" ) AND ( "_L1 ) );
3867 if ( !exp.isEmpty() )
3869 auto expression = std::make_unique<QgsExpression>( exp );
3873 mFeatureFilter.setFilter( filteredLayer, *expression );
3880 QStringList QgsRenderer::dimensionFilter( QgsVectorLayer *layer )
const
3882 QStringList expList;
3884 QgsMapLayerServerProperties *serverProperties =
static_cast<QgsMapLayerServerProperties *
>( layer->
serverProperties() );
3885 const QList<QgsMapLayerServerProperties::WmsDimensionInfo> wmsDims = serverProperties->
wmsDimensions();
3886 if ( wmsDims.isEmpty() )
3891 QMap<QString, QString> dimParamValues = mContext.parameters().dimensionValues();
3892 for (
const QgsMapLayerServerProperties::WmsDimensionInfo &dim : wmsDims )
3901 if ( fieldIndex == -1 )
3906 int endFieldIndex = -1;
3907 if ( !dim.endFieldName.isEmpty() )
3909 endFieldIndex = layer->
fields().
indexOf( dim.endFieldName );
3910 if ( endFieldIndex == -1 )
3916 if ( !dimParamValues.contains( dim.name.toUpper() ) )
3920 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::AllValues )
3924 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::ReferenceValue )
3926 defValue = dim.referenceValue;
3931 QSet<QVariant> uniqueValues = layer->
uniqueValues( fieldIndex );
3932 if ( endFieldIndex != -1 )
3934 uniqueValues.unite( layer->
uniqueValues( endFieldIndex ) );
3937 QList<QVariant> values = qgis::setToList( uniqueValues );
3938 std::sort( values.begin(), values.end() );
3939 if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MinValue )
3941 defValue = values.first();
3943 else if ( dim.defaultDisplayType == QgsMapLayerServerProperties::WmsDimensionInfo::MaxValue )
3945 defValue = values.last();
3949 if ( endFieldIndex == -1 )
3955 QStringList expElems;
3964 expList << expElems.join(
' ' );
3970 QgsField dimField = layer->
fields().
at( fieldIndex );
3972 QString dimParamValue = dimParamValues[dim.name.toUpper()];
3974 QStringList dimExplist;
3976 QStringList dimValues = dimParamValue.split(
',' );
3977 for (
int i = 0; i < dimValues.size(); ++i )
3979 QString dimValue = dimValues[i];
3981 if ( dimValue.size() > 1 )
3983 dimValue = dimValue.trimmed();
3986 if ( dimValue.contains(
'/' ) )
3988 QStringList rangeValues = dimValue.split(
'/' );
3990 if ( rangeValues.size() != 2 )
3995 QVariant rangeMin = QVariant( rangeValues[0] );
3996 QVariant rangeMax = QVariant( rangeValues[1] );
4007 QStringList expElems;
4008 if ( endFieldIndex == -1 )
4043 dimExplist << expElems.join(
' ' );
4047 QVariant dimVariant = QVariant( dimValue );
4053 if ( endFieldIndex == -1 )
4062 QStringList expElems;
4071 dimExplist << expElems.join(
' ' );
4076 if ( dimExplist.size() == 1 )
4078 expList << dimExplist;
4080 else if ( dimExplist.size() > 1 )
4082 expList << u
"( %1 )"_s.arg( dimExplist.join(
" ) OR ( "_L1 ) );
4089 void QgsRenderer::setLayerSelection( QgsMapLayer *layer,
const QStringList &fids )
const
4093 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
4095 QgsFeatureRequest request;
4099 if ( selectedIds.empty() )
4110 void QgsRenderer::setLayerAccessControlFilter( QgsMapLayer *layer )
const
4112#ifdef HAVE_SERVER_PYTHON_PLUGINS
4119 void QgsRenderer::updateExtent(
const QgsMapLayer *layer, QgsMapSettings &mapSettings )
const
4122 QgsRectangle mapExtent = mapSettings.
extent();
4130 void QgsRenderer::annotationsRendering( QPainter *painter,
const QgsMapSettings &mapSettings )
const
4132 const QgsAnnotationManager *annotationManager = mProject->annotationManager();
4133 const QList<QgsAnnotation *> annotations = annotationManager->
annotations();
4137 renderContext.
setFeedback( mContext.socketFeedback() );
4139 for ( QgsAnnotation *annotation : annotations )
4141 if ( mContext.socketFeedback() && mContext.socketFeedback()->isCanceled() )
4143 if ( !annotation || !annotation->isVisible() )
4149 if ( annotation->hasFixedMapPosition() )
4151 QgsPointXY mapPos = annotation->mapPosition();
4152 if ( mapSettings.
destinationCrs() != annotation->mapPositionCrs() )
4157 mapPos = coordTransform.transform( mapPos );
4159 catch (
const QgsCsException &e )
4165 offsetX = devicePos.
x();
4166 offsetY = devicePos.
y();
4170 const QPointF relativePos = annotation->relativePosition();
4171 offsetX = mapSettings.
outputSize().width() * relativePos.x();
4172 offsetY = mapSettings.
outputSize().height() * relativePos.y();
4176 painter->translate( offsetX, offsetY );
4177 annotation->render( renderContext );
4182 QImage *QgsRenderer::scaleImage(
const QImage *image )
const
4187 QImage *scaledImage =
nullptr;
4188 const int width = mWmsParameters.widthAsInt();
4189 const int height = mWmsParameters.heightAsInt();
4190 if ( width != image->width() || height != image->height() )
4192 scaledImage =
new QImage( image->scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
4200 QgsMapRendererJob::Errors::const_iterator it = errors.constBegin();
4201 for ( ; it != errors.constEnd(); ++it )
4203 QString msg = QString(
"Rendering error: %1" ).arg( it->message );
4204 if ( !it->layerID.isEmpty() )
4206 msg += QString(
" in layer %1" ).arg( it->layerID );
4212 void QgsRenderer::handlePrintErrors(
const QgsLayout *layout )
const
4219 QList<QgsLayoutItemMap *> mapList;
4223 QList<QgsLayoutItemMap *>::const_iterator mapIt = mapList.constBegin();
4224 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4226 logRenderingErrors( ( *mapIt )->renderingErrors() );
4229 if ( mContext.settings().ignoreRenderingErrors() )
4234 mapIt = mapList.constBegin();
4235 for ( ; mapIt != mapList.constEnd(); ++mapIt )
4237 if ( !( *mapIt )->renderingErrors().isEmpty() )
4239 const QgsMapRendererJob::Error e = ( *mapIt )->renderingErrors().at( 0 );
4240 throw QgsException( u
"Rendering error : '%1' in layer %2"_s.arg( e.
message, e.
layerID ) );
4247 const bool useSld = !mContext.parameters().sldBody().isEmpty();
4249 for (
auto layer : layers )
4251 const QgsWmsParametersLayer param = mContext.parameters( *layer );
4253 if ( !mContext.layersToRender().contains( layer ) )
4258 if ( mContext.isExternalLayer( param.mNickname ) )
4262 setLayerOpacity( layer, param.mOpacity );
4269 setLayerSld( layer, mContext.sld( *layer ) );
4273 setLayerStyle( layer, mContext.style( *layer ) );
4278 setLayerOpacity( layer, param.mOpacity );
4283 setLayerFilter( layer, param.mFilter );
4288 setLayerAccessControlFilter( layer );
4293 setLayerSelection( layer, param.mSelection );
4296 if ( settings && mContext.updateExtent() )
4298 updateExtent( layer, *settings );
4304 layers = highlightLayers( mWmsParameters.highlightLayersParameters() ) << layers;
4308 void QgsRenderer::setLayerStyle( QgsMapLayer *layer,
const QString &style )
const
4310 if ( style.isEmpty() )
4322 void QgsRenderer::setLayerSld( QgsMapLayer *layer,
const QDomElement &sld )
const
4327 QString sldStyleName =
"__sld_style";
4328 while ( styles.contains( sldStyleName ) )
4330 sldStyleName.append(
'@' );
4338 QgsLegendSettings QgsRenderer::legendSettings()
4341 QgsLegendSettings settings = mWmsParameters.legendSettings();
4343 if ( !mWmsParameters.bbox().isEmpty() )
4345 QgsMapSettings mapSettings;
4347 std::unique_ptr<QImage> tmp( createImage( mContext.mapSize(
false ) ) );
4348 configureMapSettings( tmp.get(), mapSettings );
static QString version()
Version string.
@ MapOrientation
Signifies that the AboveLine and BelowLine flags should respect the map's orientation rather than the...
@ AboveLine
Labels can be placed above a line feature. Unless MapOrientation is also specified this mode respects...
@ Millimeters
Millimeters.
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
@ VisibleLayers
Synchronize to map layers. The legend will include layers which are included in the linked map only.
@ AllProjectLayers
Synchronize to all project layers.
@ Manual
No automatic synchronization of legend layers. The legend will be manually populated.
@ DragAndDrop
"Drag and drop" layout. Needs to be configured.
@ ExactIntersect
Use exact geometry intersection (slower) instead of bounding boxes.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ NoFlags
No flags are set.
@ Warning
Warning message.
@ Critical
Critical/error message.
@ Info
Information message.
QFlags< LabelLinePlacementFlag > LabelLinePlacementFlags
Line placement flags, which control how candidates are generated for a linear feature.
@ ShowRuleDetails
If set, the rule expression of a rule based renderer legend item will be added to the JSON.
@ IdentifyValue
Numerical values.
@ IdentifyFeature
WMS GML -> feature.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Use antialiasing while drawing.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
static const double DEFAULT_SEARCH_RADIUS_MM
Identify search radius in mm.
QFlags< LegendJsonRenderFlag > LegendJsonRenderFlags
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
RasterIdentifyFormat
Raster identify formats.
@ Feature
WMS GML/JSON -> feature.
@ Value
Numerical pixel value.
@ HideFromWms
Field is not available if layer is served as WMS from QGIS server.
@ AllowOverlapIfRequired
Avoids overlapping labels when possible, but permit overlaps if labels for features cannot otherwise ...
@ Reverse
Reverse/inverse transform (from destination to source).
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
@ RecordProfile
Enable run-time profiling while rendering.
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
@ DisableTiledRasterLayerRenders
If set, then raster layers will not be drawn as separate tiles. This may improve the appearance in ex...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ DrawSelection
Draw selection.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
QList< QgsAnnotation * > annotations() const
Returns a list of all annotations contained in the manager.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
QString name() const
Returns the name of this element.
const QgsRelation & relation() const
Gets the id of the relation which shall be embedded.
Exception thrown in case of malformed requests.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Qgis::DistanceUnit mapUnits
bool hasAxisInverted() const
Returns whether the axis order is inverted for the CRS compared to the order east/north (longitude/la...
A server filter to apply a dimension filter to a request.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
@ FlagHairlineWidthExport
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 QgsFeatureRenderer * loadSld(const QDomNode &node, Qgis::GeometryType geomType, QString &errorMessage)
Create a new renderer according to the information contained in the UserStyle element of a SLD style ...
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
Qgis::FeatureRequestFlags flags() const
Returns the flags which affect how features are fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsExpression * filterExpression() const
Returns the filter expression (if set).
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsCoordinateTransformContext transformContext() const
Returns the transform context, for use when a destinationCrs() has been set and reprojection is requi...
const QgsFeatureIds & filterFids() const
Returns the feature IDs that should be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
Qgis::FieldConfigurationFlags configurationFlags
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Q_INVOKABLE int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static Q_INVOKABLE QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
void set(QgsAbstractGeometry *geometry)
Sets the underlying geometry store.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Q_INVOKABLE QString asWkt(int precision=17) const
Exports the geometry to WKT.
static void addCrsInfo(json &value, const QgsCoordinateReferenceSystem &crs)
Add crs information entry in json object regarding old GeoJSON specification format if it differs fro...
void setPlacementFlags(Qgis::LabelLinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
void removeChildrenGroupWithoutLayers()
Remove all child group nodes without layers.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
An abstract interface for legend items returned from QgsMapLayerLegend implementation.
@ RuleKey
Rule key of the node (QString).
virtual QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const
Draws symbol on the left side of the item.
A model representing the layer tree, including layers and groups of layers.
QgsLayerTree * rootGroup() const
Returns pointer to the root node of the layer tree. Always a non nullptr value.
QgsLayerTreeModelLegendNode * findLegendNode(const QString &layerId, const QString &ruleKey) const
Searches through the layer tree to find a legend node with a matching layer ID and rule key.
QgsLayerTreeNode * parent()
Gets pointer to the parent. If parent is nullptr, the node is a root node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
Used to render QgsLayout as an atlas, by iterating over the features from an associated vector layer.
bool beginRender() override
Called when rendering begins, before iteration commences.
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
bool first()
Seeks to the first feature, returning false if no feature was found.
QgsLayout * layout() override
Returns the layout associated with the iterator.
bool enabled() const
Returns whether the atlas generation is enabled.
int count() const override
Returns the number of features to iterate over.
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
Handles rendering and exports of layouts to various formats.
ExportResult exportToSvg(const QString &filePath, const QgsLayoutExporter::SvgExportSettings &settings)
Exports the layout as an SVG to the filePath, using the specified export settings.
ExportResult exportToImage(const QString &filePath, const QgsLayoutExporter::ImageExportSettings &settings)
Exports the layout to the filePath, using the specified export settings.
ExportResult exportToPdf(const QString &filePath, const QgsLayoutExporter::PdfExportSettings &settings)
Exports the layout as a PDF to the filePath, using the specified export settings.
@ ManualHtml
HTML content is manually set for the item.
@ Url
Using this mode item fetches its content via a url.
Layout graphical items for displaying a map.
double scale() const
Returns the map scale.
QList< QgsMapLayer * > layers() const
Returns the stored layer set.
QString id() const
Returns the item's ID name.
Manages storage of a set of layouts.
QgsMasterLayoutInterface * layoutByName(const QString &name) const
Returns the layout with a matching name, or nullptr if no matching layouts were found.
Provides a method of storing measurements for use in QGIS layouts using a variety of different measur...
double length() const
Returns the length of the measurement.
int pageCount() const
Returns the number of pages in the collection.
Stores information relating to the current rendering settings for a layout.
void setFeatureFilterProvider(QgsFeatureFilterProvider *featureFilterProvider)
Sets feature filter provider to featureFilterProvider.
Provides a method of storing sizes, consisting of a width and height, for use in QGIS layouts.
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
static QVector< double > predefinedScales(const QgsLayout *layout)
Returns a list of predefined scales associated with a layout.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutPageCollection * pageCollection()
Returns a pointer to the layout's page collection, which stores and manages page items in the layout.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Handles automatic layout and rendering of legends.
QSizeF minimumSize(QgsRenderContext *renderContext=nullptr)
Runs the layout algorithm and returns the minimum size required for the legend.
QJsonObject exportLegendToJson(const QgsRenderContext &context)
Renders the legend in a json object.
Q_DECL_DEPRECATED void drawLegend(QPainter *painter)
Draws the legend with given painter.
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
Q_DECL_DEPRECATED void setMapScale(double scale)
Sets the legend map scale.
Q_DECL_DEPRECATED void setMapUnitsPerPixel(double mapUnitsPerPixel)
Sets the mmPerMapUnit calculated by mapUnitsPerPixel mostly taken from the map settings.
void setJsonRenderFlags(const Qgis::LegendJsonRenderFlags &jsonRenderFlags)
Sets the JSON export flags to jsonRenderFlags.
void setWmsLegendSize(QSizeF s)
Sets the desired size (in millimeters) of WMS legend graphics shown in the legend.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
virtual Q_INVOKABLE QgsRectangle extent() const
Returns the extent of the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QgsCoordinateReferenceSystem crs
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
virtual void setOpacity(double opacity)
Sets the opacity for the layer, where opacity is a value between 0 (totally transparent) and 1....
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
virtual bool readSld(const QDomNode &node, QString &errorMessage)
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
QList< QgsMapRendererJob::Error > Errors
Contains configuration for rendering maps.
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
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