Skip to content
Permalink
Browse files

Avoid calling geos methods for some more trivial point to point geome…

…try calculations
  • Loading branch information
nyalldawson committed Sep 22, 2020
1 parent 6a00257 commit fe501506ddde1b429788f91911627bb0ee8cd91b
Showing with 24 additions and 0 deletions.
  1. +12 −0 src/core/geometry/qgsgeometry.cpp
  2. +12 −0 tests/src/python/test_qgsgeometry.py
@@ -609,6 +609,12 @@ double QgsGeometry::sqrDistToVertexAt( QgsPointXY &point, int atVertex ) const

QgsGeometry QgsGeometry::nearestPoint( const QgsGeometry &other ) const
{
// avoid calling geos for trivial point calculations
if ( d->geometry && QgsWkbTypes::flatType( d->geometry->wkbType() ) == QgsWkbTypes::Point )
{
return QgsGeometry( qgsgeometry_cast< const QgsPoint * >( d->geometry.get() )->clone() );
}

QgsGeos geos( d->geometry.get() );
mLastError.clear();
QgsGeometry result = geos.closestPoint( other );
@@ -618,6 +624,12 @@ QgsGeometry QgsGeometry::nearestPoint( const QgsGeometry &other ) const

QgsGeometry QgsGeometry::shortestLine( const QgsGeometry &other ) const
{
// avoid calling geos for trivial point-to-point line calculations
if ( d->geometry && QgsWkbTypes::flatType( d->geometry->wkbType() ) == QgsWkbTypes::Point && QgsWkbTypes::flatType( other.wkbType() ) == QgsWkbTypes::Point )
{
return QgsGeometry( qgis::make_unique< QgsLineString >( *qgsgeometry_cast< const QgsPoint * >( d->geometry.get() ), *qgsgeometry_cast< const QgsPoint * >( other.constGet() ) ) );
}

QgsGeos geos( d->geometry.get() );
mLastError.clear();
QgsGeometry result = geos.shortestLine( other, &mLastError );
@@ -1991,6 +1991,13 @@ def testNearestPoint(self):
wkt = g1.nearestPoint(g2).asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

# trivial point case
expWkt = 'Point (3 4)'
wkt = QgsGeometry.fromWkt('Point(3 4)').nearestPoint(QgsGeometry.fromWkt('Point(-1 -8)')).asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))
wkt = QgsGeometry.fromWkt('Point(3 4)').nearestPoint(QgsGeometry.fromWkt('LineString( 1 1, 5 1, 5 5 )')).asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

def testShortestLine(self):
# test with empty geometries
g1 = QgsGeometry()
@@ -2022,6 +2029,11 @@ def testShortestLine(self):
wkt = g1.shortestLine(g2).asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

# trivial point to point case
expWkt = 'LineString (3 4, -1 -8)'
wkt = QgsGeometry.fromWkt('Point(3 4)').shortestLine(QgsGeometry.fromWkt('Point(-1 -8)')).asWkt()
self.assertTrue(compareWkt(expWkt, wkt), "Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))

def testBoundingBox(self):
# 2-+-+-+-+-3
# | |

0 comments on commit fe50150

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