Skip to content

Commit e7958d7

Browse files
author
jef
committedApr 16, 2011
fix #3439
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@15728 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

1 file changed

+120
-99
lines changed

1 file changed

+120
-99
lines changed
 

‎src/core/qgsgeometry.cpp

Lines changed: 120 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3233,125 +3233,126 @@ int QgsGeometry::splitGeometry( const QList<QgsPoint>& splitLine, QList<QgsGeome
32333233
/**Replaces a part of this geometry with another line*/
32343234
int QgsGeometry::reshapeGeometry( const QList<QgsPoint>& reshapeWithLine )
32353235
{
3236-
if ( reshapeWithLine.size() < 2 )
3237-
{
3238-
return 1;
3239-
}
3240-
if ( type() == QGis::Point )
3241-
{
3242-
return 1; //cannot reshape points
3243-
}
3244-
3245-
GEOSGeometry* reshapeLineGeos = createGeosLineString( reshapeWithLine.toVector() );
3246-
3247-
//make sure this geos geometry is up-to-date
3248-
if ( !mGeos || mDirtyGeos )
3249-
{
3250-
exportWkbToGeos();
3251-
}
3252-
3253-
//single or multi?
3254-
int numGeoms = GEOSGetNumGeometries( mGeos );
3255-
if ( numGeoms == -1 )
3256-
{
3257-
return 1;
3258-
}
3259-
3260-
bool isMultiGeom = false;
3261-
int geosTypeId = GEOSGeomTypeId( mGeos );
3262-
if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
3263-
{
3264-
isMultiGeom = true;
3265-
}
3266-
3267-
bool isLine = ( type() == QGis::Line );
3268-
3269-
//polygon or multipolygon?
3270-
if ( !isMultiGeom )
3271-
{
3272-
GEOSGeometry* reshapedGeometry;
3273-
if ( isLine )
3236+
if ( reshapeWithLine.size() < 2 )
32743237
{
3275-
reshapedGeometry = reshapeLine( mGeos, reshapeLineGeos );
3238+
return 1;
32763239
}
3277-
else
3240+
3241+
if ( type() == QGis::Point )
32783242
{
3279-
reshapedGeometry = reshapePolygon( mGeos, reshapeLineGeos );
3243+
return 1; //cannot reshape points
32803244
}
32813245

3282-
GEOSGeom_destroy( reshapeLineGeos );
3283-
if ( reshapedGeometry )
3246+
GEOSGeometry* reshapeLineGeos = createGeosLineString( reshapeWithLine.toVector() );
3247+
3248+
//make sure this geos geometry is up-to-date
3249+
if ( !mGeos || mDirtyGeos )
32843250
{
3285-
GEOSGeom_destroy( mGeos );
3286-
mGeos = reshapedGeometry;
3287-
mDirtyWkb = true;
3288-
return 0;
3251+
exportWkbToGeos();
32893252
}
3290-
else
3253+
3254+
//single or multi?
3255+
int numGeoms = GEOSGetNumGeometries( mGeos );
3256+
if ( numGeoms == -1 )
32913257
{
32923258
return 1;
32933259
}
3294-
}
3295-
else
3296-
{
3297-
//call reshape for each geometry part and replace mGeos with new geometry if reshape took place
3298-
bool reshapeTookPlace = false;
32993260

3300-
GEOSGeometry* currentReshapeGeometry = 0;
3301-
GEOSGeometry** newGeoms = new GEOSGeometry*[numGeoms];
3261+
bool isMultiGeom = false;
3262+
int geosTypeId = GEOSGeomTypeId( mGeos );
3263+
if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
3264+
{
3265+
isMultiGeom = true;
3266+
}
3267+
3268+
bool isLine = ( type() == QGis::Line );
33023269

3303-
for ( int i = 0; i < numGeoms; ++i )
3270+
//polygon or multipolygon?
3271+
if ( !isMultiGeom )
33043272
{
3273+
GEOSGeometry* reshapedGeometry;
33053274
if ( isLine )
33063275
{
3307-
currentReshapeGeometry = reshapeLine( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
3276+
reshapedGeometry = reshapeLine( mGeos, reshapeLineGeos );
33083277
}
33093278
else
33103279
{
3311-
currentReshapeGeometry = reshapePolygon( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
3280+
reshapedGeometry = reshapePolygon( mGeos, reshapeLineGeos );
33123281
}
33133282

3314-
if ( currentReshapeGeometry )
3283+
GEOSGeom_destroy( reshapeLineGeos );
3284+
if ( reshapedGeometry )
33153285
{
3316-
newGeoms[i] = currentReshapeGeometry;
3317-
reshapeTookPlace = true;
3286+
GEOSGeom_destroy( mGeos );
3287+
mGeos = reshapedGeometry;
3288+
mDirtyWkb = true;
3289+
return 0;
33183290
}
33193291
else
33203292
{
3321-
newGeoms[i] = GEOSGeom_clone( GEOSGetGeometryN( mGeos, i ) );
3293+
return 1;
33223294
}
33233295
}
3324-
GEOSGeom_destroy( reshapeLineGeos );
3325-
3326-
GEOSGeometry* newMultiGeom = 0;
3327-
if ( isLine )
3328-
{
3329-
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, newGeoms, numGeoms );
3330-
}
3331-
else //multipolygon
3296+
else
33323297
{
3333-
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTIPOLYGON, newGeoms, numGeoms );
3334-
}
3298+
//call reshape for each geometry part and replace mGeos with new geometry if reshape took place
3299+
bool reshapeTookPlace = false;
33353300

3336-
delete[] newGeoms;
3337-
if ( ! newMultiGeom )
3338-
{
3339-
return 3;
3340-
}
3301+
GEOSGeometry* currentReshapeGeometry = 0;
3302+
GEOSGeometry** newGeoms = new GEOSGeometry*[numGeoms];
33413303

3342-
if ( reshapeTookPlace )
3343-
{
3344-
GEOSGeom_destroy( mGeos );
3345-
mGeos = newMultiGeom;
3346-
mDirtyWkb = true;
3347-
return 0;
3348-
}
3349-
else
3350-
{
3351-
GEOSGeom_destroy( newMultiGeom );
3352-
return 1;
3304+
for ( int i = 0; i < numGeoms; ++i )
3305+
{
3306+
if ( isLine )
3307+
{
3308+
currentReshapeGeometry = reshapeLine( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
3309+
}
3310+
else
3311+
{
3312+
currentReshapeGeometry = reshapePolygon( GEOSGetGeometryN( mGeos, i ), reshapeLineGeos );
3313+
}
3314+
3315+
if ( currentReshapeGeometry )
3316+
{
3317+
newGeoms[i] = currentReshapeGeometry;
3318+
reshapeTookPlace = true;
3319+
}
3320+
else
3321+
{
3322+
newGeoms[i] = GEOSGeom_clone( GEOSGetGeometryN( mGeos, i ) );
3323+
}
3324+
}
3325+
GEOSGeom_destroy( reshapeLineGeos );
3326+
3327+
GEOSGeometry* newMultiGeom = 0;
3328+
if ( isLine )
3329+
{
3330+
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, newGeoms, numGeoms );
3331+
}
3332+
else //multipolygon
3333+
{
3334+
newMultiGeom = GEOSGeom_createCollection( GEOS_MULTIPOLYGON, newGeoms, numGeoms );
3335+
}
3336+
3337+
delete[] newGeoms;
3338+
if ( ! newMultiGeom )
3339+
{
3340+
return 3;
3341+
}
3342+
3343+
if ( reshapeTookPlace )
3344+
{
3345+
GEOSGeom_destroy( mGeos );
3346+
mGeos = newMultiGeom;
3347+
mDirtyWkb = true;
3348+
return 0;
3349+
}
3350+
else
3351+
{
3352+
GEOSGeom_destroy( newMultiGeom );
3353+
return 1;
3354+
}
33533355
}
3354-
}
33553356
}
33563357

33573358
int QgsGeometry::makeDifference( QgsGeometry* other )
@@ -5065,16 +5066,25 @@ GEOSGeometry* QgsGeometry::reshapePolygon( const GEOSGeometry* polygon, const GE
50655066

50665067
//do inner rings intersect?
50675068
const GEOSGeometry **innerRings = new const GEOSGeometry*[nRings];
5068-
for ( int i = 0; i < nRings; ++i )
5069+
5070+
try
50695071
{
5070-
innerRings[i] = GEOSGetInteriorRingN( polygon, i );
5071-
if ( GEOSIntersects( innerRings[i], reshapeLineGeos ) == 1 )
5072+
for ( int i = 0; i < nRings; ++i )
50725073
{
5073-
++nIntersections;
5074-
lastIntersectingRing = i;
5075-
lastIntersectingGeom = innerRings[i];
5074+
innerRings[i] = GEOSGetInteriorRingN( polygon, i );
5075+
if ( GEOSIntersects( innerRings[i], reshapeLineGeos ) == 1 )
5076+
{
5077+
++nIntersections;
5078+
lastIntersectingRing = i;
5079+
lastIntersectingGeom = innerRings[i];
5080+
}
50765081
}
50775082
}
5083+
catch ( GEOSException &e )
5084+
{
5085+
Q_UNUSED( e );
5086+
nIntersections = 0;
5087+
}
50785088

50795089
if ( nIntersections != 1 ) //reshape line is only allowed to intersect one ring
50805090
{
@@ -5173,10 +5183,21 @@ GEOSGeometry* QgsGeometry::reshapeLine( const GEOSGeometry* line, const GEOSGeom
51735183
return 0;
51745184
}
51755185

5176-
//make sure there are at least two intersection between line and reshape geometry
5177-
GEOSGeometry* intersectGeom = GEOSIntersection( line, reshapeLineGeos );
5178-
bool atLeastTwoIntersections = ( GEOSGeomTypeId( intersectGeom ) == GEOS_MULTIPOINT && GEOSGetNumGeometries( intersectGeom ) > 1 );
5179-
GEOSGeom_destroy( intersectGeom );
5186+
bool atLeastTwoIntersections;
5187+
5188+
try
5189+
{
5190+
//make sure there are at least two intersection between line and reshape geometry
5191+
GEOSGeometry* intersectGeom = GEOSIntersection( line, reshapeLineGeos );
5192+
atLeastTwoIntersections = ( GEOSGeomTypeId( intersectGeom ) == GEOS_MULTIPOINT && GEOSGetNumGeometries( intersectGeom ) > 1 );
5193+
GEOSGeom_destroy( intersectGeom );
5194+
}
5195+
catch ( GEOSException &e )
5196+
{
5197+
Q_UNUSED( e );
5198+
atLeastTwoIntersections = false;
5199+
}
5200+
51805201
if ( !atLeastTwoIntersections )
51815202
{
51825203
return 0;

0 commit comments

Comments
 (0)
Please sign in to comment.