QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsmapclippingutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmapclippingutils.cpp
3 --------------------------------------
4 Date : June 2020
5 Copyright : (C) 2020 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsmapclippingutils.h"
17
18#include <algorithm>
19
20#include "qgsgeometry.h"
21#include "qgslogger.h"
23#include "qgsrendercontext.h"
24
25#include <QPointer>
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
30QList<QgsMapClippingRegion> QgsMapClippingUtils::collectClippingRegionsForLayer( const QgsRenderContext &context, const QgsMapLayer *layer )
31{
32 QList< QgsMapClippingRegion > res;
33 const QList< QgsMapClippingRegion > regions = context.clippingRegions();
34 res.reserve( regions.size() );
35
36 std::copy_if( regions.begin(), regions.end(), std::back_inserter( res ), [layer]( const QgsMapClippingRegion & region )
37 {
38 return region.appliesToLayer( layer );
39 } );
40
41 return res;
42}
43
44QgsGeometry QgsMapClippingUtils::calculateFeatureRequestGeometry( const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldFilter )
45{
46 QgsGeometry result;
47 bool first = true;
48 shouldFilter = false;
49 for ( const QgsMapClippingRegion &region : regions )
50 {
51 if ( region.geometry().type() != Qgis::GeometryType::Polygon )
52 continue;
53
54 shouldFilter = true;
55 if ( first )
56 {
57 result = region.geometry();
58 first = false;
59 }
60 else
61 {
62 result = result.intersection( region.geometry() );
63 }
64 }
65
66 if ( !shouldFilter )
67 return QgsGeometry();
68
69 // filter out polygon parts from result only
71
72 // lastly transform back to layer CRS
73 try
74 {
76 }
77 catch ( QgsCsException & )
78 {
79 QgsDebugError( u"Could not transform clipping region to layer CRS"_s );
80 shouldFilter = false;
81 return QgsGeometry();
82 }
83
84 return result;
85}
86
87QgsGeometry QgsMapClippingUtils::calculateFeatureIntersectionGeometry( const QList<QgsMapClippingRegion> &regions, const QgsRenderContext &context, bool &shouldClip )
88{
89 QgsGeometry result;
90 bool first = true;
91 shouldClip = false;
92 for ( const QgsMapClippingRegion &region : regions )
93 {
94 if ( region.geometry().type() != Qgis::GeometryType::Polygon )
95 continue;
96
98 continue;
99
100 shouldClip = true;
101 if ( first )
102 {
103 result = region.geometry();
104 first = false;
105 }
106 else
107 {
108 result = result.intersection( region.geometry() );
109 }
110 }
111
112 if ( !shouldClip )
113 return QgsGeometry();
114
115 // filter out polygon parts from result only
117
118 // lastly transform back to layer CRS
119 try
120 {
122 }
123 catch ( QgsCsException & )
124 {
125 QgsDebugError( u"Could not transform clipping region to layer CRS"_s );
126 shouldClip = false;
127 return QgsGeometry();
128 }
129
130 return result;
131}
132
133QPainterPath QgsMapClippingUtils::calculatePainterClipRegion( const QList<QgsMapClippingRegion> &regions, const QgsRenderContext &context, Qgis::LayerType layerType, bool &shouldClip )
134{
135 QgsGeometry result;
136 bool first = true;
137 shouldClip = false;
138 for ( const QgsMapClippingRegion &region : regions )
139 {
140 if ( region.geometry().type() != Qgis::GeometryType::Polygon )
141 continue;
142
143 switch ( layerType )
144 {
147 continue;
148 break;
149
151 // for now, we ignore the region's featureClip behavior when rendering vector tiles
152 // TODO: ideally we should apply this during rendering, just like we do for normal
153 // vector layers
154 break;
155
163 // for these layer types, we ignore the region's featureClip behavior.
164 break;
165
166 }
167
168 shouldClip = true;
169 if ( first )
170 {
171 result = region.geometry();
172 first = false;
173 }
174 else
175 {
176 result = result.intersection( region.geometry() );
177 }
178 }
179
180 if ( !shouldClip )
181 return QPainterPath();
182
183 // transform to painter coordinates
184 result.mapToPixel( context.mapToPixel() );
185
186 return result.constGet()->asQPainterPath();
187}
188
189QgsGeometry QgsMapClippingUtils::calculateLabelIntersectionGeometry( const QList<QgsMapClippingRegion> &regions, const QgsRenderContext &context, bool &shouldClip )
190{
191 QgsGeometry result;
192 bool first = true;
193 shouldClip = false;
194 for ( const QgsMapClippingRegion &region : regions )
195 {
196 if ( region.geometry().type() != Qgis::GeometryType::Polygon )
197 continue;
198
199 // for labeling, we clip using either painter clip regions or intersects type regions.
200 // unlike feature rendering, we clip features to painter clip regions for labeling, because
201 // we want the label to sit within the clip region if possible
204 continue;
205
206 shouldClip = true;
207 if ( first )
208 {
209 result = region.geometry();
210 first = false;
211 }
212 else
213 {
214 result = result.intersection( region.geometry() );
215 }
216 }
217
218 if ( !shouldClip )
219 return QgsGeometry();
220
221 // filter out polygon parts from result only
223
224 // lastly transform back to layer CRS
225 try
226 {
228 }
229 catch ( QgsCsException & )
230 {
231 QgsDebugError( u"Could not transform clipping region to layer CRS"_s );
232 shouldClip = false;
233 return QgsGeometry();
234 }
235
236 return result;
237}
@ Polygon
Polygons.
Definition qgis.h:368
LayerType
Types of layers that can be added to a map.
Definition qgis.h:193
@ Group
Composite group layer. Added in QGIS 3.24.
Definition qgis.h:201
@ Plugin
Plugin based layer.
Definition qgis.h:196
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
Definition qgis.h:202
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
Definition qgis.h:199
@ Vector
Vector layer.
Definition qgis.h:194
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
Definition qgis.h:198
@ Mesh
Mesh layer. Added in QGIS 3.2.
Definition qgis.h:197
@ Raster
Raster layer.
Definition qgis.h:195
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
Definition qgis.h:200
@ Reverse
Reverse/inverse transform (from destination to source).
Definition qgis.h:2731
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
Custom exception class for Coordinate Reference System related exceptions.
A geometry is the spatial representation of a feature.
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.
void mapToPixel(const QgsMapToPixel &mtp)
Transforms the geometry from map units to pixels in place.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsGeometry intersection(const QgsGeometry &geometry, const QgsGeometryParameters &parameters=QgsGeometryParameters()) const
Returns a geometry representing the points shared by this geometry and other.
bool convertGeometryCollectionToSubclass(Qgis::GeometryType geomType)
Converts geometry collection to a the desired geometry type subclass (multi-point,...
A map clipping region (in map coordinates and CRS).
@ ClipPainterOnly
Applying clipping on the painter only (i.e. feature boundaries will be unchanged, but may be invisibl...
@ ClipToIntersection
Clip the geometry of these features to the region prior to rendering (i.e. feature boundaries will fo...
static QPainterPath calculatePainterClipRegion(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, Qgis::LayerType layerType, bool &shouldClip)
Returns a QPainterPath representing the intersection of clipping regions from context which should be...
static QList< QgsMapClippingRegion > collectClippingRegionsForLayer(const QgsRenderContext &context, const QgsMapLayer *layer)
Collects the list of map clipping regions from a context which apply to a map layer.
static QgsGeometry calculateLabelIntersectionGeometry(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldClip)
Returns the geometry representing the intersection of clipping regions from context which should be u...
static QgsGeometry calculateFeatureIntersectionGeometry(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldClip)
Returns the geometry representing the intersection of clipping regions from context which should be u...
static QgsGeometry calculateFeatureRequestGeometry(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldFilter)
Returns the geometry representing the intersection of clipping regions from context.
Base class for all map layer types.
Definition qgsmaplayer.h:83
Contains information about the context of a rendering operation.
QList< QgsMapClippingRegion > clippingRegions() const
Returns the list of clipping regions to apply during the render.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
#define QgsDebugError(str)
Definition qgslogger.h:59