/
qgsgeometrycontainedcheck.cpp
111 lines (100 loc) · 4.65 KB
/
qgsgeometrycontainedcheck.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/***************************************************************************
qgsgeometrycontainedcheck.cpp
---------------------
begin : September 2015
copyright : (C) 2014 by Sandro Mani / Sourcepole AG
email : smani at sourcepole dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsgeometryengine.h"
#include "qgsgeometrycontainedcheck.h"
#include "../utils/qgsfeaturepool.h"
bool QgsGeometryContainedCheckError::handleFidChanges( const QString &layerId, const QMap<QgsFeatureId, QgsFeatureId> &oldNewFidMap )
{
bool changed = QgsGeometryCheckError::handleFidChanges( layerId, oldNewFidMap );
if ( mContainingFeature.first == layerId )
{
QgsFeatureId oldId = mContainingFeature.second;
mContainingFeature.second = oldNewFidMap.value( mContainingFeature.second, mContainingFeature.second );
changed |= ( oldId != mContainingFeature.second );
}
return changed;
}
void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter, const QMap<QString, QgsFeatureIds> &ids ) const
{
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
QgsGeometryCheckerUtils::LayerFeatures layerFeaturesA( mContext->featurePools, featureIds, mCompatibleGeometryTypes, progressCounter, true );
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeatureA : layerFeaturesA )
{
QgsRectangle bboxA = layerFeatureA.geometry()->boundingBox();
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );
QgsGeometryCheckerUtils::LayerFeatures layerFeaturesB( mContext->featurePools, featureIds.keys(), bboxA, mCompatibleGeometryTypes );
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeatureB : layerFeaturesB )
{
if ( layerFeatureA == layerFeatureB )
{
continue;
}
QString errMsg;
if ( geomEngineA->within( *layerFeatureB.geometry(), &errMsg ) )
{
errors.append( new QgsGeometryContainedCheckError( this, layerFeatureA, layerFeatureA.geometry()->centroid(), layerFeatureB ) );
}
else if ( !errMsg.isEmpty() )
{
messages.append( tr( "Feature %1 within feature %2: %3" ).arg( layerFeatureA.id() ).arg( layerFeatureB.id() ).arg( errMsg ) );
}
}
}
}
void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
{
QgsGeometryContainedCheckError *containerError = static_cast<QgsGeometryContainedCheckError *>( error );
QgsFeaturePool *featurePoolA = mContext->featurePools[ error->layerId() ];
QgsFeaturePool *featurePoolB = mContext->featurePools[ containerError->containingFeature().first ];
QgsFeature featureA;
QgsFeature featureB;
if ( !featurePoolA->get( error->featureId(), featureA ) ||
!featurePoolB->get( containerError->containingFeature().second, featureB ) )
{
error->setObsolete();
return;
}
// Check if error still applies
QgsGeometryCheckerUtils::LayerFeature layerFeatureA( featurePoolA, featureA, true );
QgsGeometryCheckerUtils::LayerFeature layerFeatureB( featurePoolB, featureB, true );
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( layerFeatureA.geometry(), mContext->tolerance );
if ( !geomEngineA->within( *layerFeatureB.geometry() ) )
{
error->setObsolete();
return;
}
// Fix error
if ( method == NoChange )
{
error->setFixed( method );
}
else if ( method == Delete )
{
changes[error->layerId()][featureA.id()].append( Change( ChangeFeature, ChangeRemoved ) );
featurePoolA->deleteFeature( featureA );
error->setFixed( method );
}
else
{
error->setFixFailed( tr( "Unknown method" ) );
}
}
QStringList QgsGeometryContainedCheck::getResolutionMethods() const
{
static QStringList methods = QStringList()
<< tr( "Delete feature" )
<< tr( "No action" );
return methods;
}