Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsgeometrycheckerror.cpp 3 : : -------- 4 : : begin : September 2018 5 : : copyright : (C) 2018 by Denis Rouzaud 6 : : email : denis@opengis.ch 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #include "qgsgeometrycheckerror.h" 19 : : #include "qgsapplication.h" 20 : : 21 : 52 : QgsGeometryCheckError::QgsGeometryCheckError( const QgsGeometryCheck *check, 22 : : const QString &layerId, 23 : : QgsFeatureId featureId, 24 : : const QgsGeometry &geometry, 25 : : const QgsPointXY &errorLocation, 26 : : QgsVertexId vidx, 27 : : const QVariant &value, ValueType valueType ) 28 : 26 : : mCheck( check ) 29 : 26 : , mLayerId( layerId ) 30 : 26 : , mFeatureId( featureId ) 31 : 26 : , mGeometry( geometry ) 32 : 26 : , mErrorLocation( errorLocation ) 33 : 26 : , mVidx( vidx ) 34 : 26 : , mValue( value ) 35 : 26 : , mValueType( valueType ) 36 : 26 : , mStatus( StatusPending ) 37 : 26 : { 38 : 26 : } 39 : : 40 : 315 : QgsGeometryCheckError::QgsGeometryCheckError( const QgsGeometryCheck *check, 41 : : const QgsGeometryCheckerUtils::LayerFeature &layerFeature, 42 : : const QgsPointXY &errorLocation, 43 : : QgsVertexId vidx, 44 : : const QVariant &value, 45 : : ValueType valueType ) 46 : 105 : : mCheck( check ) 47 : 105 : , mLayerId( layerFeature.layerId() ) 48 : 105 : , mFeatureId( layerFeature.feature().id() ) 49 : 105 : , mErrorLocation( errorLocation ) 50 : 105 : , mVidx( vidx ) 51 : 105 : , mValue( value ) 52 : 105 : , mValueType( valueType ) 53 : 105 : , mStatus( StatusPending ) 54 : 105 : { 55 : 105 : if ( vidx.part != -1 ) 56 : : { 57 : 59 : const QgsGeometry geom = layerFeature.geometry(); 58 : 59 : mGeometry = QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom.constGet(), vidx.part )->clone() ); 59 : 59 : } 60 : : else 61 : : { 62 : 46 : mGeometry = layerFeature.geometry(); 63 : : } 64 : 105 : if ( !layerFeature.useMapCrs() ) 65 : : { 66 : 76 : QgsVectorLayer *vl = layerFeature.layer().data(); 67 : 76 : if ( vl ) 68 : : { 69 : 76 : QgsCoordinateTransform ct( vl->crs(), check->context()->mapCrs, check->context()->transformContext ); 70 : : try 71 : : { 72 : 76 : mGeometry.transform( ct ); 73 : 76 : mErrorLocation = ct.transform( mErrorLocation ); 74 : 76 : } 75 : : catch ( const QgsCsException & ) 76 : : { 77 : 0 : QgsDebugMsg( QStringLiteral( "Can not show error in current map coordinate reference system" ) ); 78 : 0 : } 79 : 76 : } 80 : 76 : } 81 : 105 : } 82 : : 83 : 3 : QgsGeometry QgsGeometryCheckError::geometry() const 84 : : { 85 : 3 : return mGeometry; 86 : : } 87 : : 88 : 0 : QgsRectangle QgsGeometryCheckError::contextBoundingBox() const 89 : : { 90 : 0 : return QgsRectangle(); 91 : : } 92 : : 93 : 0 : QgsRectangle QgsGeometryCheckError::affectedAreaBBox() const 94 : : { 95 : 0 : return mGeometry.boundingBox(); 96 : : } 97 : : 98 : 21 : void QgsGeometryCheckError::setFixed( int method ) 99 : : { 100 : 21 : mStatus = StatusFixed; 101 : 21 : const QList<QgsGeometryCheckResolutionMethod> methods = mCheck->availableResolutionMethods(); 102 : 87 : for ( const QgsGeometryCheckResolutionMethod &fix : methods ) 103 : : { 104 : 66 : if ( fix.id() == method ) 105 : 30 : mResolutionMessage = fix.name(); 106 : : } 107 : 21 : } 108 : : 109 : 0 : void QgsGeometryCheckError::setFixFailed( const QString &reason ) 110 : : { 111 : 0 : mStatus = StatusFixFailed; 112 : 0 : mResolutionMessage = reason; 113 : 0 : } 114 : : 115 : 0 : bool QgsGeometryCheckError::isEqual( QgsGeometryCheckError *other ) const 116 : : { 117 : 0 : return other->check() == check() && 118 : 0 : other->layerId() == layerId() && 119 : 0 : other->featureId() == featureId() && 120 : 0 : other->vidx() == vidx(); 121 : : } 122 : : 123 : 0 : bool QgsGeometryCheckError::closeMatch( QgsGeometryCheckError * ) const 124 : : { 125 : 0 : return false; 126 : : } 127 : : 128 : 18 : bool QgsGeometryCheckError::handleChanges( const QgsGeometryCheck::Changes &changes ) 129 : : { 130 : 18 : if ( status() == StatusObsolete ) 131 : : { 132 : 0 : return false; 133 : : } 134 : : 135 : 36 : for ( const QgsGeometryCheck::Change &change : changes.value( layerId() ).value( featureId() ) ) 136 : : { 137 : 18 : if ( change.what == QgsGeometryCheck::ChangeFeature ) 138 : : { 139 : 2 : if ( change.type == QgsGeometryCheck::ChangeRemoved ) 140 : : { 141 : 1 : return false; 142 : : } 143 : 1 : else if ( change.type == QgsGeometryCheck::ChangeChanged ) 144 : : { 145 : : // If the check is checking the feature at geometry nodes level, the 146 : : // error almost certainly invalid after a geometry change. In the other 147 : : // cases, it might likely still be valid. 148 : 1 : return mCheck->checkType() != QgsGeometryCheck::FeatureNodeCheck; 149 : : } 150 : 0 : } 151 : 16 : else if ( change.what == QgsGeometryCheck::ChangePart ) 152 : : { 153 : 5 : if ( mVidx.part == change.vidx.part ) 154 : : { 155 : 2 : return false; 156 : : } 157 : 3 : else if ( mVidx.part > change.vidx.part ) 158 : : { 159 : 1 : mVidx.part += change.type == QgsGeometryCheck::ChangeAdded ? 1 : -1; 160 : 1 : } 161 : 3 : } 162 : 11 : else if ( change.what == QgsGeometryCheck::ChangeRing ) 163 : : { 164 : 4 : if ( mVidx.partEqual( change.vidx ) ) 165 : : { 166 : 4 : if ( mVidx.ring == change.vidx.ring ) 167 : : { 168 : 2 : return false; 169 : : } 170 : 2 : else if ( mVidx.ring > change.vidx.ring ) 171 : : { 172 : 0 : mVidx.ring += change.type == QgsGeometryCheck::ChangeAdded ? 1 : -1; 173 : 0 : } 174 : 2 : } 175 : 2 : } 176 : 7 : else if ( change.what == QgsGeometryCheck::ChangeNode ) 177 : : { 178 : 7 : if ( mVidx.ringEqual( change.vidx ) ) 179 : : { 180 : 7 : if ( mVidx.vertex == change.vidx.vertex ) 181 : : { 182 : 2 : return false; 183 : : } 184 : 5 : else if ( mVidx.vertex > change.vidx.vertex ) 185 : : { 186 : 1 : mVidx.vertex += change.type == QgsGeometryCheck::ChangeAdded ? 1 : -1; 187 : 1 : } 188 : 5 : } 189 : 5 : } 190 : : } 191 : 10 : return true; 192 : 18 : } 193 : : 194 : 0 : QMap<QString, QgsFeatureIds> QgsGeometryCheckError::involvedFeatures() const 195 : : { 196 : 0 : return QMap<QString, QSet<QgsFeatureId> >(); 197 : : } 198 : : 199 : 0 : QIcon QgsGeometryCheckError::icon() const 200 : : { 201 : 0 : if ( status() == QgsGeometryCheckError::StatusFixed ) 202 : 0 : return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmCheckGeometry.svg" ) ); 203 : : else 204 : 0 : return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmLineIntersections.svg" ) ); 205 : 0 : } 206 : : 207 : 0 : void QgsGeometryCheckError::update( const QgsGeometryCheckError *other ) 208 : : { 209 : : Q_ASSERT( mCheck == other->mCheck ); 210 : : Q_ASSERT( mLayerId == other->mLayerId ); 211 : : Q_ASSERT( mFeatureId == other->mFeatureId ); 212 : 0 : mErrorLocation = other->mErrorLocation; 213 : 0 : mVidx = other->mVidx; 214 : 0 : mValue = other->mValue; 215 : 0 : mGeometry = other->mGeometry; 216 : 0 : } 217 : : 218 : 0 : QgsGeometryCheck::LayerFeatureIds::LayerFeatureIds( const QMap<QString, QgsFeatureIds> &idsIn ) 219 : 0 : : ids( idsIn ) 220 : : { 221 : 0 : }