Skip to content
Permalink
Browse files
fix #2829
git-svn-id: http://svn.osgeo.org/qgis/trunk@15812 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Apr 22, 2011
1 parent 6877ecb commit f33d9f2ed07f7d9a7f40cd062584270bbfdbbcde
Showing with 104 additions and 94 deletions.
  1. +4 −0 src/app/qgsmaptoolsplitfeatures.cpp
  2. +96 −90 src/core/qgsgeometry.cpp
  3. +4 −4 src/core/qgsvectorlayer.cpp
@@ -86,6 +86,10 @@ void QgsMapToolSplitFeatures::canvasReleaseEvent( QMouseEvent * e )
{
QMessageBox::warning( 0, tr( "No feature split done" ), tr( "Cut edges detected. Make sure the line splits features into multiple parts." ) );
}
else if ( returnCode == 7 )
{
QMessageBox::warning( 0, tr( "No feature split done" ), tr( "The geometry is invalid. Please repair before trying to split it." ) );
}
else if ( returnCode != 0 )
{
//several intersections but only one split (most likely line)
@@ -3177,12 +3177,18 @@ int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeome
{
exportGeosToWkb();
}

if ( !mGeos || mDirtyGeos )
{
if ( !exportWkbToGeos() )
return 1;
}

if ( !GEOSisValid( mGeos ) )
{
return 7;
}

//make sure splitLine is valid
if ( splitLine.size() < 2 )
{
@@ -3233,126 +3239,126 @@ int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeome
/**Replaces a part of this geometry with another line*/
int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
{
if ( reshapeWithLine.size() < 2 )
{
return 1;
}
if ( reshapeWithLine.size() < 2 )
{
return 1;
}

if ( type() == QGis::Point )
{
return 1; //cannot reshape points
}
if ( type() == QGis::Point )
{
return 1; //cannot reshape points
}

GEOSGeometry* reshapeLineGeos = createGeosLineString( reshapeWithLine.toVector() );

//make sure this geos geometry is up-to-date
if ( !mGeos || mDirtyGeos )
{
exportWkbToGeos();
}

GEOSGeometry* reshapeLineGeos = createGeosLineString( reshapeWithLine.toVector() );
//single or multi?
int numGeoms = GEOSGetNumGeometries( mGeos );
if ( numGeoms == -1 )
{
return 1;
}

bool isMultiGeom = false;
int geosTypeId = GEOSGeomTypeId( mGeos );
if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
{
isMultiGeom = true;
}

//make sure this geos geometry is up-to-date
if ( !mGeos || mDirtyGeos )
bool isLine = ( type() == QGis::Line );

//polygon or multipolygon?
if ( !isMultiGeom )
{
GEOSGeometry* reshapedGeometry;
if ( isLine )
{
exportWkbToGeos();
reshapedGeometry = reshapeLine( mGeos, reshapeLineGeos );
}

//single or multi?
int numGeoms = GEOSGetNumGeometries( mGeos );
if ( numGeoms == -1 )
else
{
return 1;
reshapedGeometry = reshapePolygon( mGeos, reshapeLineGeos );
}

bool isMultiGeom = false;
int geosTypeId = GEOSGeomTypeId( mGeos );
if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
GEOSGeom_destroy( reshapeLineGeos );
if ( reshapedGeometry )
{
isMultiGeom = true;
GEOSGeom_destroy( mGeos );
mGeos = reshapedGeometry;
mDirtyWkb = true;
return 0;
}
else
{
return 1;
}
}
else
{
//call reshape for each geometry part and replace mGeos with new geometry if reshape took place
bool reshapeTookPlace = false;

bool isLine = ( type() == QGis::Line );
GEOSGeometry* currentReshapeGeometry = 0;
GEOSGeometry** newGeoms = new GEOSGeometry*[numGeoms];

//polygon or multipolygon?
if ( !isMultiGeom )
for ( int i = 0; i < numGeoms; ++i )
{
GEOSGeometry* reshapedGeometry;
if ( isLine )
{
reshapedGeometry = reshapeLine( mGeos, reshapeLineGeos );
currentReshapeGeometry = reshapeLine( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
}
else
{
reshapedGeometry = reshapePolygon( mGeos, reshapeLineGeos );
currentReshapeGeometry = reshapePolygon( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
}

GEOSGeom_destroy( reshapeLineGeos );
if ( reshapedGeometry )
if ( currentReshapeGeometry )
{
GEOSGeom_destroy( mGeos );
mGeos = reshapedGeometry;
mDirtyWkb = true;
return 0;
newGeoms[i] = currentReshapeGeometry;
reshapeTookPlace = true;
}
else
{
return 1;
newGeoms[i] = GEOSGeom_clone( GEOSGetGeometryN( mGeos, i ) );
}
}
else
{
//call reshape for each geometry part and replace mGeos with new geometry if reshape took place
bool reshapeTookPlace = false;

GEOSGeometry* currentReshapeGeometry = 0;
GEOSGeometry** newGeoms = new GEOSGeometry*[numGeoms];

for ( int i = 0; i < numGeoms; ++i )
{
if ( isLine )
{
currentReshapeGeometry = reshapeLine( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
}
else
{
currentReshapeGeometry = reshapePolygon( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
}

if ( currentReshapeGeometry )
{
newGeoms[i] = currentReshapeGeometry;
reshapeTookPlace = true;
}
else
{
newGeoms[i] = GEOSGeom_clone( GEOSGetGeometryN( mGeos, i ) );
}
}
GEOSGeom_destroy( reshapeLineGeos );
GEOSGeom_destroy( reshapeLineGeos );

GEOSGeometry* newMultiGeom = 0;
if ( isLine )
{
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, newGeoms, numGeoms );
}
else //multipolygon
{
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTIPOLYGON, newGeoms, numGeoms );
}
GEOSGeometry* newMultiGeom = 0;
if ( isLine )
{
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, newGeoms, numGeoms );
}
else //multipolygon
{
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTIPOLYGON, newGeoms, numGeoms );
}

delete[] newGeoms;
if ( ! newMultiGeom )
{
return 3;
}
delete[] newGeoms;
if ( ! newMultiGeom )
{
return 3;
}

if ( reshapeTookPlace )
{
GEOSGeom_destroy( mGeos );
mGeos = newMultiGeom;
mDirtyWkb = true;
return 0;
}
else
{
GEOSGeom_destroy( newMultiGeom );
return 1;
}
if ( reshapeTookPlace )
{
GEOSGeom_destroy( mGeos );
mGeos = newMultiGeom;
mDirtyWkb = true;
return 0;
}
else
{
GEOSGeom_destroy( newMultiGeom );
return 1;
}
}
}

int QgsGeometry::makeDifference( QgsGeometry* other )
@@ -2272,7 +2272,7 @@ int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topolo
QgsRectangle bBox; //bounding box of the split line
int returnCode = 0;
int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
int numberOfSplitedFeatures = 0;
int numberOfSplittedFeatures = 0;

QgsFeatureList featureList;
const QgsFeatureIds selectedIds = selectedFeaturesIds();
@@ -2352,15 +2352,15 @@ int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topolo
addTopologicalPoints( *topol_it );
}
}
++numberOfSplitedFeatures;
++numberOfSplittedFeatures;
}
else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
{
returnCode = 3;
returnCode = splitFunctionReturn;
}
}

if ( numberOfSplitedFeatures == 0 && selectedIds.size() > 0 )
if ( numberOfSplittedFeatures == 0 && selectedIds.size() > 0 )
{
//There is a selection but no feature has been split.
//Maybe user forgot that only the selected features are split

0 comments on commit f33d9f2

Please sign in to comment.