Skip to content

Commit

Permalink
Avoid calling geos methods for some more trivial point to point geome…
Browse files Browse the repository at this point in the history
…try calculations
  • Loading branch information
nyalldawson committed Sep 22, 2020
1 parent 6a00257 commit fe50150
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/core/geometry/qgsgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand All @@ -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 );
Expand Down
12 changes: 12 additions & 0 deletions tests/src/python/test_qgsgeometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
# | |
Expand Down

0 comments on commit fe50150

Please sign in to comment.