Use optimised point getters/setters on GEOS >= 3.8

This commit is contained in:
Nyall Dawson 2019-10-12 05:53:43 +10:00
parent cfe1766e5a
commit fe296fa95d
5 changed files with 116 additions and 2 deletions

View File

@ -1225,12 +1225,19 @@ std::unique_ptr<QgsLineString> QgsGeos::sequenceToLinestring( const GEOSGeometry
double *m = mOut.data();
for ( unsigned int i = 0; i < nPoints; ++i )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
if ( hasZ )
GEOSCoordSeq_getXYZ_r( geosinit.ctxt, cs, i, x++, y++, z++ );
else
GEOSCoordSeq_getXY_r( geosinit.ctxt, cs, i, x++, y++ );
#else
GEOSCoordSeq_getX_r( geosinit.ctxt, cs, i, x++ );
GEOSCoordSeq_getY_r( geosinit.ctxt, cs, i, y++ );
if ( hasZ )
{
GEOSCoordSeq_getZ_r( geosinit.ctxt, cs, i, z++ );
}
#endif
if ( hasM )
{
GEOSCoordSeq_getOrdinate_r( geosinit.ctxt, cs, i, 3, m++ );
@ -1264,12 +1271,19 @@ QgsPoint QgsGeos::coordSeqPoint( const GEOSCoordSequence *cs, int i, bool hasZ,
double x, y;
double z = 0;
double m = 0;
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
if ( hasZ )
GEOSCoordSeq_getXYZ_r( geosinit.ctxt, cs, i, &x, &y, &z );
else
GEOSCoordSeq_getXY_r( geosinit.ctxt, cs, i, &x, &y );
#else
GEOSCoordSeq_getX_r( geosinit.ctxt, cs, i, &x );
GEOSCoordSeq_getY_r( geosinit.ctxt, cs, i, &y );
if ( hasZ )
{
GEOSCoordSeq_getZ_r( geosinit.ctxt, cs, i, &z );
}
#endif
if ( hasM )
{
GEOSCoordSeq_getOrdinate_r( geosinit.ctxt, cs, i, 3, &m );
@ -1831,12 +1845,23 @@ GEOSCoordSequence *QgsGeos::createCoordinateSequence( const QgsCurve *curve, dou
zData = hasZ ? line->zData() : nullptr;
mData = hasM ? line->mData() : nullptr;
}
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
if ( hasZ )
{
GEOSCoordSeq_setXYZ_r( geosinit.ctxt, coordSeq, i, std::round( *xData++ / precision ) * precision, std::round( *yData++ / precision ) * precision, std::round( *zData++ / precision ) * precision );
}
else
{
GEOSCoordSeq_setXY_r( geosinit.ctxt, coordSeq, i, std::round( *xData++ / precision ) * precision, std::round( *yData++ / precision ) * precision );
}
#else
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, std::round( *xData++ / precision ) * precision );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, std::round( *yData++ / precision ) * precision );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, std::round( *zData++ / precision ) * precision );
}
#endif
if ( hasM )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 3, line->mAt( *mData++ ) );
@ -1855,12 +1880,23 @@ GEOSCoordSequence *QgsGeos::createCoordinateSequence( const QgsCurve *curve, dou
zData = hasZ ? line->zData() : nullptr;
mData = hasM ? line->mData() : nullptr;
}
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
if ( hasZ )
{
GEOSCoordSeq_setXYZ_r( geosinit.ctxt, coordSeq, i, *xData++, *yData++, *zData++ );
}
else
{
GEOSCoordSeq_setXY_r( geosinit.ctxt, coordSeq, i, *xData++, *yData++ );
}
#else
GEOSCoordSeq_setX_r( geosinit.ctxt, coordSeq, i, *xData++ );
GEOSCoordSeq_setY_r( geosinit.ctxt, coordSeq, i, *yData++ );
if ( hasZ )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 2, *zData++ );
}
#endif
if ( hasM )
{
GEOSCoordSeq_setOrdinate_r( geosinit.ctxt, coordSeq, i, 3, *mData++ );
@ -1888,9 +1924,20 @@ geos::unique_ptr QgsGeos::createGeosPointXY( double x, double y, bool hasZ, doub
Q_UNUSED( m )
geos::unique_ptr geosPoint;
try
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
if ( coordDims == 2 )
{
// optimised constructor
if ( precision > 0. )
geosPoint.reset( GEOSGeom_createPointFromXY_r( geosinit.ctxt, std::round( x / precision ) * precision, std::round( y / precision ) * precision ) );
else
geosPoint.reset( GEOSGeom_createPointFromXY_r( geosinit.ctxt, x, y ) );
return geosPoint;
}
#endif
GEOSCoordSequence *coordSeq = GEOSCoordSeq_create_r( geosinit.ctxt, 1, coordDims );
if ( !coordSeq )
{

View File

@ -132,8 +132,12 @@ void FeaturePart::extractCoords( const GEOSGeometry *geom )
for ( int i = 0; i < nbPoints; ++i )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_getXY_r( geosctxt, coordSeq, i, &x[i], &y[i] );
#else
GEOSCoordSeq_getX_r( geosctxt, coordSeq, i, &x[i] );
GEOSCoordSeq_getY_r( geosctxt, coordSeq, i, &y[i] );
#endif
xmax = x[i] > xmax ? x[i] : xmax;
xmin = x[i] < xmin ? x[i] : xmin;
@ -320,8 +324,12 @@ std::unique_ptr<LabelPosition> FeaturePart::createCandidatePointOnSurface( Point
if ( pointGeom )
{
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom.get() );
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
#else
GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
#endif
}
}
catch ( GEOSException &e )

View File

@ -326,8 +326,12 @@ bool GeomFunction::containsCandidate( const GEOSPreparedGeometry *geom, double x
GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 5, 2 );
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, coord, 0, x, y );
#else
GEOSCoordSeq_setX_r( geosctxt, coord, 0, x );
GEOSCoordSeq_setY_r( geosctxt, coord, 0, y );
#endif
if ( !qgsDoubleNear( alpha, 0.0 ) )
{
double beta = alpha + M_PI_2;
@ -335,25 +339,41 @@ bool GeomFunction::containsCandidate( const GEOSPreparedGeometry *geom, double x
double dy1 = std::sin( alpha ) * width;
double dx2 = std::cos( beta ) * height;
double dy2 = std::sin( beta ) * height;
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, coord, 1, x + dx1, y + dy1 );
GEOSCoordSeq_setXY_r( geosctxt, coord, 2, x + dx1 + dx2, y + dy1 + dy2 );
GEOSCoordSeq_setXY_r( geosctxt, coord, 3, x + dx2, y + dy2 );
#else
GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + dx1 );
GEOSCoordSeq_setY_r( geosctxt, coord, 1, y + dy1 );
GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + dx1 + dx2 );
GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + dy1 + dy2 );
GEOSCoordSeq_setX_r( geosctxt, coord, 3, x + dx2 );
GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + dy2 );
#endif
}
else
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, coord, 1, x + width, y );
GEOSCoordSeq_setXY_r( geosctxt, coord, 2, x + width, y + height );
GEOSCoordSeq_setXY_r( geosctxt, coord, 3, x, y + height );
#else
GEOSCoordSeq_setX_r( geosctxt, coord, 1, x + width );
GEOSCoordSeq_setY_r( geosctxt, coord, 1, y );
GEOSCoordSeq_setX_r( geosctxt, coord, 2, x + width );
GEOSCoordSeq_setY_r( geosctxt, coord, 2, y + height );
GEOSCoordSeq_setX_r( geosctxt, coord, 3, x );
GEOSCoordSeq_setY_r( geosctxt, coord, 3, y + height );
#endif
}
//close ring
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, coord, 4, x, y );
#else
GEOSCoordSeq_setX_r( geosctxt, coord, 4, x );
GEOSCoordSeq_setY_r( geosctxt, coord, 4, y );
#endif
try
{

View File

@ -435,8 +435,12 @@ void Layer::chopFeaturesAtRepeatDistance()
std::vector<Point> points( n );
for ( unsigned int i = 0; i < n; ++i )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_getXY_r( geosctxt, cs, i, &points[i].x, &points[i].y );
#else
GEOSCoordSeq_getX_r( geosctxt, cs, i, &points[i].x );
GEOSCoordSeq_getY_r( geosctxt, cs, i, &points[i].y );
#endif
}
// Cumulative length vector
@ -469,8 +473,12 @@ void Layer::chopFeaturesAtRepeatDistance()
GEOSCoordSequence *cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
for ( int i = 0; i < part.size(); ++i )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, cooSeq, i, part[i].x, part[i].y );
#else
GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
#endif
}
GEOSGeometry *newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
FeaturePart *newfpart = new FeaturePart( fpart->feature(), newgeom );
@ -489,8 +497,12 @@ void Layer::chopFeaturesAtRepeatDistance()
GEOSCoordSequence *cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
for ( int i = 0; i < part.size(); ++i )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, cooSeq, i, part[i].x, part[i].y );
#else
GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
#endif
}
GEOSGeometry *newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );

View File

@ -127,15 +127,23 @@ void PointSet::createGeosGeom() const
GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, nbPoints + ( needClose ? 1 : 0 ), 2 );
for ( int i = 0; i < nbPoints; ++i )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, coord, i, x[i], y[i] );
#else
GEOSCoordSeq_setX_r( geosctxt, coord, i, x[i] );
GEOSCoordSeq_setY_r( geosctxt, coord, i, y[i] );
#endif
}
//close ring if needed
if ( needClose )
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_setXY_r( geosctxt, coord, nbPoints, x[0], y[0] );
#else
GEOSCoordSeq_setX_r( geosctxt, coord, nbPoints, x[0] );
GEOSCoordSeq_setY_r( geosctxt, coord, nbPoints, y[0] );
#endif
}
switch ( type )
@ -239,10 +247,14 @@ bool PointSet::containsPoint( double x, double y ) const
GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
try
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
geos::unique_ptr point( GEOSGeom_createPointFromXY_r( geosctxt, x, y ) );
#else
GEOSCoordSequence *seq = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
GEOSCoordSeq_setX_r( geosctxt, seq, 0, x );
GEOSCoordSeq_setY_r( geosctxt, seq, 0, y );
geos::unique_ptr point( GEOSGeom_createPoint_r( geosctxt, seq ) );
#endif
bool result = ( GEOSPreparedContainsProperly_r( geosctxt, preparedGeom(), point.get() ) == 1 );
return result;
@ -783,11 +795,14 @@ double PointSet::minDistanceToPoint( double px, double py, double *rx, double *r
GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();
try
{
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
geos::unique_ptr geosPt( GEOSGeom_createPointFromXY_r( geosctxt, px, py ) );
#else
GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
GEOSCoordSeq_setX_r( geosctxt, coord, 0, px );
GEOSCoordSeq_setY_r( geosctxt, coord, 0, py );
geos::unique_ptr geosPt( GEOSGeom_createPoint_r( geosctxt, coord ) );
#endif
int type = GEOSGeomTypeId_r( geosctxt, mGeos );
const GEOSGeometry *extRing = nullptr;
if ( type != GEOS_POLYGON )
@ -802,8 +817,12 @@ double PointSet::minDistanceToPoint( double px, double py, double *rx, double *r
geos::coord_sequence_unique_ptr nearestCoord( GEOSNearestPoints_r( geosctxt, extRing, geosPt.get() ) );
double nx;
double ny;
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
( void )GEOSCoordSeq_getXY_r( geosctxt, nearestCoord.get(), 0, &nx, &ny );
#else
( void )GEOSCoordSeq_getX_r( geosctxt, nearestCoord.get(), 0, &nx );
( void )GEOSCoordSeq_getY_r( geosctxt, nearestCoord.get(), 0, &ny );
#endif
if ( rx )
*rx = nx;
@ -834,8 +853,12 @@ void PointSet::getCentroid( double &px, double &py, bool forceInside ) const
if ( centroidGeom )
{
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, centroidGeom.get() );
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
#else
GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
#endif
}
// check if centroid inside in polygon
@ -846,8 +869,12 @@ void PointSet::getCentroid( double &px, double &py, bool forceInside ) const
if ( pointGeom )
{
const GEOSCoordSequence *coordSeq = GEOSGeom_getCoordSeq_r( geosctxt, pointGeom.get() );
#if GEOS_VERSION_MAJOR>3 || GEOS_VERSION_MINOR>=8
GEOSCoordSeq_getXY_r( geosctxt, coordSeq, 0, &px, &py );
#else
GEOSCoordSeq_getX_r( geosctxt, coordSeq, 0, &px );
GEOSCoordSeq_getY_r( geosctxt, coordSeq, 0, &py );
#endif
}
}
}