mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-23 00:05:43 -04:00
[Geometry checker] Adapt for API changes
This commit is contained in:
parent
b52b2c51e4
commit
1642eb1601
@ -51,11 +51,13 @@ void QgsGeometryAngleCheck::collectErrors( QList<QgsGeometryCheckError *> &error
|
||||
continue;
|
||||
}
|
||||
|
||||
double angle = std::acos( v21 * v23 ) / M_PI * 180.0;
|
||||
double angle = qAcos( v21 * v23 ) / M_PI * 180.0;
|
||||
if ( angle < mMinAngle )
|
||||
{
|
||||
QgsAbstractGeometry *part = QgsGeometryCheckerUtils::getGeomPart( geom, iPart )->clone();
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), part, p2, QgsVertexId( iPart, iRing, iVert ), angle ) );
|
||||
part->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( p2, QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), part, pos, QgsVertexId( iPart, iRing, iVert ), angle ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,10 @@ void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
double value;
|
||||
if ( checkThreshold( mapToLayerUnits, geom, value ) )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), geom->centroid(), QgsVertexId( 0 ), value / ( mapToLayerUnits * mapToLayerUnits ), QgsGeometryCheckError::ValueArea ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPoint pos = g->centroid();
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, QgsVertexId( 0 ), value / ( mapToLayerUnits * mapToLayerUnits ), QgsGeometryCheckError::ValueArea ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsgeometrycollection.h"
|
||||
#include "qgscurvepolygon.h"
|
||||
#include "qgsgeometrycheck.h"
|
||||
@ -30,7 +29,7 @@ QgsGeometryCheckerContext::QgsGeometryCheckerContext( int _precision, const QStr
|
||||
|
||||
QgsGeometryCheckError::QgsGeometryCheckError( const QgsGeometryCheck *check, const QString &layerId,
|
||||
QgsFeatureId featureId, QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
QgsVertexId vidx,
|
||||
const QVariant &value, ValueType valueType )
|
||||
: mCheck( check )
|
||||
@ -47,9 +46,7 @@ QgsGeometryCheckError::QgsGeometryCheckError( const QgsGeometryCheck *check, con
|
||||
|
||||
QgsRectangle QgsGeometryCheckError::affectedAreaBBox() const
|
||||
{
|
||||
QString srcCrs = mCheck->getContext()->featurePools[ layerId() ]->getLayer()->crs().authid();
|
||||
QgsCoordinateTransform t = QgsCoordinateTransformCache::instance()->transform( srcCrs, mCheck->getContext()->mapCrs );
|
||||
return t.transformBoundingBox( mGeometry->boundingBox() );
|
||||
return mGeometry->boundingBox();
|
||||
}
|
||||
|
||||
bool QgsGeometryCheckError::handleChanges( const QgsGeometryCheck::Changes &changes )
|
||||
|
@ -99,7 +99,7 @@ class QgsGeometryCheckError
|
||||
const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
QgsVertexId vidx = QgsVertexId(),
|
||||
const QVariant &value = QVariant(),
|
||||
ValueType valueType = ValueOther );
|
||||
@ -113,11 +113,13 @@ class QgsGeometryCheckError
|
||||
const QgsGeometryCheck *check() const { return mCheck; }
|
||||
const QString &layerId() const { return mLayerId; }
|
||||
QgsFeatureId featureId() const { return mFeatureId; }
|
||||
QgsAbstractGeometry *geometry() const { return mGeometry; }
|
||||
// In map units
|
||||
const QgsAbstractGeometry *geometry() const { return mGeometry; }
|
||||
// In map units
|
||||
virtual QgsRectangle affectedAreaBBox() const;
|
||||
virtual QString description() const { return mCheck->errorDescription(); }
|
||||
const QgsPoint &location() const { return mErrorLocation; }
|
||||
// In map units
|
||||
const QgsPointXY &location() const { return mErrorLocation; }
|
||||
// Lengths, areas in map units
|
||||
QVariant value() const { return mValue; }
|
||||
ValueType valueType() const { return mValueType; }
|
||||
@ -165,7 +167,7 @@ class QgsGeometryCheckError
|
||||
QString mLayerId;
|
||||
QgsFeatureId mFeatureId;
|
||||
QgsAbstractGeometry *mGeometry;
|
||||
QgsPoint mErrorLocation;
|
||||
QgsPointXY mErrorLocation;
|
||||
QgsVertexId mVidx;
|
||||
QVariant mValue;
|
||||
ValueType mValueType;
|
||||
|
@ -13,7 +13,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsgeometryengine.h"
|
||||
#include "qgsgeometrycontainedcheck.h"
|
||||
#include "../utils/qgsfeaturepool.h"
|
||||
@ -32,7 +31,9 @@ void QgsGeometryContainedCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
QString errMsg;
|
||||
if ( geomEngineA->within( *layerFeatureB.geometry(), &errMsg ) )
|
||||
{
|
||||
errors.append( new QgsGeometryContainedCheckError( this, layerFeatureA.layer().id(), layerFeatureA.feature().id(), layerFeatureA.geometry()->clone(), layerFeatureA.geometry()->centroid(), qMakePair( layerFeatureB.layer().id(), layerFeatureB.feature().id() ) ) );
|
||||
QgsAbstractGeometry *g = layerFeatureA.geometry()->clone();
|
||||
QgsPoint pos = g->centroid();
|
||||
errors.append( new QgsGeometryContainedCheckError( this, layerFeatureA.layer().id(), layerFeatureA.feature().id(), g, pos, qMakePair( layerFeatureB.layer().id(), layerFeatureB.feature().id() ) ) );
|
||||
}
|
||||
else if ( !errMsg.isEmpty() )
|
||||
{
|
||||
@ -56,16 +57,14 @@ void QgsGeometryContainedCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
error->setObsolete();
|
||||
return;
|
||||
}
|
||||
QgsCoordinateTransform crstA = QgsCoordinateTransformCache::instance()->transform( featurePoolA->getLayer()->crs().authid(), mContext->mapCrs );
|
||||
QgsCoordinateTransform crstB = QgsCoordinateTransformCache::instance()->transform( featurePoolB->getLayer()->crs().authid(), mContext->mapCrs );
|
||||
|
||||
// Check if error still applies
|
||||
QgsAbstractGeometry *featureGeomA = featureA.geometry().geometry()->clone();
|
||||
featureGeomA->transform( crstA );
|
||||
featureGeomA->transform( featurePoolA->getMapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( featureGeomA, mContext->tolerance );
|
||||
|
||||
QgsAbstractGeometry *featureGeomB = featureB.geometry().geometry()->clone();
|
||||
featureGeomB->transform( crstB );
|
||||
featureGeomB->transform( featurePoolB->getMapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
|
||||
bool within = geomEngineA->within( *featureGeomB );
|
||||
delete featureGeomA;
|
||||
|
@ -25,7 +25,7 @@ class QgsGeometryContainedCheckError : public QgsGeometryCheckError
|
||||
const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
const QPair<QString, QgsFeatureId> &containingFeature
|
||||
)
|
||||
: QgsGeometryCheckError( check, layerId, featureId, geometry, errorLocation, QgsVertexId(), QString( "%1:%2" ).arg( containingFeature.first ).arg( containingFeature.second ), ValueOther )
|
||||
|
@ -29,7 +29,10 @@ void QgsGeometryDegeneratePolygonCheck::collectErrors( QList<QgsGeometryCheckErr
|
||||
{
|
||||
if ( QgsGeometryCheckerUtils::polyLineSize( geom, iPart, iRing ) < 3 )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), geom->vertexAt( QgsVertexId( iPart, iRing, 0 ) ), QgsVertexId( iPart, iRing ) ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( geom->vertexAt( QgsVertexId( iPart, iRing, 0 ) ), QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, QgsVertexId( iPart, iRing ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsgeometryengine.h"
|
||||
#include "qgsgeometryduplicatecheck.h"
|
||||
#include "qgsspatialindex.h"
|
||||
@ -56,7 +55,9 @@ void QgsGeometryDuplicateCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
}
|
||||
if ( !duplicates.isEmpty() )
|
||||
{
|
||||
errors.append( new QgsGeometryDuplicateCheckError( this, layerFeatureA.layer().id(), layerFeatureA.feature().id(), layerFeatureA.geometry()->clone(), layerFeatureA.geometry()->centroid(), duplicates ) );
|
||||
QgsAbstractGeometry *g = layerFeatureA.geometry()->clone();
|
||||
QgsPoint pos = g->centroid();
|
||||
errors.append( new QgsGeometryDuplicateCheckError( this, layerFeatureA.layer().id(), layerFeatureA.feature().id(), g, pos, duplicates ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,16 +78,14 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
}
|
||||
else if ( method == RemoveDuplicates )
|
||||
{
|
||||
QgsCoordinateTransform crstA = QgsCoordinateTransformCache::instance()->transform( featurePoolA->getLayer()->crs().authid(), mContext->mapCrs );
|
||||
QgsAbstractGeometry *featureGeomA = featureA.geometry().geometry()->clone();
|
||||
featureGeomA->transform( crstA );
|
||||
featureGeomA->transform( featurePoolA->getMapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QSharedPointer<QgsGeometryEngine> geomEngine = QgsGeometryCheckerUtils::createGeomEngine( featureGeomA, mContext->tolerance );
|
||||
|
||||
QgsGeometryDuplicateCheckError *duplicateError = static_cast<QgsGeometryDuplicateCheckError *>( error );
|
||||
for ( const QString &layerIdB : duplicateError->duplicates().keys() )
|
||||
{
|
||||
QgsFeaturePool *featurePoolB = mContext->featurePools[ layerIdB ];
|
||||
QgsCoordinateTransform crstB = QgsCoordinateTransformCache::instance()->transform( featurePoolB->getLayer()->crs().authid(), mContext->mapCrs );
|
||||
for ( QgsFeatureId idB : duplicateError->duplicates()[layerIdB] )
|
||||
{
|
||||
QgsFeature featureB;
|
||||
@ -95,7 +94,7 @@ void QgsGeometryDuplicateCheck::fixError( QgsGeometryCheckError *error, int meth
|
||||
continue;
|
||||
}
|
||||
QgsAbstractGeometry *featureGeomB = featureB.geometry().geometry()->clone();
|
||||
featureGeomB->transform( crstB );
|
||||
featureGeomB->transform( featurePoolB->getMapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsAbstractGeometry *diffGeom = geomEngine->symDifference( *featureGeomB );
|
||||
if ( diffGeom && diffGeom->area() < mContext->tolerance )
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ class QgsGeometryDuplicateCheckError : public QgsGeometryCheckError
|
||||
const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
const QMap<QString, QList<QgsFeatureId>> &duplicates )
|
||||
: QgsGeometryCheckError( check, layerId, featureId, geometry, errorLocation, QgsVertexId(), duplicatesString( duplicates ) )
|
||||
, mDuplicates( duplicates )
|
||||
|
@ -33,11 +33,14 @@ void QgsGeometryDuplicateNodesCheck::collectErrors( QList<QgsGeometryCheckError
|
||||
continue;
|
||||
for ( int iVert = nVerts - 1, jVert = 0; jVert < nVerts; iVert = jVert++ )
|
||||
{
|
||||
QgsPointV2 pi = geom->vertexAt( QgsVertexId( iPart, iRing, iVert ) );
|
||||
QgsPointV2 pj = geom->vertexAt( QgsVertexId( iPart, iRing, jVert ) );
|
||||
QgsPoint pi = geom->vertexAt( QgsVertexId( iPart, iRing, iVert ) );
|
||||
QgsPoint pj = geom->vertexAt( QgsVertexId( iPart, iRing, jVert ) );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( pi, pj ) < mContext->tolerance )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), pj, QgsVertexId( iPart, iRing, jVert ) ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( pj, QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, QgsVertexId( iPart, iRing, jVert ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsgeometryengine.h"
|
||||
#include "qgsgeometrygapcheck.h"
|
||||
#include "qgsgeometrycollection.h"
|
||||
@ -100,12 +99,11 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
for ( const QString &layerId : featureIds.keys() )
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
|
||||
QgsCoordinateTransform t = QgsCoordinateTransformCache::instance()->transform( mContext->mapCrs, featurePool->getLayer()->crs().authid() );
|
||||
QgsRectangle gapAreaLayerBBox = t.transform( gapGeom->boundingBox() ); // Don't use gapAreaBBox since it is updated below
|
||||
QgsRectangle gapAreaLayerBBox = featurePool->getMapToLayerTransform().transform( gapGeom->boundingBox() ); // Don't use gapAreaBBox since it is updated below
|
||||
|
||||
QgsFeatureIds intersectIds = featurePool->getIntersects( gapAreaLayerBBox );
|
||||
QgsAbstractGeometry *gapLayerGeom = gapGeom->clone();
|
||||
gapLayerGeom->transform( t );
|
||||
gapLayerGeom->transform( featurePool->getMapToLayerTransform() );
|
||||
|
||||
for ( QgsFeatureId id : intersectIds )
|
||||
{
|
||||
@ -118,9 +116,9 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
|
||||
if ( QgsGeometryCheckerUtils::sharedEdgeLength( gapLayerGeom, featureGeom, mContext->reducedTolerance ) > 0 )
|
||||
{
|
||||
neighboringIds[layerId].insert( feature.id() );
|
||||
gapAreaLayerBBox.unionRect( featureGeom->boundingBox() );
|
||||
gapAreaLayerBBox.combineExtentWith( featureGeom->boundingBox() );
|
||||
}
|
||||
gapAreaBBox.unionRect( t.transform( gapAreaLayerBBox, QgsCoordinateTransform::ReverseTransform ) );
|
||||
gapAreaBBox.combineExtentWith( featurePool->getMapToLayerTransform().transform( gapAreaLayerBBox, QgsCoordinateTransform::ReverseTransform ) );
|
||||
}
|
||||
delete gapLayerGeom;
|
||||
}
|
||||
@ -170,15 +168,14 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
|
||||
QgsFeature mergeFeature;
|
||||
int mergePartIdx = -1;
|
||||
|
||||
QgsAbstractGeometry *errGeometry = QgsGeometryCheckerUtils::getGeomPart( err->geometry(), 0 );
|
||||
const QgsAbstractGeometry *errGeometry = QgsGeometryCheckerUtils::getGeomPart( err->geometry(), 0 );
|
||||
|
||||
// Search for touching neighboring geometries
|
||||
for ( const QString &layerId : err->neighbors().keys() )
|
||||
{
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ err->layerId() ];
|
||||
QgsCoordinateTransform t = QgsCoordinateTransformCache::instance()->transform( mContext->mapCrs, featurePool->getLayer()->crs().authid() );
|
||||
QgsAbstractGeometry *errLayerGeom = errGeometry->clone();
|
||||
errLayerGeom->transform( t );
|
||||
errLayerGeom->transform( featurePool->getMapToLayerTransform() );
|
||||
|
||||
for ( QgsFeatureId testId : err->neighbors()[layerId] )
|
||||
{
|
||||
@ -211,9 +208,8 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
|
||||
|
||||
// Merge geometries
|
||||
QgsFeaturePool *featurePool = mContext->featurePools[ mergeLayerId ];
|
||||
QgsCoordinateTransform t = QgsCoordinateTransformCache::instance()->transform( mContext->mapCrs, featurePool->getLayer()->crs().authid() );
|
||||
QgsAbstractGeometry *errLayerGeom = errGeometry->clone();
|
||||
errLayerGeom->transform( t );
|
||||
errLayerGeom->transform( featurePool->getMapToLayerTransform() );
|
||||
QgsGeometry mergeFeatureGeom = mergeFeature.geometry();
|
||||
QgsAbstractGeometry *mergeGeom = mergeFeatureGeom.geometry();
|
||||
QSharedPointer<QgsGeometryEngine> geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errLayerGeom, mContext->tolerance );
|
||||
|
@ -28,7 +28,10 @@ void QgsGeometryHoleCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
// Rings after the first one are interiors
|
||||
for ( int iRing = 1, nRings = geom->ringCount( iPart ); iRing < nRings; ++iRing )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), QgsGeometryCheckerUtils::getGeomPart( geom, iPart )->centroid(), QgsVertexId( iPart, iRing ) ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( QgsGeometryCheckerUtils::getGeomPart( geom, iPart )->centroid(), QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, QgsVertexId( iPart, iRing ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,10 @@ void QgsGeometryMultipartCheck::collectErrors( QList<QgsGeometryCheckError *> &e
|
||||
QgsWkbTypes::Type type = geom->wkbType();
|
||||
if ( geom->partCount() == 1 && QgsWkbTypes::isMultiType( type ) )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), geom->centroid() ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPoint pos = g->centroid();
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsgeometryengine.h"
|
||||
#include "qgsgeometryoverlapcheck.h"
|
||||
#include "../utils/qgsfeaturepool.h"
|
||||
@ -81,16 +80,14 @@ void QgsGeometryOverlapCheck::fixError( QgsGeometryCheckError *error, int method
|
||||
error->setObsolete();
|
||||
return;
|
||||
}
|
||||
QgsCoordinateTransform crstA = QgsCoordinateTransformCache::instance()->transform( featurePoolA->getLayer()->crs().authid(), mContext->mapCrs );
|
||||
QgsCoordinateTransform crstB = QgsCoordinateTransformCache::instance()->transform( featurePoolB->getLayer()->crs().authid(), mContext->mapCrs );
|
||||
|
||||
// Check if error still applies
|
||||
QgsAbstractGeometry *featureGeomA = featureA.geometry().geometry()->clone();
|
||||
featureGeomA->transform( crstA );
|
||||
featureGeomA->transform( featurePoolA->getMapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QSharedPointer<QgsGeometryEngine> geomEngineA = QgsGeometryCheckerUtils::createGeomEngine( featureGeomA, mContext->reducedTolerance );
|
||||
|
||||
QgsAbstractGeometry *featureGeomB = featureB.geometry().geometry()->clone();
|
||||
featureGeomB->transform( crstB );
|
||||
featureGeomB->transform( featurePoolB->getMapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
|
||||
if ( !geomEngineA->overlaps( *featureGeomB ) )
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ class QgsGeometryOverlapCheckError : public QgsGeometryCheckError
|
||||
const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
const QVariant &value,
|
||||
const QPair<QString, QgsFeatureId> &overlappedFeature )
|
||||
: QgsGeometryCheckError( check, layerId, featureId, geometry, errorLocation, QgsVertexId(), value, ValueArea )
|
||||
|
@ -43,7 +43,10 @@ void QgsGeometrySegmentLengthCheck::collectErrors( QList<QgsGeometryCheckError *
|
||||
double dist = qSqrt( QgsGeometryUtils::sqrDistance2D( pi, pj ) );
|
||||
if ( dist < minLength )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), layerFeature.geometry()->clone(), QgsPoint( 0.5 * ( pi.x() + pj.x() ), 0.5 * ( pi.y() + pj.y() ) ), QgsVertexId( iPart, iRing, iVert ), dist / mapToLayerUnits, QgsGeometryCheckError::ValueLength ) );
|
||||
QgsAbstractGeometry *g = layerFeature.geometry()->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( QgsPoint( 0.5 * ( pi.x() + pj.x() ), 0.5 * ( pi.y() + pj.y() ) ), QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, QgsVertexId( iPart, iRing, iVert ), dist / mapToLayerUnits, QgsGeometryCheckError::ValueLength ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *>
|
||||
|
||||
// Geometry ring without duplicate nodes
|
||||
QVector<int> vtxMap;
|
||||
QVector<QgsPointV2> ring;
|
||||
QVector<QgsPoint> ring;
|
||||
vtxMap.append( 0 );
|
||||
ring.append( geom->vertexAt( QgsVertexId( iPart, iRing, 0 ) ) );
|
||||
for ( int i = 1; i < n; ++i )
|
||||
@ -53,7 +53,7 @@ void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *>
|
||||
// For each vertex, check whether it lies on a segment
|
||||
for ( int iVert = 0, nVerts = n - isClosed; iVert < nVerts; ++iVert )
|
||||
{
|
||||
const QgsPointV2 &p = ring[iVert];
|
||||
const QgsPoint &p = ring[iVert];
|
||||
for ( int i = 0, j = 1; j < n; i = j++ )
|
||||
{
|
||||
if ( iVert == i || iVert == j || ( isClosed && iVert == 0 && j == n - 1 ) )
|
||||
@ -65,7 +65,10 @@ void QgsGeometrySelfContactCheck::collectErrors( QList<QgsGeometryCheckError *>
|
||||
QgsPoint q = QgsGeometryUtils::projPointOnSegment( p, si, sj );
|
||||
if ( QgsGeometryUtils::sqrDistance2D( p, q ) < mContext->tolerance * mContext->tolerance )
|
||||
{
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), p, QgsVertexId( iPart, iRing, vtxMap[iVert] ) ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( p, QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometryCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, QgsVertexId( iPart, iRing, vtxMap[iVert] ) ) );
|
||||
break; // No need to report same contact on different segments multiple times
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,10 @@ void QgsGeometrySelfIntersectionCheck::collectErrors( QList<QgsGeometryCheckErro
|
||||
{
|
||||
for ( const QgsGeometryUtils::SelfIntersection &inter : QgsGeometryUtils::getSelfIntersections( geom, iPart, iRing, mContext->tolerance ) )
|
||||
{
|
||||
errors.append( new QgsGeometrySelfIntersectionCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), inter.point, QgsVertexId( iPart, iRing ), inter ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPointXY pos = layerFeature.mapToLayerTransform().transform( inter.point, QgsCoordinateTransform::ReverseTransform );
|
||||
errors.append( new QgsGeometrySelfIntersectionCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), pos, QgsVertexId( iPart, iRing ), inter ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class QgsGeometrySelfIntersectionCheckError : public QgsGeometryCheckError
|
||||
const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
QgsVertexId vidx,
|
||||
const QgsGeometryUtils::SelfIntersection &inter )
|
||||
: QgsGeometryCheckError( check, layerId, featureId, geometry, errorLocation, vidx )
|
||||
|
@ -33,7 +33,10 @@ void QgsGeometryTypeCheck::collectErrors( QList<QgsGeometryCheckError *> &errors
|
||||
QgsWkbTypes::Type type = QgsWkbTypes::flatType( geom->wkbType() );
|
||||
if ( ( mAllowedTypes & ( 1 << type ) ) == 0 )
|
||||
{
|
||||
errors.append( new QgsGeometryTypeCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), geom->clone(), geom->centroid(), type ) );
|
||||
QgsAbstractGeometry *g = geom->clone();
|
||||
g->transform( layerFeature.mapToLayerTransform(), QgsCoordinateTransform::ReverseTransform );
|
||||
QgsPoint pos = g->centroid();
|
||||
errors.append( new QgsGeometryTypeCheckError( this, layerFeature.layer().id(), layerFeature.feature().id(), g, pos, type ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class QgsGeometryTypeCheckError : public QgsGeometryCheckError
|
||||
const QString &layerId,
|
||||
QgsFeatureId featureId,
|
||||
QgsAbstractGeometry *geometry,
|
||||
const QgsPoint &errorLocation,
|
||||
const QgsPointXY &errorLocation,
|
||||
QgsWkbTypes::Type flatType )
|
||||
: QgsGeometryCheckError( check, layerId, featureId, geometry, errorLocation )
|
||||
{
|
||||
|
@ -268,8 +268,7 @@ bool QgsGeometryCheckerResultTab::exportErrorsDo( const QString &file )
|
||||
f.setAttribute( fieldLayer, srcLayer->name() );
|
||||
f.setAttribute( fieldFeatureId, error->featureId() );
|
||||
f.setAttribute( fieldErrDesc, error->description() );
|
||||
QgsGeometry geom( error->location().clone() );
|
||||
geom.transform( QgsCoordinateTransformCache::instance()->transform( srcLayer->crs().authid(), layer->crs().authid() ) );
|
||||
QgsGeometry geom( new QgsPoint( error->location() ) );
|
||||
f.setGeometry( geom );
|
||||
layer->dataProvider()->addFeatures( QgsFeatureList() << f );
|
||||
}
|
||||
@ -324,14 +323,13 @@ void QgsGeometryCheckerResultTab::highlightErrors( bool current )
|
||||
for ( QTableWidgetItem *item : items )
|
||||
{
|
||||
QgsGeometryCheckError *error = ui.tableWidgetErrors->item( item->row(), 0 )->data( Qt::UserRole ).value<QgsGeometryCheckError *>();
|
||||
QgsVectorLayer *layer = !error->layerId().isEmpty() ? mChecker->getContext()->featurePools[error->layerId()]->getLayer() : nullptr;
|
||||
|
||||
QgsAbstractGeometry *geometry = error->geometry();
|
||||
const QgsAbstractGeometry *geometry = error->geometry();
|
||||
if ( ui.checkBoxHighlight->isChecked() && geometry )
|
||||
{
|
||||
QgsRubberBand *featureRubberBand = new QgsRubberBand( mIface->mapCanvas() );
|
||||
QgsGeometry geom( geometry->clone() );
|
||||
featureRubberBand->addGeometry( geom, layer );
|
||||
featureRubberBand->addGeometry( geom, 0 );
|
||||
featureRubberBand->setWidth( 5 );
|
||||
featureRubberBand->setColor( Qt::yellow );
|
||||
mCurrentRubberBands.append( featureRubberBand );
|
||||
@ -340,12 +338,11 @@ void QgsGeometryCheckerResultTab::highlightErrors( bool current )
|
||||
if ( ui.radioButtonError->isChecked() || current || error->status() == QgsGeometryCheckError::StatusFixed )
|
||||
{
|
||||
QgsRubberBand *pointRubberBand = new QgsRubberBand( mIface->mapCanvas(), QgsWkbTypes::PointGeometry );
|
||||
QgsPoint pos = mIface->mapCanvas()->mapSettings().layerToMapCoordinates( layer, QgsPointXY( error->location().x(), error->location().y() ) );
|
||||
pointRubberBand->addPoint( pos );
|
||||
pointRubberBand->addPoint( error->location() );
|
||||
pointRubberBand->setWidth( 20 );
|
||||
pointRubberBand->setColor( Qt::red );
|
||||
mCurrentRubberBands.append( pointRubberBand );
|
||||
errorPositions.append( pos );
|
||||
errorPositions.append( error->location() );
|
||||
}
|
||||
else if ( ui.radioButtonFeature->isChecked() )
|
||||
{
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include "qgisinterface.h"
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
@ -64,7 +65,7 @@ QgsGeometryCheckerSetupTab::QgsGeometryCheckerSetupTab( QgisInterface *iface, QW
|
||||
}
|
||||
|
||||
connect( mRunButton, &QAbstractButton::clicked, this, &QgsGeometryCheckerSetupTab::runChecks );
|
||||
connect( ui.listWidgetInputLayers, &QListWidgetItem::itemChanged, this, &QgsGeometryCheckerSetupTab::validateInput() );
|
||||
connect( ui.listWidgetInputLayers, &QListWidget::itemChanged, this, &QgsGeometryCheckerSetupTab::validateInput );
|
||||
connect( QgsProject::instance(), &QgsProject::layersAdded, this, &QgsGeometryCheckerSetupTab::updateLayers );
|
||||
connect( QgsProject::instance(), static_cast<void ( QgsProject::* )( const QStringList & )>( &QgsProject::layersWillBeRemoved ), this, &QgsGeometryCheckerSetupTab::updateLayers );
|
||||
connect( ui.radioButtonOutputNew, &QAbstractButton::toggled, ui.frameOutput, &QWidget::setEnabled );
|
||||
@ -397,7 +398,8 @@ void QgsGeometryCheckerSetupTab::runChecks()
|
||||
for ( QgsVectorLayer *layer : processLayers )
|
||||
{
|
||||
double mapToLayerUnits = 1. / mIface->mapCanvas()->mapSettings().layerToMapUnits( layer );
|
||||
featurePools.insert( layer->id(), new QgsFeaturePool( layer, mapToLayerUnits, selectedOnly ) );
|
||||
QgsCoordinateTransform mapToLayerTransform = QgsCoordinateTransformCache::instance()->transform( mIface->mapCanvas()->mapSettings().destinationCrs().authid(), layer->crs().authid() );
|
||||
featurePools.insert( layer->id(), new QgsFeaturePool( layer, mapToLayerUnits, mapToLayerTransform, selectedOnly ) );
|
||||
}
|
||||
|
||||
QgsGeometryCheckerContext *context = new QgsGeometryCheckerContext( ui.spinBoxTolerance->value(), mIface->mapCanvas()->mapSettings().destinationCrs().authid(), featurePools );
|
||||
|
@ -25,10 +25,11 @@
|
||||
#include <QMutexLocker>
|
||||
#include <limits>
|
||||
|
||||
QgsFeaturePool::QgsFeaturePool( QgsVectorLayer *layer, double mapToLayerUnits, bool selectedOnly )
|
||||
QgsFeaturePool::QgsFeaturePool( QgsVectorLayer *layer, double mapToLayerUnits, const QgsCoordinateTransform &mapToLayerTransform, bool selectedOnly )
|
||||
: mFeatureCache( CACHE_SIZE )
|
||||
, mLayer( layer )
|
||||
, mMapToLayerUnits( mapToLayerUnits )
|
||||
, mMapToLayerTransform( mapToLayerTransform )
|
||||
, mSelectedOnly( selectedOnly )
|
||||
{
|
||||
if ( selectedOnly )
|
||||
|
@ -30,7 +30,7 @@ class QgsVectorLayer;
|
||||
class QgsFeaturePool
|
||||
{
|
||||
public:
|
||||
QgsFeaturePool( QgsVectorLayer *layer, double mapToLayerUnits, bool selectedOnly = false );
|
||||
QgsFeaturePool( QgsVectorLayer *layer, double mapToLayerUnits, const QgsCoordinateTransform &mapToLayerTransform, bool selectedOnly = false );
|
||||
bool get( QgsFeatureId id, QgsFeature &feature );
|
||||
void addFeature( QgsFeature &feature );
|
||||
void updateFeature( QgsFeature &feature );
|
||||
@ -38,7 +38,8 @@ class QgsFeaturePool
|
||||
QgsFeatureIds getIntersects( const QgsRectangle &rect ) const;
|
||||
QgsVectorLayer *getLayer() const { return mLayer; }
|
||||
const QgsFeatureIds &getFeatureIds() const { return mFeatureIds; }
|
||||
double getMapToLayerUnits() const { return mMapToLayerUnits;}
|
||||
double getMapToLayerUnits() const { return mMapToLayerUnits; }
|
||||
const QgsCoordinateTransform &getMapToLayerTransform() const { return mMapToLayerTransform; }
|
||||
bool getSelectedOnly() const { return mSelectedOnly; }
|
||||
void clearLayer() { mLayer = nullptr; }
|
||||
|
||||
@ -62,6 +63,7 @@ class QgsFeaturePool
|
||||
mutable QMutex mIndexMutex;
|
||||
QgsSpatialIndex mIndex;
|
||||
double mMapToLayerUnits;
|
||||
QgsCoordinateTransform mMapToLayerTransform;
|
||||
bool mSelectedOnly;
|
||||
|
||||
bool getTouchingWithSharedEdge( QgsFeature &feature, QgsFeatureId &touchingId, const double & ( *comparator )( const double &, const double & ), double init );
|
||||
|
@ -25,19 +25,19 @@
|
||||
|
||||
namespace QgsGeometryCheckerUtils
|
||||
{
|
||||
LayerFeature::LayerFeature( const QgsVectorLayer *layer, const QgsFeature &feature, double mapToLayerUnits, const QString &targetCrs )
|
||||
LayerFeature::LayerFeature( const QgsVectorLayer *layer, const QgsFeature &feature, double mapToLayerUnits, const QgsCoordinateTransform &mapToLayerTransform )
|
||||
: mLayer( layer )
|
||||
, mFeature( feature )
|
||||
, mMapToLayerUnits( mapToLayerUnits )
|
||||
, mMapToLayerTransform( mapToLayerTransform )
|
||||
, mClonedGeometry( false )
|
||||
{
|
||||
mGeometry = feature.geometry().geometry();
|
||||
if ( !targetCrs.isEmpty() && targetCrs != layer->crs().authid() )
|
||||
if ( !mapToLayerTransform.isShortCircuited() )
|
||||
{
|
||||
mClonedGeometry = true;
|
||||
mGeometry = mGeometry->clone();
|
||||
QgsCoordinateTransform crst = QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), targetCrs );
|
||||
mGeometry->transform( crst );
|
||||
mGeometry->transform( mapToLayerTransform, QgsCoordinateTransform::ReverseTransform );
|
||||
}
|
||||
}
|
||||
LayerFeature::~LayerFeature()
|
||||
@ -55,7 +55,7 @@ namespace QgsGeometryCheckerUtils
|
||||
, mFeatureIt( featureIt )
|
||||
, mFeature( feature )
|
||||
, mParent( parent )
|
||||
, mCurrentFeature( LayerFeature( parent->mFeaturePools[ * layerIt]->getLayer(), feature, parent->mFeaturePools[ * layerIt]->getMapToLayerUnits(), parent->mTargetCrs ) )
|
||||
, mCurrentFeature( LayerFeature( parent->mFeaturePools[ * layerIt]->getLayer(), feature, parent->mFeaturePools[ * layerIt]->getMapToLayerUnits(), parent->mFeaturePools[ * layerIt]->getMapToLayerTransform() ) )
|
||||
{
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ namespace QgsGeometryCheckerUtils
|
||||
mParent->mProgressCounter->fetchAndAddRelaxed( 1 );
|
||||
if ( featurePool->get( *mFeatureIt, mFeature ) )
|
||||
{
|
||||
mCurrentFeature = LayerFeature( mParent->mFeaturePools[*mLayerIt]->getLayer(), mFeature, mParent->mFeaturePools[*mLayerIt]->getMapToLayerUnits(), mParent->mTargetCrs );
|
||||
mCurrentFeature = LayerFeature( mParent->mFeaturePools[*mLayerIt]->getLayer(), mFeature, mParent->mFeaturePools[*mLayerIt]->getMapToLayerUnits(), mParent->mFeaturePools[*mLayerIt]->getMapToLayerTransform() );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -125,8 +125,7 @@ namespace QgsGeometryCheckerUtils
|
||||
const QgsFeaturePool *featurePool = featurePools[layerId];
|
||||
if ( geometryTypes.contains( featurePool->getLayer()->geometryType() ) )
|
||||
{
|
||||
QgsCoordinateTransform crst = QgsCoordinateTransformCache::instance()->transform( targetCrs, featurePool->getLayer()->crs().authid() );
|
||||
mFeatureIds.insert( layerId, featurePool->getIntersects( crst.transform( extent ) ) );
|
||||
mFeatureIds.insert( layerId, featurePool->getIntersects( featurePool->getMapToLayerTransform().transform( extent ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -17,7 +17,6 @@
|
||||
#ifndef QGS_GEOMETRYCHECKERUTILS_H
|
||||
#define QGS_GEOMETRYCHECKERUTILS_H
|
||||
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "geometry/qgsabstractgeometry.h"
|
||||
@ -31,11 +30,12 @@ namespace QgsGeometryCheckerUtils
|
||||
class LayerFeature
|
||||
{
|
||||
public:
|
||||
LayerFeature( const QgsVectorLayer *layer, const QgsFeature &feature, double mapToLayerUnits, const QString &targetCrs );
|
||||
LayerFeature( const QgsVectorLayer *layer, const QgsFeature &feature, double mapToLayerUnits, const QgsCoordinateTransform &mapToLayerTransform );
|
||||
~LayerFeature();
|
||||
const QgsVectorLayer &layer() const { return *mLayer; }
|
||||
const QgsFeature &feature() const { return mFeature; }
|
||||
double mapToLayerUnits() const { return mMapToLayerUnits; }
|
||||
const QgsCoordinateTransform &mapToLayerTransform() const { return mMapToLayerTransform; }
|
||||
const QgsAbstractGeometry *geometry() const { return mGeometry; }
|
||||
QString id() const { return QString( "%1:%2" ).arg( mLayer->id() ).arg( mFeature.id() ); }
|
||||
|
||||
@ -43,6 +43,7 @@ namespace QgsGeometryCheckerUtils
|
||||
const QgsVectorLayer *mLayer = nullptr;
|
||||
QgsFeature mFeature;
|
||||
double mMapToLayerUnits;
|
||||
QgsCoordinateTransform mMapToLayerTransform;
|
||||
QgsAbstractGeometry *mGeometry = nullptr;
|
||||
bool mClonedGeometry = false;
|
||||
};
|
||||
@ -132,7 +133,7 @@ namespace QgsGeometryCheckerUtils
|
||||
* \param tol The tolerance
|
||||
* \returns Whether the points are equal
|
||||
*/
|
||||
inline bool pointsFuzzyEqual( const QgsPoint &p1, const QgsPoint &p2, double tol )
|
||||
inline bool pointsFuzzyEqual( const QgsPointXY &p1, const QgsPointXY &p2, double tol )
|
||||
{
|
||||
double dx = p1.x() - p2.x(), dy = p1.y() - p2.y();
|
||||
return ( dx * dx + dy * dy ) < tol * tol;
|
||||
|
Loading…
x
Reference in New Issue
Block a user