Skip to content

Commit

Permalink
Optimise QgsGeos conversions
Browse files Browse the repository at this point in the history
Avoid some unnecessary creation of QgsPointV2
  • Loading branch information
nyalldawson committed Mar 26, 2017
1 parent 314842d commit 8eb3553
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 33 deletions.
5 changes: 2 additions & 3 deletions src/core/geometry/qgsgeometry.cpp
Expand Up @@ -1192,9 +1192,8 @@ QgsPolyline QgsGeometry::asPolyline() const
polyLine.resize( nVertices );
for ( int i = 0; i < nVertices; ++i )
{
QgsPointV2 pt = line->pointN( i );
polyLine[i].setX( pt.x() );
polyLine[i].setY( pt.y() );
polyLine[i].setX( line->xAt( i ) );
polyLine[i].setY( line->yAt( i ) );
}

if ( doSegmentation )
Expand Down
61 changes: 31 additions & 30 deletions src/core/geometry/qgsgeos.cpp
Expand Up @@ -417,8 +417,7 @@ int QgsGeos::splitGeometry( const QgsLineString &splitLine,
}
else if ( splitLine.numPoints() == 1 )
{
QgsPointV2 pt = splitLine.pointN( 0 );
splitLineGeos = createGeosPoint( &pt, 2, mPrecision );
splitLineGeos = createGeosPointXY( splitLine.xAt( 0 ), splitLine.yAt( 0 ), false, 0, false, 0, 2, mPrecision );
}
else
{
Expand Down Expand Up @@ -1544,33 +1543,31 @@ GEOSCoordSequence *QgsGeos::createCoordinateSequence( const QgsCurve *curve, dou
{
for ( int i = 0; i < numOutPoints; ++i )
{
const QgsPointV2 &pt = line->pointN( i % numPoints ); //todo: create method to get const point reference
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, qgsRound( pt.x() / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, qgsRound( pt.y() / precision ) * precision );
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, qgsRound( line->xAt( i % numPoints ) / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, qgsRound( line->yAt( i % numPoints ) / precision ) * precision );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, qgsRound( pt.z() / precision ) * precision );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, qgsRound( line->zAt( i % numPoints ) / precision ) * precision );
}
if ( hasM )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 3, pt.m() );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 3, line->mAt( i % numPoints ) );
}
}
}
else
{
for ( int i = 0; i < numOutPoints; ++i )
{
const QgsPointV2 &pt = line->pointN( i % numPoints ); //todo: create method to get const point reference
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, pt.x() );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, pt.y() );
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, line->xAt( i % numPoints ) );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, line->yAt( i % numPoints ) );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, pt.z() );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, line->zAt( i % numPoints ) );
}
if ( hasM )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 3, pt.m() );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 3, line->mAt( i % numPoints ) );
}
}
}
Expand All @@ -1590,6 +1587,14 @@ GEOSGeometry *QgsGeos::createGeosPoint( const QgsAbstractGeometry *point, int co
if ( !pt )
return nullptr;

return createGeosPointXY( pt->x(), pt->y(), pt->is3D(), pt->z(), pt->isMeasure(), pt->m(), coordDims, precision );
}

GEOSGeometry *QgsGeos::createGeosPointXY( double x, double y, bool hasZ, double z, bool hasM, double m, int coordDims, double precision )
{
Q_UNUSED( hasM );
Q_UNUSED( m );

GEOSGeometry *geosPoint = nullptr;

try
Expand All @@ -1602,26 +1607,26 @@ GEOSGeometry *QgsGeos::createGeosPoint( const QgsAbstractGeometry *point, int co
}
if ( precision > 0. )
{
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, 0, qgsRound( pt->x() / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, 0, qgsRound( pt->y() / precision ) * precision );
if ( pt->is3D() )
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, 0, qgsRound( x / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, 0, qgsRound( y / precision ) * precision );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 2, qgsRound( pt->z() / precision ) * precision );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 2, qgsRound( z / precision ) * precision );
}
}
else
{
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, 0, pt->x() );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, 0, pt->y() );
if ( pt->is3D() )
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, 0, x );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, 0, y );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 2, pt->z() );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 2, z );
}
}
#if 0 //disabled until geos supports m-coordinates
if ( pt->isMeasure() )
if ( hasM )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 3, pt->m() );
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, 0, 3, m );
}
#endif
geosPoint = GEOSGeom_createPoint_r( geosinit.ctxt, coordSeq );
Expand Down Expand Up @@ -2165,10 +2170,8 @@ GEOSGeometry *QgsGeos::reshapeLine( const GEOSGeometry *line, const GEOSGeometry
if ( !_linestringEndpoints( line, x1, y1, x2, y2 ) )
return nullptr;

QgsPointV2 beginPoint( x1, y1 );
GEOSGeometry *beginLineVertex = createGeosPoint( &beginPoint, 2, precision );
QgsPointV2 endPoint( x2, y2 );
GEOSGeometry *endLineVertex = createGeosPoint( &endPoint, 2, precision );
GEOSGeometry *beginLineVertex = createGeosPointXY( x1, y1, false, 0, false, 0, 2, precision );
GEOSGeometry *endLineVertex = createGeosPointXY( x2, y2, false, 0, false, 0, 2, precision );

bool isRing = false;
if ( GEOSGeomTypeId_r( geosinit.ctxt, line ) == GEOS_LINEARRING
Expand Down Expand Up @@ -2225,10 +2228,8 @@ GEOSGeometry *QgsGeos::reshapeLine( const GEOSGeometry *line, const GEOSGeometry
GEOSCoordSeq_getY_r( geosinit.ctxt, currentCoordSeq, 0, &yBegin );
GEOSCoordSeq_getX_r( geosinit.ctxt, currentCoordSeq, currentCoordSeqSize - 1, &xEnd );
GEOSCoordSeq_getY_r( geosinit.ctxt, currentCoordSeq, currentCoordSeqSize - 1, &yEnd );
QgsPointV2 beginPoint( xBegin, yBegin );
GEOSGeometry *beginCurrentGeomVertex = createGeosPoint( &beginPoint, 2, precision );
QgsPointV2 endPoint( xEnd, yEnd );
GEOSGeometry *endCurrentGeomVertex = createGeosPoint( &endPoint, 2, precision );
GEOSGeometry *beginCurrentGeomVertex = createGeosPointXY( xBegin, yBegin, false, 0, false, 0, 2, precision );
GEOSGeometry *endCurrentGeomVertex = createGeosPointXY( xEnd, yEnd, false, 0, false, 0, 2, precision );

//check how many endpoints of the line merge result are on the (original) line
int nEndpointsOnOriginalLine = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/core/geometry/qgsgeos.h
Expand Up @@ -190,6 +190,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine

static GEOSContextHandle_t getGEOSHandler();


private:
mutable GEOSGeometry *mGeos;
const GEOSPreparedGeometry *mGeosPrepared = nullptr;
Expand Down Expand Up @@ -228,6 +229,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
*/
static GEOSGeometry *createGeosCollection( int typeId, const QVector<GEOSGeometry *> &geoms );

static GEOSGeometry *createGeosPointXY( double x, double y, bool hasZ, double z, bool hasM, double m, int coordDims, double precision );
static GEOSGeometry *createGeosPoint( const QgsAbstractGeometry *point, int coordDims, double precision );
static GEOSGeometry *createGeosLinestring( const QgsAbstractGeometry *curve, double precision );
static GEOSGeometry *createGeosPolygon( const QgsAbstractGeometry *poly, double precision );
Expand Down

0 comments on commit 8eb3553

Please sign in to comment.