Skip to content

Commit

Permalink
Port fix geometries alg to c++
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 13, 2017
1 parent 07fd9cb commit 7c5521e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 110 deletions.
5 changes: 0 additions & 5 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -222,11 +222,6 @@ qgis:fixeddistancebuffer: >

The miter limit parameter is only applicable for miter join styles, and controls the maximum distance from the offset curve to use when creating a mitered join.

qgis:fixgeometries: >
This algorithm attempts to create a valid representation of a given invalid geometry without losing any of the input vertices. Already-valid geometries are returned without further intervention. Always outputs multi-geometry layer.

NOTE: M values will be dropped from the output.

qgis:frequencyanalysis: >
This algorithm generates a table with frequency analysis of the values of a selected attribute from an input vector layer

Expand Down
101 changes: 0 additions & 101 deletions python/plugins/processing/algs/qgis/FixGeometry.py

This file was deleted.

2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -75,7 +75,6 @@
from .FieldsMapper import FieldsMapper
from .FindProjection import FindProjection
from .FixedDistanceBuffer import FixedDistanceBuffer
from .FixGeometry import FixGeometry
from .GeometryConvert import GeometryConvert
from .GeometryByExpression import GeometryByExpression
from .Gridify import Gridify
Expand Down Expand Up @@ -216,7 +215,6 @@ def getAlgs(self):
FieldsPyculator(),
FindProjection(),
FixedDistanceBuffer(),
FixGeometry(),
GeometryByExpression(),
GeometryConvert(),
Gridify(),
Expand Down
Expand Up @@ -2729,7 +2729,7 @@ tests:
# name: expected/zonal_statistics.gml
# type: vector

- algorithm: qgis:fixgeometries
- algorithm: native:fixgeometries
name: Fix geometries
params:
INPUT:
Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgsgeometrymakevalid.cpp
Expand Up @@ -928,7 +928,7 @@ QgsAbstractGeometry *_qgis_lwgeom_make_valid( const QgsAbstractGeometry *lwgeom_
}
else
{
QgsDebugMsg( "original geom converted to GEOS" );
QgsDebugMsgLevel( "original geom converted to GEOS", 4 );
}

GEOSGeometry *geosout = LWGEOM_GEOS_makeValid( geosgeom, errorMessage );
Expand Down
52 changes: 52 additions & 0 deletions src/core/processing/qgsnativealgorithms.cpp
Expand Up @@ -78,6 +78,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsPromoteToMultipartAlgorithm() );
addAlgorithm( new QgsSelectByLocationAlgorithm() );
addAlgorithm( new QgsExtractByLocationAlgorithm() );
addAlgorithm( new QgsFixGeometriesAlgorithm() );
}

void QgsCentroidAlgorithm::initAlgorithm( const QVariantMap & )
Expand Down Expand Up @@ -1614,5 +1615,56 @@ QVariantMap QgsExtractByLocationAlgorithm::processAlgorithm( const QVariantMap &
}


QString QgsFixGeometriesAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm attempts to create a valid representation of a given invalid geometry without "
"losing any of the input vertices. Already-valid geometries are returned without further intervention. "
"Always outputs multi-geometry layer.\n\n"
"NOTE: M values will be dropped from the output." );
}

QgsFixGeometriesAlgorithm *QgsFixGeometriesAlgorithm::createInstance() const
{
return new QgsFixGeometriesAlgorithm();
}

QgsFeature QgsFixGeometriesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback )
{
if ( !feature.hasGeometry() )
return feature;

QgsFeature outputFeature = feature;

QgsGeometry outputGeometry = outputFeature.geometry().makeValid();
if ( !outputGeometry )
{
feedback->pushInfo( QObject::tr( "makeValid failed for feature %1 " ).arg( feature.id() ) );
outputFeature.clearGeometry();
return outputFeature;
}

if ( outputGeometry.wkbType() == QgsWkbTypes::Unknown ||
QgsWkbTypes::flatType( outputGeometry.geometry()->wkbType() ) == QgsWkbTypes::GeometryCollection )
{
// keep only the parts of the geometry collection with correct type
const QList< QgsGeometry > tmpGeometries = outputGeometry.asGeometryCollection();
QList< QgsGeometry > matchingParts;
for ( const QgsGeometry &g : tmpGeometries )
{
if ( g.type() == feature.geometry().type() )
matchingParts << g;
}
if ( !matchingParts.empty() )
outputGeometry = QgsGeometry::collectGeometry( matchingParts );
else
outputGeometry = QgsGeometry();
}

outputGeometry.convertToMultiType();
outputFeature.setGeometry( outputGeometry );
return outputFeature;
}

///@endcond


23 changes: 23 additions & 0 deletions src/core/processing/qgsnativealgorithms.h
Expand Up @@ -556,6 +556,29 @@ class QgsExtractByLocationAlgorithm : public QgsLocationBasedAlgorithm

};

/**
* Native repair geometries algorithm.
*/
class QgsFixGeometriesAlgorithm : public QgsProcessingFeatureBasedAlgorithm
{

public:

QgsFixGeometriesAlgorithm() = default;
QString name() const override { return QStringLiteral( "fixgeometries" ); }
QString displayName() const override { return QObject::tr( "Fix geometries" ); }
virtual QStringList tags() const override { return QObject::tr( "repair,invalid,geometry,make,valid" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry" ); }
QString shortHelpString() const override;
QgsFixGeometriesAlgorithm *createInstance() const override SIP_FACTORY;

protected:
QString outputName() const override { return QObject::tr( "Fixed geometries" ); }
QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type type ) const override { return QgsWkbTypes::multiType( type ); }
QgsFeature processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback ) override;

};

///@endcond PRIVATE

#endif // QGSNATIVEALGORITHMS_H
Expand Down

0 comments on commit 7c5521e

Please sign in to comment.