Skip to content

Commit

Permalink
Fixes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Apr 18, 2018
1 parent 4f829fd commit 45b264d
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 254 deletions.
12 changes: 12 additions & 0 deletions python/core/geometry/qgsgeometry.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,18 @@ If it is already a single part geometry, it will return true and
not change the geometry.

:return: true in case of success and false else
%End

bool convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType );
%Docstring
Converts geometry collection to a the desired geometry type subclass (multi-point,
multi-linestring or multi-polygon). Child geometries of different type are filtered out.
Does nothing the geometry is not a geometry collection. May leave the geometry
empty if none of the child geometries match the desired type.

:return: true in case of success and false else

.. versionadded:: 3.2
%End

int avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers );
Expand Down
5 changes: 0 additions & 5 deletions python/plugins/processing/algs/help/qgis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,6 @@ qgis:importintopostgis: >

Prior to this a connection between QGIS and the PostGIS database has to be created (for example with the DB Manager).

qgis:intersection: >
This algorithm extracts the overlapping portions of features in the Input and Intersect layers. Features in the Intersection layer are assigned the attributes of the overlapping features from both the Input and Intersect layers.

Attributes are not modified.

qgis:joinattributesbylocation: >
This algorithm takes an input vector layer and creates a new vector layer that is an extended version of the input one, with additional attributes in its attribute table.

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

This file was deleted.

2 changes: 0 additions & 2 deletions python/plugins/processing/algs/qgis/QgisAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
from .IdwInterpolation import IdwInterpolation
from .ImportIntoPostGIS import ImportIntoPostGIS
from .ImportIntoSpatialite import ImportIntoSpatialite
from .Intersection import Intersection
from .KeepNBiggestParts import KeepNBiggestParts
from .LinesToPolygons import LinesToPolygons
from .MinimumBoundingGeometry import MinimumBoundingGeometry
Expand Down Expand Up @@ -198,7 +197,6 @@ def getAlgs(self):
IdwInterpolation(),
ImportIntoPostGIS(),
ImportIntoSpatialite(),
Intersection(),
KeepNBiggestParts(),
LinesToPolygons(),
MinimumBoundingGeometry(),
Expand Down
69 changes: 18 additions & 51 deletions src/analysis/processing/qgsalgorithmintersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,8 @@
#include "qgsgeometrycollection.h"
#include "qgsgeometryengine.h"

#include "qgsmultipoint.h"
#include "qgsmultipolygon.h"
#include "qgsmultilinestring.h"

///@cond PRIVATE

static QgsGeometry geometryCollectionToSingleGeometryType( const QgsGeometry &geom, QgsWkbTypes::GeometryType geomType )
{
const QgsGeometryCollection *origGeom = qgsgeometry_cast<const QgsGeometryCollection *>( geom.constGet() );
if ( !origGeom )
return QgsGeometry();

QgsGeometryCollection *resGeom = nullptr;
switch ( geomType )
{
case QgsWkbTypes::PointGeometry:
resGeom = new QgsMultiPoint;
break;
case QgsWkbTypes::LineGeometry:
resGeom = new QgsMultiLineString;
break;
case QgsWkbTypes::PolygonGeometry:
resGeom = new QgsMultiPolygon;
break;
default:
break;
}
if ( !resGeom )
return QgsGeometry();

for ( int i = 0; i < origGeom->numGeometries(); ++i )
{
const QgsAbstractGeometry *g = origGeom->geometryN( i );
if ( QgsWkbTypes::geometryType( g->wkbType() ) == geomType )
resGeom->addGeometry( g->clone() );
}
return QgsGeometry( resGeom );
}


QString QgsIntersectionAlgorithm::name() const
{
Expand All @@ -78,6 +41,12 @@ QString QgsIntersectionAlgorithm::groupId() const
return QStringLiteral( "vectoroverlay" );
}

QString QgsIntersectionAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm extracts the overlapping portions of features in the Input and Overlay layers. Features in the Overlay layer are assigned the attributes of the overlapping features from both the Input and Overlay layers." )
+ QStringLiteral( "\n\n" )
+ QObject::tr( "Optionally, the rotation can occur around a preset point. If not set the rotation occurs around each feature's centroid." );
}

QgsProcessingAlgorithm *QgsIntersectionAlgorithm::createInstance() const
{
Expand Down Expand Up @@ -225,27 +194,25 @@ QVariantMap QgsIntersectionAlgorithm::processAlgorithm( const QVariantMap &param

if ( intGeom.isNull() )
{
// TODO: not sure if this ever happens - if it does, that means GEOS failed badly and we should try to provide an error from it
throw QgsProcessingException( QObject::tr( "GEOS geoprocessing error: intersection failed." ) );
// TODO: not sure if this ever happens - if it does, that means GEOS failed badly - would be good to have a test for such situation
throw QgsProcessingException( QStringLiteral( "%1\n\n%2" ).arg( QObject::tr( "GEOS geoprocessing error: intersection failed." ), intGeom.lastError() ) );
}

// Intersection of geometries may give use also geometries we do not want in our results.
// For example, two square polygons touching at the corner have a point as the intersection, but no area.
// In other cases we may get a mixture of geometries in the output - we want to keep only the expected types.
if ( QgsWkbTypes::geometryType( intGeom.wkbType() ) != QgsWkbTypes::geometryType( geomType ) )
if ( QgsWkbTypes::flatType( intGeom.wkbType() ) == QgsWkbTypes::GeometryCollection )
{
if ( QgsWkbTypes::flatType( intGeom.wkbType() ) == QgsWkbTypes::GeometryCollection )
{
// try to filter out irrelevant parts with different geometry type than what we want
intGeom = geometryCollectionToSingleGeometryType( intGeom, QgsWkbTypes::geometryType( geomType ) );
if ( intGeom.isEmpty() )
continue;
}
else
{
// we can't make use of this resulting geometry -
// try to filter out irrelevant parts with different geometry type than what we want
intGeom.convertGeometryCollectionToSubclass( QgsWkbTypes::geometryType( geomType ) );
if ( intGeom.isEmpty() )
continue;
}
}

if ( QgsWkbTypes::geometryType( intGeom.wkbType() ) != QgsWkbTypes::geometryType( geomType ) )
{
// we can't make use of this resulting geometry
continue;
}

const QgsAttributes attrsB( featB.attributes() );
Expand Down
1 change: 1 addition & 0 deletions src/analysis/processing/qgsalgorithmintersection.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class QgsIntersectionAlgorithm : public QgsProcessingAlgorithm
virtual QString displayName() const override;
virtual QString group() const override;
virtual QString groupId() const override;
QString shortHelpString() const override;

protected:
virtual QgsProcessingAlgorithm *createInstance() const override;
Expand Down
37 changes: 37 additions & 0 deletions src/core/geometry/qgsgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,43 @@ bool QgsGeometry::convertToSingleType()
return true;
}


bool QgsGeometry::convertGeometryCollectionToSubclass( QgsWkbTypes::GeometryType geomType )
{
const QgsGeometryCollection *origGeom = qgsgeometry_cast<const QgsGeometryCollection *>( constGet() );
if ( !origGeom )
return false;

std::unique_ptr<QgsGeometryCollection> resGeom;
switch ( geomType )
{
case QgsWkbTypes::PointGeometry:
resGeom = qgis::make_unique<QgsMultiPoint>();
break;
case QgsWkbTypes::LineGeometry:
resGeom = qgis::make_unique<QgsMultiLineString>();
break;
case QgsWkbTypes::PolygonGeometry:
resGeom = qgis::make_unique<QgsMultiPolygon>();
break;
default:
break;
}
if ( !resGeom )
return false;

for ( int i = 0; i < origGeom->numGeometries(); ++i )
{
const QgsAbstractGeometry *g = origGeom->geometryN( i );
if ( QgsWkbTypes::geometryType( g->wkbType() ) == geomType )
resGeom->addGeometry( g->clone() );
}

set( resGeom.release() );
return true;
}


QgsPointXY QgsGeometry::asPoint() const
{
if ( !d->geometry || QgsWkbTypes::flatType( d->geometry->wkbType() ) != QgsWkbTypes::Point )
Expand Down
Loading

0 comments on commit 45b264d

Please sign in to comment.