Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix multi split for multilinestring (#34510)
* Fix multi split for multilinestring
  • Loading branch information
lbartoletti committed Mar 20, 2020
1 parent 02623cd commit 364dc3f
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .ci/azure-pipelines/azure-pipelines.yml
@@ -1,7 +1,7 @@
variables:
LR: release-3_12
LTR: release-3_10
CTEST_CUSTOM_TESTS_IGNORE: "ProcessingGdalAlgorithmsRasterTest;ProcessingGdalAlgorithmsVectorTest;ProcessingGrass7AlgorithmsImageryTest;ProcessingGrass7AlgorithmsRasterTest;ProcessingGrass7AlgorithmsVectorTest;ProcessingGuiTest;ProcessingOtbAlgorithmsTest;ProcessingQgisAlgorithmsTestPt1;ProcessingQgisAlgorithmsTestPt2;ProcessingQgisAlgorithmsTestPt3;ProcessingQgisAlgorithmsTestPt4;ProcessingScriptUtilsTest;PyQgsAnnotation;PyQgsAppStartup;PyQgsAuthManagerOAuth2OWSTest;PyQgsAuthManagerPasswordOWSTest;PyQgsAuthManagerPKIOWSTest;PyQgsAuthManagerProxy;PyQgsAuthSettingsWidget;PyQgsAuxiliaryStorage;PyQgsBlockingNetworkRequest;PyQgsExifTools;PyQgsFileDownloader;PyQgsFileUtils;PyQgsGeometryTest;PyQgsImageCache;PyQgsImportIntoPostGIS;PyQgsLayoutAtlas;PyQgsLayoutLegend;PyQgsLayoutMap;PyQgsLayoutMapGrid;PyQgsMapLayer;PyQgsOfflineEditingWFS;PyQgsOGRProvider;PyQgsOGRProviderGpkg;PyQgsOGRProviderSqlite;PyQgsPalLabelingCanvas;PyQgsPalLabelingLayout;PyQgsPalLabelingPlacement;PyQgsPointDisplacementRenderer;PyQgsProject;PyQgsProviderConnectionGpkg;PyQgsProviderConnectionPostgres;PyQgsPythonProvider;PyQgsRasterFileWriter;PyQgsRasterLayer;PyQgsSelectiveMasking;PyQgsServerAccessControlWMSGetlegendgraphic;PyQgsServerApi;PyQgsServerCacheManager;PyQgsServerLocaleOverride;PyQgsServerSecurity;PyQgsServerSettings;PyQgsServerWMS;PyQgsServerWMSDimension;PyQgsServerWMSGetFeatureInfo;PyQgsServerWMSGetLegendGraphic;PyQgsServerWMSGetMap;PyQgsServerWMSGetPrint;PyQgsServerWMTS;PyQgsSettings;PyQgsShapefileProvider;PyQgsSpatialiteProvider;PyQgsSvgCache;PyQgsSymbolLayer;PyQgsTaskManager;PyQgsTextRenderer;PyQgsVectorFileWriter;PyQgsVectorLayer;PyQgsVectorLayerUtils;PyQgsVirtualLayerProvider;PyQgsWFSProviderGUI;PyQgsZipUtils;qgis_3drenderingtest;qgis_alignrastertest;qgis_arcgisrestutilstest;qgis_banned_keywords;qgis_browsermodeltest;qgis_callouttest;qgis_compositionconvertertest;qgis_coordinatereferencesystemtest;qgis_datadefinedsizelegendtest;qgis_datumtransformdialog;qgis_diagramtest;qgis_doxygen_order;qgis_dxfexporttest;qgis_expressiontest;qgis_filedownloader;qgis_geometrycheckstest;qgis_geometrytest;qgis_geonodeconnectiontest;qgis_grassprovidertest7;qgis_imagecachetest;qgis_invertedpolygonrenderertest;qgis_labelingenginetest;qgis_layerdefinitiontest;qgis_layout3dmaptest;qgis_layouthtmltest;qgis_layoutlabeltest;qgis_layoutmapgridtest;qgis_layoutmaptest;qgis_layoutpicturetest;qgis_layoutscalebartest;qgis_layouttabletest;qgis_legendrenderertest;qgis_licenses;qgis_maprendererjobtest;qgis_maprotationtest;qgis_mapsettingsutilstest;qgis_maptooladdfeatureline;qgis_mimedatautilstest;qgis_networkaccessmanagertest;qgis_openclutilstest;qgis_painteffecttest;qgis_pallabelingtest;qgis_processingtest;qgis_projecttest;qgis_qgisappclipboard;qgis_rasterlayersaveasdialog;qgis_shellcheck;qgis_sipify;qgis_sip_include;qgis_sip_uptodate;qgis_spelling;qgis_styletest;qgis_svgcachetest;qgis_taskmanagertest;qgis_transformdialog;qgis_vectorfilewritertest;qgis_wcsprovidertest;qgis_ziplayertest;qgis_meshcalculator;qgis_pointlocatortest;PyQgsExpressionBuilderWidget;PyQgsDatumTransform;qgis_vertextool;PyQgsCoordinateOperationWidget;PyQgsProviderConnectionSpatialite"
CTEST_CUSTOM_TESTS_IGNORE: "ProcessingGdalAlgorithmsRasterTest;ProcessingGdalAlgorithmsVectorTest;ProcessingGrass7AlgorithmsImageryTest;ProcessingGrass7AlgorithmsRasterTest;ProcessingGrass7AlgorithmsVectorTest;ProcessingGuiTest;ProcessingOtbAlgorithmsTest;ProcessingQgisAlgorithmsTestPt1;ProcessingQgisAlgorithmsTestPt2;ProcessingQgisAlgorithmsTestPt3;ProcessingQgisAlgorithmsTestPt4;ProcessingScriptUtilsTest;PyQgsAnnotation;PyQgsAppStartup;PyQgsAuthManagerOAuth2OWSTest;PyQgsAuthManagerPasswordOWSTest;PyQgsAuthManagerPKIOWSTest;PyQgsAuthManagerProxy;PyQgsAuthSettingsWidget;PyQgsAuxiliaryStorage;PyQgsBlockingNetworkRequest;PyQgsExifTools;PyQgsFileDownloader;PyQgsFileUtils;PyQgsGeometryTest;PyQgsImageCache;PyQgsImportIntoPostGIS;PyQgsLayoutAtlas;PyQgsLayoutLegend;PyQgsLayoutMap;PyQgsLayoutMapGrid;PyQgsMapLayer;PyQgsOfflineEditingWFS;PyQgsOGRProvider;PyQgsOGRProviderGpkg;PyQgsOGRProviderSqlite;PyQgsPalLabelingCanvas;PyQgsPalLabelingLayout;PyQgsPalLabelingPlacement;PyQgsPointDisplacementRenderer;PyQgsProject;PyQgsProviderConnectionGpkg;PyQgsProviderConnectionPostgres;PyQgsPythonProvider;PyQgsRasterFileWriter;PyQgsRasterLayer;PyQgsSelectiveMasking;PyQgsServerAccessControlWMSGetlegendgraphic;PyQgsServerApi;PyQgsServerCacheManager;PyQgsServerLocaleOverride;PyQgsServerSecurity;PyQgsServerSettings;PyQgsServerWMS;PyQgsServerWMSDimension;PyQgsServerWMSGetFeatureInfo;PyQgsServerWMSGetLegendGraphic;PyQgsServerWMSGetMap;PyQgsServerWMSGetPrint;PyQgsServerWMTS;PyQgsSettings;PyQgsShapefileProvider;PyQgsSpatialiteProvider;PyQgsSvgCache;PyQgsSymbolLayer;PyQgsTaskManager;PyQgsTextRenderer;PyQgsVectorFileWriter;PyQgsVectorLayer;PyQgsVectorLayerUtils;PyQgsVirtualLayerProvider;PyQgsWFSProviderGUI;PyQgsZipUtils;qgis_3drenderingtest;qgis_alignrastertest;qgis_arcgisrestutilstest;qgis_banned_keywords;qgis_browsermodeltest;qgis_callouttest;qgis_compositionconvertertest;qgis_coordinatereferencesystemtest;qgis_datadefinedsizelegendtest;qgis_datumtransformdialog;qgis_diagramtest;qgis_doxygen_order;qgis_dxfexporttest;qgis_expressiontest;qgis_filedownloader;qgis_geometrycheckstest;qgis_geometrytest;qgis_geonodeconnectiontest;qgis_grassprovidertest7;qgis_imagecachetest;qgis_invertedpolygonrenderertest;qgis_labelingenginetest;qgis_layerdefinitiontest;qgis_layout3dmaptest;qgis_layouthtmltest;qgis_layoutlabeltest;qgis_layoutmapgridtest;qgis_layoutmaptest;qgis_layoutpicturetest;qgis_layoutscalebartest;qgis_layouttabletest;qgis_legendrenderertest;qgis_licenses;qgis_maprendererjobtest;qgis_maprotationtest;qgis_mapsettingsutilstest;qgis_maptooladdfeatureline;qgis_mimedatautilstest;qgis_networkaccessmanagertest;qgis_openclutilstest;qgis_painteffecttest;qgis_pallabelingtest;qgis_processingtest;qgis_projecttest;qgis_qgisappclipboard;qgis_rasterlayersaveasdialog;qgis_shellcheck;qgis_sipify;qgis_sip_include;qgis_sip_uptodate;qgis_spelling;qgis_styletest;qgis_svgcachetest;qgis_taskmanagertest;qgis_transformdialog;qgis_vectorfilewritertest;qgis_wcsprovidertest;qgis_ziplayertest;qgis_meshcalculator;qgis_pointlocatortest;PyQgsExpressionBuilderWidget;PyQgsDatumTransform;qgis_vertextool;PyQgsCoordinateOperationWidget;PyQgsProviderConnectionSpatialite;qgis_maptoolsplitpartstest

This comment has been minimized.

Copy link
@nirvn

nirvn Mar 20, 2020

Contributor

@lbartoletti , that broke azure.

This comment has been minimized.

Copy link
@roya0045

roya0045 Mar 20, 2020

Contributor

@nirvn To be honest the escape character error was present in the tests before this was merged. I just think that the mistake introduced here was hidden by the escape character error.

Agent.Source.Git.ShallowFetchDepth: 120

trigger:
Expand Down
7 changes: 5 additions & 2 deletions python/core/auto_generated/geometry/qgsgeometry.sip.in
Expand Up @@ -839,29 +839,32 @@ Rotate this geometry around the Z axis
:return: OperationResult a result code: success or reason of failure
%End

OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries /Out/, bool topological, QVector<QgsPointXY> &topologyTestPoints /Out/ ) /Deprecated/;
OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries /Out/, bool topological, QVector<QgsPointXY> &topologyTestPoints /Out/, bool splitFeature = true ) /Deprecated/;
%Docstring
Splits this geometry according to a given line.

:param splitLine: the line that splits the geometry
\param[out] newGeometries list of new geometries that have been created with the split
:param topological: ``True`` if topological editing is enabled
\param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
:param splitFeature: Set to True if you want to split a feature, otherwise set to False to split parts

:return: OperationResult a result code: success or reason of failure

.. deprecated:: QGIS 3.12
- will be removed in QGIS 4.0. Use the variant which accepts QgsPoint objects instead of QgsPointXY.
%End

OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries /Out/, bool topological, QgsPointSequence &topologyTestPoints /Out/ );
OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries /Out/, bool topological, QgsPointSequence &topologyTestPoints /Out/, bool splitFeature = true );
%Docstring
Splits this geometry according to a given line.

:param splitLine: the line that splits the geometry
\param[out] newGeometries list of new geometries that have been created with the split
:param topological: ``True`` if topological editing is enabled
\param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
:param splitFeature: Set to True if you want to split a feature, otherwise set to False to split parts
fix this bug?

:return: OperationResult a result code: success or reason of failure
%End
Expand Down
Binary file not shown.
@@ -1 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
4 changes: 2 additions & 2 deletions src/app/qgsmaptoolsplitparts.h
Expand Up @@ -19,11 +19,11 @@
#include "qgsmaptoolcapture.h"

//! A map tool that draws a line and splits the parts cut by the line
class QgsMapToolSplitParts: public QgsMapToolCapture
class APP_EXPORT QgsMapToolSplitParts: public QgsMapToolCapture
{
Q_OBJECT
public:
explicit QgsMapToolSplitParts( QgsMapCanvas *canvas );
QgsMapToolSplitParts( QgsMapCanvas *canvas );
void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
};

Expand Down
10 changes: 5 additions & 5 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -813,14 +813,14 @@ QgsGeometry::OperationResult QgsGeometry::rotate( double rotation, const QgsPoin
return QgsGeometry::Success;
}

QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries, bool topological, QVector<QgsPointXY> &topologyTestPoints )
QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries, bool topological, QVector<QgsPointXY> &topologyTestPoints, bool splitFeature )
{
QgsPointSequence split, topology;
convertPointList( splitLine, split );
convertPointList( topologyTestPoints, topology );
return splitGeometry( split, newGeometries, topological, topology );
return splitGeometry( split, newGeometries, topological, topology, splitFeature );
}
QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries, bool topological, QgsPointSequence &topologyTestPoints )
QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries, bool topological, QgsPointSequence &topologyTestPoints, bool splitFeature )
{
if ( !d->geometry )
{
Expand All @@ -836,8 +836,8 @@ QgsGeometry::OperationResult QgsGeometry::splitGeometry( const QgsPointSequence

if ( result == QgsGeometryEngine::Success )
{
*this = newGeoms.takeAt( 0 );

if ( splitFeature )
*this = newGeoms.takeAt( 0 );
newGeometries = newGeoms;
}

Expand Down
7 changes: 5 additions & 2 deletions src/core/geometry/qgsgeometry.h
Expand Up @@ -881,20 +881,23 @@ class CORE_EXPORT QgsGeometry
* \param[out] newGeometries list of new geometries that have been created with the split
* \param topological TRUE if topological editing is enabled
* \param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
* \param splitFeature Set to True if you want to split a feature, otherwise set to False to split parts
* \returns OperationResult a result code: success or reason of failure
* \deprecated since QGIS 3.12 - will be removed in QGIS 4.0. Use the variant which accepts QgsPoint objects instead of QgsPointXY.
*/
Q_DECL_DEPRECATED OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT ) SIP_DEPRECATED;
Q_DECL_DEPRECATED OperationResult splitGeometry( const QVector<QgsPointXY> &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QVector<QgsPointXY> &topologyTestPoints SIP_OUT, bool splitFeature = true ) SIP_DEPRECATED;

/**
* Splits this geometry according to a given line.
* \param splitLine the line that splits the geometry
* \param[out] newGeometries list of new geometries that have been created with the split
* \param topological TRUE if topological editing is enabled
* \param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset
* \param splitFeature Set to True if you want to split a feature, otherwise set to False to split parts
* fix this bug?
* \returns OperationResult a result code: success or reason of failure
*/
OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT );
OperationResult splitGeometry( const QgsPointSequence &splitLine, QVector<QgsGeometry> &newGeometries SIP_OUT, bool topological, QgsPointSequence &topologyTestPoints SIP_OUT, bool splitFeature = true );

/**
* Replaces a part of this geometry with another line
Expand Down
28 changes: 10 additions & 18 deletions src/core/qgsvectorlayereditutils.cpp
Expand Up @@ -475,35 +475,27 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitParts( const QgsPoint
fit = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
}

QgsGeometry::OperationResult addPartRet = QgsGeometry::OperationResult::Success;

QgsFeature feat;
while ( fit.nextFeature( feat ) )
{
QVector<QgsGeometry> newGeometries;
QgsPointSequence topologyTestPoints;
QgsGeometry featureGeom = feat.geometry();
splitFunctionReturn = featureGeom.splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
if ( splitFunctionReturn == 0 )
splitFunctionReturn = featureGeom.splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints, false );

if ( splitFunctionReturn == QgsGeometry::OperationResult::Success && !newGeometries.isEmpty() )
{
//add new parts
if ( !newGeometries.isEmpty() )
featureGeom.convertToMultiType();
QgsGeometry newGeom( newGeometries.at( 0 ) );
newGeom.convertToMultiType();

for ( int i = 0; i < newGeometries.size(); ++i )
for ( int i = 1; i < newGeometries.size(); ++i )
{
addPartRet = featureGeom.addPart( newGeometries.at( i ) );
if ( addPartRet )
break;
QgsGeometry part = newGeometries.at( i );
part.convertToSingleType();
newGeom.addPart( part );
}

// For test only: Exception already thrown here...
// feat.geometry()->asWkb();

if ( !addPartRet )
{
mLayer->changeGeometry( feat.id(), featureGeom );
}
mLayer->changeGeometry( feat.id(), newGeom );

if ( topologicalEditing )
{
Expand Down
1 change: 1 addition & 0 deletions tests/src/app/CMakeLists.txt
Expand Up @@ -129,6 +129,7 @@ ADD_QGIS_TEST(maptoolmovefeaturetest testqgsmaptoolmovefeature.cpp)
ADD_QGIS_TEST(maptoolellipsetest testqgsmaptoolellipse.cpp)
ADD_QGIS_TEST(maptoolrectangletest testqgsmaptoolrectangle.cpp)
ADD_QGIS_TEST(maptoolregularpolygontest testqgsmaptoolregularpolygon.cpp)
ADD_QGIS_TEST(maptoolsplitpartstest testqgsmaptoolsplitparts.cpp)
ADD_QGIS_TEST(measuretool testqgsmeasuretool.cpp)
ADD_QGIS_TEST(vertextool testqgsvertextool.cpp)
ADD_QGIS_TEST(vectorlayersaveasdialogtest testqgsvectorlayersaveasdialog.cpp)
Expand Down

0 comments on commit 364dc3f

Please sign in to comment.