13
13
* *
14
14
***************************************************************************/
15
15
16
+ #include " qgscrscache.h"
16
17
#include " qgsgeometryengine.h"
17
18
#include " qgsgeometrycontainedcheck.h"
18
19
#include " ../utils/qgsfeaturepool.h"
19
20
20
21
void QgsGeometryContainedCheck::collectErrors ( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter, const QMap<QString, QgsFeatureIds> &ids ) const
21
22
{
22
23
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty () ? allLayerFeatureIds () : ids;
23
- for ( const QString &layerId : featureIds.keys () )
24
+ for ( const QString &layerIdA : featureIds.keys () )
24
25
{
25
- QgsFeaturePool *featurePool = mContext ->featurePools [ layerId ];
26
- if ( !getCompatibility ( featurePool ->getLayer ()->geometryType () ) )
26
+ QgsFeaturePool *featurePoolA = mContext ->featurePools [ layerIdA ];
27
+ if ( !getCompatibility ( featurePoolA ->getLayer ()->geometryType () ) )
27
28
{
28
29
continue ;
29
30
}
30
- for ( QgsFeatureId featureid : featureIds[layerId] )
31
+ QgsCoordinateTransform crstA = QgsCoordinateTransformCache::instance ()->transform ( featurePoolA->getLayer ()->crs ().authid (), mContext ->mapCrs );
32
+
33
+ for ( QgsFeatureId featureIdA : featureIds[layerIdA] )
31
34
{
32
35
if ( progressCounter ) progressCounter->fetchAndAddRelaxed ( 1 );
33
- QgsFeature feature ;
34
- if ( !featurePool ->get ( featureid, feature ) )
36
+ QgsFeature featureA ;
37
+ if ( !featurePoolA ->get ( featureIdA, featureA ) )
35
38
{
36
39
continue ;
37
40
}
38
41
39
- QgsGeometry featureGeom = feature.geometry ();
40
- QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine ( featureGeom.geometry (), mContext ->tolerance );
42
+ QgsAbstractGeometry *featureGeomA = featureA.geometry ().geometry ()->clone ();
43
+ featureGeomA->transform ( crstA );
44
+ QgsGeometryEngine *geomEngineA = QgsGeometryCheckerUtils::createGeomEngine ( featureGeomA, mContext ->tolerance );
45
+ QgsRectangle bboxA = crstA.transform ( featureGeomA->boundingBox () );
41
46
42
- QgsFeatureIds ids = featurePool->getIntersects ( featureGeom.geometry ()->boundingBox () );
43
- for ( QgsFeatureId otherid : ids )
47
+ for ( const QString &layerIdB : featureIds.keys () )
44
48
{
45
- if ( otherid == featureid )
46
- {
47
- continue ;
48
- }
49
- QgsFeature otherFeature;
50
- if ( !featurePool->get ( otherid, otherFeature ) )
49
+ QgsFeaturePool *featurePoolB = mContext ->featurePools [ layerIdB ];
50
+ if ( !getCompatibility ( featurePoolB->getLayer ()->geometryType () ) )
51
51
{
52
52
continue ;
53
53
}
54
+ QgsCoordinateTransform crstB = QgsCoordinateTransformCache::instance ()->transform ( featurePoolB->getLayer ()->crs ().authid (), mContext ->mapCrs );
54
55
55
- QString errMsg ;
56
- if ( geomEngine-> within ( *otherFeature. geometry (). geometry (), &errMsg ) )
56
+ QgsFeatureIds idsB = featurePoolB-> getIntersects ( crstB. transform ( bboxA, QgsCoordinateTransform::ReverseTransform ) ) ;
57
+ for ( QgsFeatureId featureIdB : idsB )
57
58
{
58
- errors.append ( new QgsGeometryContainedCheckError ( this , layerId, featureid, feature.geometry ().geometry ()->centroid (), otherid ) );
59
- }
60
- else if ( !errMsg.isEmpty () )
61
- {
62
- messages.append ( tr ( " Feature %1 within feature %2: %3" ).arg ( feature.id () ).arg ( otherFeature.id () ).arg ( errMsg ) );
59
+ QgsFeature featureB;
60
+ if ( !featurePoolB->get ( featureIdB, featureB ) )
61
+ {
62
+ continue ;
63
+ }
64
+ QgsAbstractGeometry *featureGeomB = featureB.geometry ().geometry ()->clone ();
65
+ featureGeomB->transform ( crstB );
66
+
67
+ QString errMsg;
68
+ if ( geomEngineA->within ( *featureGeomB, &errMsg ) )
69
+ {
70
+ errors.append ( new QgsGeometryContainedCheckError ( this , layerIdA, featureIdA, featureGeomA->centroid (), qMakePair ( layerIdB, featureIdB ) ) );
71
+ }
72
+ else if ( !errMsg.isEmpty () )
73
+ {
74
+ messages.append ( tr ( " Feature %1:%2 within feature %3:%4: %5" ).arg ( layerIdA ).arg ( featureIdA ).arg ( layerIdB ).arg ( featureIdB ).arg ( errMsg ) );
75
+ }
76
+ delete featureGeomB;
63
77
}
64
78
}
65
- delete geomEngine;
79
+ delete geomEngineA;
80
+ delete featureGeomA;
66
81
}
67
82
}
68
83
}
69
84
70
85
void QgsGeometryContainedCheck::fixError ( QgsGeometryCheckError *error, int method, const QMap<QString, int > & /* mergeAttributeIndices*/ , Changes &changes ) const
71
86
{
72
- QgsFeaturePool *featurePool = mContext ->featurePools [ error->layerId () ];
73
87
QgsGeometryContainedCheckError *containerError = static_cast <QgsGeometryContainedCheckError *>( error );
88
+ QgsFeaturePool *featurePoolA = mContext ->featurePools [ error->layerId () ];
89
+ QgsFeaturePool *featurePoolB = mContext ->featurePools [ containerError->containingFeature ().first ];
74
90
75
- QgsFeature feature ;
76
- QgsFeature otherFeature ;
77
- if ( !featurePool ->get ( error->featureId (), feature ) ||
78
- !featurePool ->get ( containerError->otherId (), otherFeature ) )
91
+ QgsFeature featureA ;
92
+ QgsFeature featureB ;
93
+ if ( !featurePoolA ->get ( error->featureId (), featureA ) ||
94
+ !featurePoolB ->get ( containerError->containingFeature (). second , featureB ) )
79
95
{
80
96
error->setObsolete ();
81
97
return ;
82
98
}
99
+ QgsCoordinateTransform crstA = QgsCoordinateTransformCache::instance ()->transform ( featurePoolA->getLayer ()->crs ().authid (), mContext ->mapCrs );
100
+ QgsCoordinateTransform crstB = QgsCoordinateTransformCache::instance ()->transform ( featurePoolB->getLayer ()->crs ().authid (), mContext ->mapCrs );
83
101
84
102
// Check if error still applies
85
- QgsGeometry featureGeom = feature.geometry ();
86
- QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine ( featureGeom.geometry (), mContext ->tolerance );
103
+ QgsAbstractGeometry *featureGeomA = featureA.geometry ().geometry ()->clone ();
104
+ featureGeomA->transform ( crstA );
105
+ QgsGeometryEngine *geomEngineA = QgsGeometryCheckerUtils::createGeomEngine ( featureGeomA, mContext ->tolerance );
106
+
107
+ QgsAbstractGeometry *featureGeomB = featureB.geometry ().geometry ()->clone ();
108
+ featureGeomB->transform ( crstB );
109
+
110
+ bool within = geomEngineA->within ( *featureGeomB );
111
+ delete geomEngineA;
112
+ delete featureGeomA;
113
+ delete featureGeomB;
87
114
88
- if ( !geomEngine-> within ( otherFeature. geometry (). geometry () ) )
115
+ if ( !within )
89
116
{
90
- delete geomEngine;
91
117
error->setObsolete ();
92
118
return ;
93
119
}
94
- delete geomEngine;
95
120
96
121
// Fix error
97
122
if ( method == NoChange )
@@ -100,8 +125,8 @@ void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int meth
100
125
}
101
126
else if ( method == Delete )
102
127
{
103
- changes[error->layerId ()][feature .id ()].append ( Change ( ChangeFeature, ChangeRemoved ) );
104
- featurePool ->deleteFeature ( feature );
128
+ changes[error->layerId ()][featureA .id ()].append ( Change ( ChangeFeature, ChangeRemoved ) );
129
+ featurePoolA ->deleteFeature ( featureA );
105
130
error->setFixed ( method );
106
131
}
107
132
else
0 commit comments