Skip to content
Permalink
Browse files

Make geometry import/export more robust in case of invalid geometries.

…Fixes #12836
  • Loading branch information
mhugent committed Jun 4, 2015
1 parent f39fbf4 commit 08f2f4138d838423c7d33caf8a606b160b41173c
@@ -177,13 +177,24 @@ bool QgsGeometryCollectionV2::fromWkb( const unsigned char * wkb )
wkbPtr >> mWkbType;
int nGeometries = 0;
wkbPtr >> nGeometries;
mGeometries.resize( nGeometries );

QList<QgsAbstractGeometryV2*> geometryList;
for ( int i = 0; i < nGeometries; ++i )
{
QgsAbstractGeometryV2* geom = QgsGeometryImport::geomFromWkb( wkbPtr );
mGeometries[i] = geom;
wkbPtr += geom->wkbSize();
if ( geom )
{
geometryList.append( geom );
wkbPtr += geom->wkbSize();
}
}

mGeometries.resize( geometryList.size() );
for ( int i = 0; i < geometryList.size(); ++i )
{
mGeometries[i] = geometryList.at( i );
}

return true;
}

@@ -198,7 +209,10 @@ int QgsGeometryCollectionV2::wkbSize() const
int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
foreach ( const QgsAbstractGeometryV2 *geom, mGeometries )
{
size += geom->wkbSize();
if ( geom )
{
size += geom->wkbSize();
}
}
return size;
}
@@ -214,10 +228,13 @@ unsigned char* QgsGeometryCollectionV2::asWkb( int& binarySize ) const
foreach ( const QgsAbstractGeometryV2 *geom, mGeometries )
{
int geomWkbLen = 0;
unsigned char* geomWkb = geom->asWkb( geomWkbLen );
memcpy( wkb, geomWkb, geomWkbLen );
wkb += geomWkbLen;
delete[] geomWkb;
if ( geom )
{
unsigned char* geomWkb = geom->asWkb( geomWkbLen );
memcpy( wkb, geomWkb, geomWkbLen );
wkb += geomWkbLen;
delete[] geomWkb;
}
}
return geomPtr;
}
@@ -21,6 +21,7 @@
#include "qgscurvepolygonv2.h"
#include "qgspointv2.h"
#include "qgspolygonv2.h"
#include "qgscurvepolygonv2.h"
#include "qgslinestringv2.h"
#include "qgsmulticurvev2.h"
#include "qgsmultilinestringv2.h"
@@ -229,6 +230,12 @@ QgsAbstractGeometryV2* QgsGeometryImport::geomFromWkbType( QgsWKBTypes::Type t )
return new QgsMultiPolygonV2();
case QgsWKBTypes::MultiPoint:
return new QgsMultiPointV2();
case QgsWKBTypes::MultiCurve:
return new QgsMultiCurveV2();
case QgsWKBTypes::MultiSurface:
return new QgsMultiSurfaceV2();
case QgsWKBTypes::GeometryCollection:
return new QgsGeometryCollectionV2();
default:
return 0;
}
@@ -1009,12 +1009,42 @@ GEOSGeometry* QgsGeos::asGeos( const QgsAbstractGeometryV2* geom )
{
return 0;
}
GEOSGeometry **geomarr = new GEOSGeometry*[ c->numGeometries()];
for ( int i = 0; i < c->numGeometries(); ++i )

try
{
geomarr[i] = asGeos( c->geometryN( i ) );

//GEOSGeometry **geomarr = new GEOSGeometry*[ c->numGeometries()];
QList< GEOSGeometry* > validGeoms;
GEOSGeometry* geosGeom = 0;
for ( int i = 0; i < c->numGeometries(); ++i )
{
geosGeom = asGeos( c->geometryN( i ) );
if ( geosGeom )
{
validGeoms.append( geosGeom );
}
}

if ( validGeoms.size() < 1 )
{
return 0;
}

GEOSGeometry **geomarr = new GEOSGeometry*[ validGeoms.size()];
for ( int i = 0; i < validGeoms.size(); ++i )
{
geomarr[i] = validGeoms.at( i );
}

return GEOSGeom_createCollection_r( geosinit.ctxt, geosType, geomarr, validGeoms.size() );
}

catch ( GEOSException &e )
{
Q_UNUSED( e );
//delete?
return 0;
}
return GEOSGeom_createCollection_r( geosinit.ctxt, geosType, geomarr, c->numGeometries() ); //todo: geos exceptions
}

return 0;
@@ -1415,6 +1445,10 @@ GEOSGeometry* QgsGeos::createGeosPolygon( const QgsAbstractGeometryV2* poly )
return 0;

const QgsCurveV2* exteriorRing = polygon->exteriorRing();
if ( !exteriorRing )
{
return 0;
}
GEOSGeometry* exteriorRingGeos = GEOSGeom_createLinearRing_r( geosinit.ctxt, createCoordinateSequence( exteriorRing ) );

int nHoles = polygon->numInteriorRings();
@@ -48,7 +48,12 @@ bool QgsPolygonV2::fromWkb( const unsigned char* wkb )
{
QgsLineStringV2* line = new QgsLineStringV2();
line->fromWkbPoints( mWkbType, wkbPtr );
if ( i == 0 )
if ( !line->isRing() )
{
delete line; continue;
}

if ( !mExteriorRing )
{
mExteriorRing = line;
}

1 comment on commit 08f2f41

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn commented on 08f2f41 Jun 5, 2015

@mhugent happy to report that this has indeed fixed the issue I reported. Thanks :)

Please sign in to comment.
You can’t perform that action at this time.