Skip to content

Commit b6d0320

Browse files
authoredAug 11, 2016
Fix closest segment for points (#3383)
* Make closestSegment() behave as expected by QgsGeometry::closestSegmentWithContext This fixes a bug that QgsPointLocator::nearestEdge() would return valid match even for point layers. * Shortcut if using QgsPointLocator with a wrong layer type
1 parent 7233d26 commit b6d0320

File tree

5 files changed

+27
-9
lines changed

5 files changed

+27
-9
lines changed
 

‎python/core/geometry/qgsabstractgeometry.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ class QgsAbstractGeometry
261261
* @param leftOf returns whether the point lies on the left side of the nearest segment (true if point is to left of segment,
262262
* false if point is to right of segment)
263263
* @param epsilon epsilon for segment snapping
264-
* @returns squared distance to closest segment
264+
* @returns squared distance to closest segment or negative value on error
265265
*/
266266
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const = 0;
267267

‎src/core/geometry/qgsabstractgeometry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ class CORE_EXPORT QgsAbstractGeometry
246246
* @param leftOf returns whether the point lies on the left side of the nearest segment (true if point is to left of segment,
247247
* false if point is to right of segment)
248248
* @param epsilon epsilon for segment snapping
249-
* @returns squared distance to closest segment
249+
* @returns squared distance to closest segment or negative value on error
250250
*/
251251
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const = 0;
252252

‎src/core/geometry/qgspointv2.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,12 @@ bool QgsPointV2::moveVertex( QgsVertexId position, const QgsPointV2& newPos )
311311

312312
double QgsPointV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
313313
{
314+
Q_UNUSED( pt );
315+
Q_UNUSED( segmentPt );
316+
Q_UNUSED( vertexAfter );
314317
Q_UNUSED( leftOf );
315318
Q_UNUSED( epsilon );
316-
segmentPt = *this;
317-
vertexAfter = QgsVertexId( 0, 0, 0 );
318-
return QgsGeometryUtils::sqrDistance2D( *this, pt );
319+
return -1; // no segments - return error
319320
}
320321

321322
bool QgsPointV2::nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const

‎src/core/qgspointlocator.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,10 @@ QgsPointLocator::Match QgsPointLocator::nearestEdge( const QgsPoint& point, doub
861861
return Match();
862862
}
863863

864+
QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
865+
if ( geomType == QgsWkbTypes::PointGeometry )
866+
return Match();
867+
864868
Match m;
865869
QgsPointLocator_VisitorNearestEdge visitor( this, m, point, filter );
866870
QgsRectangle rect( point.x() - tolerance, point.y() - tolerance, point.x() + tolerance, point.y() + tolerance );
@@ -879,6 +883,10 @@ QgsPointLocator::MatchList QgsPointLocator::edgesInRect( const QgsRectangle& rec
879883
return MatchList();
880884
}
881885

886+
QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
887+
if ( geomType == QgsWkbTypes::PointGeometry )
888+
return MatchList();
889+
882890
MatchList lst;
883891
QgsPointLocator_VisitorEdgesInRect visitor( this, lst, rect, filter );
884892
mRTree->intersectsWithQuery( rect2region( rect ), visitor );
@@ -902,6 +910,10 @@ QgsPointLocator::MatchList QgsPointLocator::pointInPolygon( const QgsPoint& poin
902910
return MatchList();
903911
}
904912

913+
QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
914+
if ( geomType == QgsWkbTypes::PointGeometry || geomType == QgsWkbTypes::LineGeometry )
915+
return MatchList();
916+
905917
MatchList lst;
906918
QgsPointLocator_VisitorArea visitor( this, point, lst );
907919
mRTree->intersectsWithQuery( point2point( point ), visitor );

‎tests/src/core/testqgsgeometry.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -684,12 +684,11 @@ void TestQgsGeometry::point()
684684
p20.deleteVertex( QgsVertexId( 0, 0, 0 ) );
685685
QCOMPARE( p20, QgsPointV2( 2.0, 3.0 ) );
686686

687-
//closestSegment
687+
// closestSegment
688688
QgsPointV2 closest;
689689
QgsVertexId after;
690-
QCOMPARE( p20.closestSegment( QgsPointV2( 4.0, 6.0 ), closest, after, 0, 0 ), 13.0 );
691-
QCOMPARE( closest, p20 );
692-
QCOMPARE( after, QgsVertexId( 0, 0, 0 ) );
690+
// return error - points have no segments
691+
QVERIFY( p20.closestSegment( QgsPointV2( 4.0, 6.0 ), closest, after, 0, 0 ) < 0 );
693692

694693
//nextVertex
695694
QgsPointV2 p21( 3.0, 4.0 );
@@ -3023,6 +3022,12 @@ void TestQgsGeometry::multiPoint()
30233022
boundaryMP.addGeometry( new QgsPointV2( 0, 0 ) );
30243023
boundaryMP.addGeometry( new QgsPointV2( 1, 1 ) );
30253024
QVERIFY( !boundaryMP.boundary() );
3025+
3026+
// closestSegment
3027+
QgsPointV2 closest;
3028+
QgsVertexId after;
3029+
// return error - points have no segments
3030+
QVERIFY( boundaryMP.closestSegment( QgsPointV2( 0.5, 0.5 ), closest, after, 0, 0 ) < 0 );
30263031
}
30273032

30283033
void TestQgsGeometry::multiLineString()

0 commit comments

Comments
 (0)
Please sign in to comment.