Skip to content

Commit

Permalink
Use std::unique_ptr in QgsGeometryGapCheck
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Aug 19, 2018
1 parent 1192f94 commit 448e769
Showing 1 changed file with 19 additions and 28 deletions.
47 changes: 19 additions & 28 deletions src/analysis/vector/geometry_checker/qgsgeometrygapcheck.cpp
Expand Up @@ -21,7 +21,8 @@

void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter, const QMap<QString, QgsFeatureIds> &ids ) const
{
if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
if ( progressCounter )
progressCounter->fetchAndAddRelaxed( 1 );

QVector<QgsAbstractGeometry *> geomList;

Expand All @@ -41,7 +42,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,

// Create union of geometry
QString errMsg;
QgsAbstractGeometry *unionGeom = geomEngine->combine( geomList, &errMsg );
std::unique_ptr<QgsAbstractGeometry> unionGeom( geomEngine->combine( geomList, &errMsg ) );
qDeleteAll( geomList );
if ( !unionGeom )
{
Expand All @@ -50,36 +51,32 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
}

// Get envelope of union
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( unionGeom, mContext->tolerance );
QgsAbstractGeometry *envelope = geomEngine->envelope( &errMsg );
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( unionGeom.get(), mContext->tolerance );
std::unique_ptr<QgsAbstractGeometry> envelope( geomEngine->envelope( &errMsg ) );
if ( !envelope )
{
messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
delete unionGeom;
return;
}

// Buffer envelope
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope, mContext->tolerance );
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope.get(), mContext->tolerance );
QgsAbstractGeometry *bufEnvelope = geomEngine->buffer( 2, 0, GEOSBUF_CAP_SQUARE, GEOSBUF_JOIN_MITRE, 4. ); //#spellok //#spellok
delete envelope;
envelope = bufEnvelope;
envelope.reset( bufEnvelope );

// Compute difference between envelope and union to obtain gap polygons
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope, mContext->tolerance );
QgsAbstractGeometry *diffGeom = geomEngine->difference( unionGeom, &errMsg );
geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope.get(), mContext->tolerance );
std::unique_ptr<QgsAbstractGeometry> diffGeom( geomEngine->difference( unionGeom.get(), &errMsg ) );
if ( !diffGeom )
{
messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
delete unionGeom;
delete diffGeom;
return;
}

// For each gap polygon which does not lie on the boundary, get neighboring polygons and add error
for ( int iPart = 0, nParts = diffGeom->partCount(); iPart < nParts; ++iPart )
{
QgsAbstractGeometry *gapGeom = QgsGeometryCheckerUtils::getGeomPart( diffGeom, iPart )->clone();
std::unique_ptr<QgsAbstractGeometry> gapGeom( QgsGeometryCheckerUtils::getGeomPart( diffGeom.get(), iPart )->clone() );
// Skip the gap between features and boundingbox
if ( gapGeom->boundingBox() == envelope->boundingBox() )
{
Expand All @@ -99,7 +96,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,
QgsGeometryCheckerUtils::LayerFeatures layerFeatures( mContext->featurePools, featureIds.keys(), gapAreaBBox, mCompatibleGeometryTypes );
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
{
if ( QgsGeometryCheckerUtils::sharedEdgeLength( gapGeom, layerFeature.geometry(), mContext->reducedTolerance ) > 0 )
if ( QgsGeometryCheckerUtils::sharedEdgeLength( gapGeom.get(), layerFeature.geometry(), mContext->reducedTolerance ) > 0 )
{
neighboringIds[layerFeature.layer().id()].insert( layerFeature.feature().id() );
gapAreaBBox.combineExtentWith( layerFeature.geometry()->boundingBox() );
Expand All @@ -108,17 +105,14 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors,

if ( neighboringIds.isEmpty() )
{
delete gapGeom;
continue;
}

// Add error
errors.append( new QgsGeometryGapCheckError( this, "", gapGeom, neighboringIds, gapGeom->area(), gapAreaBBox ) );
double area = gapGeom->area();
errors.append( new QgsGeometryGapCheckError( this, QString(), gapGeom.release(), neighboringIds, area, gapAreaBBox ) );

}
delete unionGeom;
delete envelope;
delete diffGeom;
}

void QgsGeometryGapCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
Expand Down Expand Up @@ -158,7 +152,7 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
for ( const QString &layerId : err->neighbors().keys() )
{
QgsFeaturePool *featurePool = mContext->featurePools[ layerId ];
QgsAbstractGeometry *errLayerGeom = errGeometry->clone();
std::unique_ptr<QgsAbstractGeometry> errLayerGeom( errGeometry->clone() );
errLayerGeom->transform( featurePool->getLayerToMapTransform(), QgsCoordinateTransform::ReverseTransform );

for ( QgsFeatureId testId : err->neighbors()[layerId] )
Expand All @@ -172,7 +166,7 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
const QgsAbstractGeometry *testGeom = featureGeom.constGet();
for ( int iPart = 0, nParts = testGeom->partCount(); iPart < nParts; ++iPart )
{
double len = QgsGeometryCheckerUtils::sharedEdgeLength( errLayerGeom, QgsGeometryCheckerUtils::getGeomPart( testGeom, iPart ), mContext->reducedTolerance );
double len = QgsGeometryCheckerUtils::sharedEdgeLength( errLayerGeom.get(), QgsGeometryCheckerUtils::getGeomPart( testGeom, iPart ), mContext->reducedTolerance );
if ( len > maxVal )
{
maxVal = len;
Expand All @@ -182,7 +176,6 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan
}
}
}
delete errLayerGeom;
}

if ( maxVal == 0. )
Expand All @@ -192,21 +185,19 @@ bool QgsGeometryGapCheck::mergeWithNeighbor( QgsGeometryGapCheckError *err, Chan

// Merge geometries
QgsFeaturePool *featurePool = mContext->featurePools[ mergeLayerId ];
QgsAbstractGeometry *errLayerGeom = errGeometry->clone();
std::unique_ptr<QgsAbstractGeometry> errLayerGeom( errGeometry->clone() );
errLayerGeom->transform( featurePool->getLayerToMapTransform(), QgsCoordinateTransform::ReverseTransform );
QgsGeometry mergeFeatureGeom = mergeFeature.geometry();
const QgsAbstractGeometry *mergeGeom = mergeFeatureGeom.constGet();
std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errLayerGeom, mContext->reducedTolerance );
QgsAbstractGeometry *combinedGeom = geomEngine->combine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), &errMsg );
delete errLayerGeom;
std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errLayerGeom.get(), mContext->reducedTolerance );
std::unique_ptr<QgsAbstractGeometry> combinedGeom( geomEngine->combine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), &errMsg ) );
if ( !combinedGeom || combinedGeom->isEmpty() || !QgsWkbTypes::isSingleType( combinedGeom->wkbType() ) )
{
delete combinedGeom;
return false;
}

// Add merged polygon to destination geometry
replaceFeatureGeometryPart( mergeLayerId, mergeFeature, mergePartIdx, combinedGeom, changes );
replaceFeatureGeometryPart( mergeLayerId, mergeFeature, mergePartIdx, combinedGeom.release(), changes );

return true;
}
Expand Down

0 comments on commit 448e769

Please sign in to comment.