Skip to content

Commit

Permalink
Use pointers instead of references for QgsAbstractGeometry
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Aug 13, 2017
1 parent b2cd9f2 commit feffa04
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 43 deletions.
4 changes: 1 addition & 3 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -2013,9 +2013,7 @@ QgsGeometry QgsGeometry::makeValid()
return QgsGeometry();

QString errorMsg;
QgsAbstractGeometry *g = _qgis_lwgeom_make_valid( *d->geometry, errorMsg );
if ( !g )
return QgsGeometry();
QgsAbstractGeometry *g = _qgis_lwgeom_make_valid( d->geometry, errorMsg );

return QgsGeometry( g );
}
Expand Down
70 changes: 34 additions & 36 deletions src/core/geometry/qgsgeometrymakevalid.cpp
Expand Up @@ -338,16 +338,16 @@ static GEOSGeometry *LWGEOM_GEOS_getPointN( const GEOSGeometry *g_in, uint32_t n
}


static bool lwline_make_geos_friendly( QgsLineString &line );
static bool lwpoly_make_geos_friendly( QgsPolygonV2 &poly );
static bool lwcollection_make_geos_friendly( QgsGeometryCollection &g );
static bool lwline_make_geos_friendly( QgsLineString *line );
static bool lwpoly_make_geos_friendly( QgsPolygonV2 *poly );
static bool lwcollection_make_geos_friendly( QgsGeometryCollection *g );


// Ensure the geometry is "structurally" valid (enough for GEOS to accept it)
static bool lwgeom_make_geos_friendly( QgsAbstractGeometry &geom )
static bool lwgeom_make_geos_friendly( QgsAbstractGeometry *geom )
{
QgsDebugMsg( QString( "lwgeom_make_geos_friendly enter (type %1)" ).arg( geom.wkbType() ) );
switch ( QgsWkbTypes::flatType( geom.wkbType() ) )
QgsDebugMsg( QString( "lwgeom_make_geos_friendly enter (type %1)" ).arg( geom->wkbType() ) );
switch ( QgsWkbTypes::flatType( geom->wkbType() ) )
{
case QgsWkbTypes::Point:
case QgsWkbTypes::MultiPoint:
Expand All @@ -357,82 +357,82 @@ static bool lwgeom_make_geos_friendly( QgsAbstractGeometry &geom )

case QgsWkbTypes::LineString:
// lines need at least 2 points
return lwline_make_geos_friendly( qgsgeometry_cast<QgsLineString &>( geom ) );
return lwline_make_geos_friendly( qgsgeometry_cast<QgsLineString *>( geom ) );
break;

case QgsWkbTypes::Polygon:
// polygons need all rings closed and with npoints > 3
return lwpoly_make_geos_friendly( qgsgeometry_cast<QgsPolygonV2 &>( geom ) );
return lwpoly_make_geos_friendly( qgsgeometry_cast<QgsPolygonV2 *>( geom ) );
break;

case QgsWkbTypes::MultiLineString:
case QgsWkbTypes::MultiPolygon:
case QgsWkbTypes::GeometryCollection:
return lwcollection_make_geos_friendly( qgsgeometry_cast<QgsGeometryCollection &>( geom ) );
return lwcollection_make_geos_friendly( qgsgeometry_cast<QgsGeometryCollection *>( geom ) );
break;

default:
QgsDebugMsg( QString( "lwgeom_make_geos_friendly: unsupported input geometry type: %1" ).arg( geom.wkbType() ) );
QgsDebugMsg( QString( "lwgeom_make_geos_friendly: unsupported input geometry type: %1" ).arg( geom->wkbType() ) );
break;
}
return false;
}


static bool ring_make_geos_friendly( QgsCurve &ring )
static bool ring_make_geos_friendly( QgsCurve *ring )
{
if ( ring.nCoordinates() == 0 )
if ( ring->nCoordinates() == 0 )
return false;

// earlier we allowed in only geometries with straight segments
QgsLineString &linestring = dynamic_cast<QgsLineString &>( ring );
QgsLineString *linestring = qgsgeometry_cast<QgsLineString *>( ring );

// close the ring if not already closed (2d only)

QgsPoint p1 = linestring.startPoint(), p2 = linestring.endPoint();
QgsPoint p1 = linestring->startPoint(), p2 = linestring->endPoint();
if ( p1.x() != p2.x() || p1.y() != p2.y() )
linestring.addVertex( p1 );
linestring->addVertex( p1 );

// must have at least 4 coordinates to be accepted by GEOS

while ( linestring.nCoordinates() < 4 )
linestring.addVertex( p1 );
while ( linestring->nCoordinates() < 4 )
linestring->addVertex( p1 );

return true;
}

// Make sure all rings are closed and have > 3 points.
static bool lwpoly_make_geos_friendly( QgsPolygonV2 &poly )
static bool lwpoly_make_geos_friendly( QgsPolygonV2 *poly )
{
// If the polygon has no rings there's nothing to do
// TODO: in qgis representation there always is exterior ring
//if ( ! poly->nrings ) return true;

// All rings must be closed and have > 3 points
for ( int i = 0; i < poly.numInteriorRings(); i++ )
for ( int i = 0; i < poly->numInteriorRings(); i++ )
{
if ( !ring_make_geos_friendly( *const_cast<QgsCurve *>( poly.interiorRing( i ) ) ) )
if ( !ring_make_geos_friendly( qgsgeometry_cast<QgsCurve *>( poly->interiorRing( i ) ) ) )
return false;
}

return true;
}

// Need NO or >1 points. Duplicate first if only one.
static bool lwline_make_geos_friendly( QgsLineString &line )
static bool lwline_make_geos_friendly( QgsLineString *line )
{
if ( line.numPoints() == 1 ) // 0 is fine, 2 is fine
if ( line->numPoints() == 1 ) // 0 is fine, 2 is fine
{
line.addVertex( line.startPoint() );
line->addVertex( line->startPoint() );
}
return true;
}

static bool lwcollection_make_geos_friendly( QgsGeometryCollection &g )
static bool lwcollection_make_geos_friendly( QgsGeometryCollection *g )
{
for ( int i = 0; i < g.numGeometries(); i++ )
for ( int i = 0; i < g->numGeometries(); i++ )
{
if ( !lwgeom_make_geos_friendly( *g.geometryN( i ) ) )
if ( !lwgeom_make_geos_friendly( g->geometryN( i ) ) )
return false;
}

Expand Down Expand Up @@ -895,34 +895,32 @@ static GEOSGeometry *LWGEOM_GEOS_makeValid( const GEOSGeometry *gin, QString &er
}


QgsAbstractGeometry *_qgis_lwgeom_make_valid( const QgsAbstractGeometry &lwgeom_in, QString &errorMessage )
QgsAbstractGeometry *_qgis_lwgeom_make_valid( const QgsAbstractGeometry *lwgeom_in, QString &errorMessage )
{
//bool is3d = FLAGS_GET_Z(lwgeom_in->flags);

// try to convert to GEOS, if impossible, clean that up first
// otherwise (adding only duplicates of existing points)
GEOSContextHandle_t handle = QgsGeos::getGEOSHandler();

GEOSGeometry *geosgeom = QgsGeos::asGeos( &lwgeom_in );
if ( ! geosgeom )
GEOSGeometry *geosgeom = QgsGeos::asGeos( lwgeom_in );
if ( !geosgeom )
{
QgsDebugMsg( "Original geom can't be converted to GEOS - will try cleaning that up first" );

QgsAbstractGeometry *lwgeom_in_clone = lwgeom_in.clone();
if ( !lwgeom_make_geos_friendly( *lwgeom_in_clone ) )
std::unique_ptr<QgsAbstractGeometry> lwgeom_in_clone( lwgeom_in->clone() );
if ( !lwgeom_make_geos_friendly( lwgeom_in_clone.get() ) )
{
QgsDebugMsg( "Could not make a valid geometry out of input" );
}

// try again as we did cleanup now
// TODO: invoke LWGEOM2GEOS directly with autoclean ?
geosgeom = QgsGeos::asGeos( lwgeom_in_clone );

delete lwgeom_in_clone;
geosgeom = QgsGeos::asGeos( lwgeom_in_clone.get() );

if ( ! geosgeom )
{
errorMessage = "Couldn't convert QGIS geom to GEOS";
errorMessage = "Could not convert QGIS geom to GEOS";
return nullptr;
}
}
Expand All @@ -942,7 +940,7 @@ QgsAbstractGeometry *_qgis_lwgeom_make_valid( const QgsAbstractGeometry &lwgeom_
return nullptr;

// force multi-type if we had a multi-type before
if ( QgsWkbTypes::isMultiType( lwgeom_in.wkbType() ) && !QgsWkbTypes::isMultiType( lwgeom_out->wkbType() ) )
if ( QgsWkbTypes::isMultiType( lwgeom_in->wkbType() ) && !QgsWkbTypes::isMultiType( lwgeom_out->wkbType() ) )
{
QgsGeometryCollection *collection = nullptr;
switch ( QgsWkbTypes::multiType( lwgeom_out->wkbType() ) )
Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgsgeometrymakevalid.h
Expand Up @@ -22,6 +22,6 @@ class QString;
class QgsAbstractGeometry;

//! Implementation of QgsGeometry::makeValid(). Not a public API.
QgsAbstractGeometry *_qgis_lwgeom_make_valid( const QgsAbstractGeometry &lwgeom_in, QString &errorMessage );
QgsAbstractGeometry *_qgis_lwgeom_make_valid( const QgsAbstractGeometry *lwgeom_in, QString &errorMessage );

#endif // QGSGEOMETRYMAKEVALID_H
6 changes: 3 additions & 3 deletions src/core/qgsmaptopixelgeometrysimplifier.cpp
Expand Up @@ -137,7 +137,7 @@ QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
// Write the geometry
if ( flatType == QgsWkbTypes::LineString || flatType == QgsWkbTypes::CircularString )
{
const QgsCurve &srcCurve = qgsgeometry_cast<const QgsCurve &>( geometry );
const QgsCurve &srcCurve = dynamic_cast<const QgsCurve &>( geometry );
std::unique_ptr<QgsCurve> output( createEmptySameTypeGeom( srcCurve ) );
double x = 0.0, y = 0.0, lastX = 0.0, lastY = 0.0;
QgsRectangle r;
Expand Down Expand Up @@ -267,7 +267,7 @@ QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
}
else if ( flatType == QgsWkbTypes::Polygon )
{
const QgsPolygonV2 &srcPolygon = qgsgeometry_cast<const QgsPolygonV2 &>( geometry );
const QgsPolygonV2 &srcPolygon = dynamic_cast<const QgsPolygonV2 &>( geometry );
std::unique_ptr<QgsPolygonV2> polygon( new QgsPolygonV2() );
polygon->setExteriorRing( qgsgeometry_cast<QgsCurve *>( simplifyGeometry( simplifyFlags, simplifyAlgorithm, srcPolygon.exteriorRing()->wkbType(), *srcPolygon.exteriorRing(), envelope, map2pixelTol, true ).geometry()->clone() ) );
for ( int i = 0; i < srcPolygon.numInteriorRings(); ++i )
Expand All @@ -279,7 +279,7 @@ QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
}
else if ( QgsWkbTypes::isMultiType( flatType ) )
{
const QgsGeometryCollection &srcCollection = qgsgeometry_cast<const QgsGeometryCollection &>( geometry );
const QgsGeometryCollection &srcCollection = dynamic_cast<const QgsGeometryCollection &>( geometry );
std::unique_ptr<QgsGeometryCollection> collection( createEmptySameTypeGeom( srcCollection ) );
const int numGeoms = srcCollection.numGeometries();
for ( int i = 0; i < numGeoms; ++i )
Expand Down

0 comments on commit feffa04

Please sign in to comment.