Skip to content

Commit c4dcfbf

Browse files
wonder-sk3nids
authored andcommittedAug 12, 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 786a59c commit c4dcfbf

File tree

5 files changed

+27
-9
lines changed

5 files changed

+27
-9
lines changed
 

‎python/core/geometry/qgsabstractgeometryv2.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ class QgsAbstractGeometryV2
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/qgsabstractgeometryv2.h

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

‎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
@@ -858,6 +858,10 @@ QgsPointLocator::Match QgsPointLocator::nearestEdge( const QgsPoint& point, doub
858858
return Match();
859859
}
860860

861+
QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
862+
if ( geomType == QgsWkbTypes::PointGeometry )
863+
return Match();
864+
861865
Match m;
862866
QgsPointLocator_VisitorNearestEdge visitor( this, m, point, filter );
863867
QgsRectangle rect( point.x() - tolerance, point.y() - tolerance, point.x() + tolerance, point.y() + tolerance );
@@ -876,6 +880,10 @@ QgsPointLocator::MatchList QgsPointLocator::edgesInRect( const QgsRectangle& rec
876880
return MatchList();
877881
}
878882

883+
QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
884+
if ( geomType == QgsWkbTypes::PointGeometry )
885+
return MatchList();
886+
879887
MatchList lst;
880888
QgsPointLocator_VisitorEdgesInRect visitor( this, lst, rect, filter );
881889
mRTree->intersectsWithQuery( rect2region( rect ), visitor );
@@ -899,6 +907,10 @@ QgsPointLocator::MatchList QgsPointLocator::pointInPolygon( const QgsPoint& poin
899907
return MatchList();
900908
}
901909

910+
QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
911+
if ( geomType == QgsWkbTypes::PointGeometry || geomType == QgsWkbTypes::LineGeometry )
912+
return MatchList();
913+
902914
MatchList lst;
903915
QgsPointLocator_VisitorArea visitor( this, point, lst );
904916
mRTree->intersectsWithQuery( point2point( point ), visitor );

‎tests/src/core/testqgsgeometry.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -675,12 +675,11 @@ void TestQgsGeometry::pointV2()
675675
p20.deleteVertex( QgsVertexId( 0, 0, 0 ) );
676676
QCOMPARE( p20, QgsPointV2( 2.0, 3.0 ) );
677677

678-
//closestSegment
678+
// closestSegment
679679
QgsPointV2 closest;
680680
QgsVertexId after;
681-
QCOMPARE( p20.closestSegment( QgsPointV2( 4.0, 6.0 ), closest, after, 0, 0 ), 13.0 );
682-
QCOMPARE( closest, p20 );
683-
QCOMPARE( after, QgsVertexId( 0, 0, 0 ) );
681+
// return error - points have no segments
682+
QVERIFY( p20.closestSegment( QgsPointV2( 4.0, 6.0 ), closest, after, 0, 0 ) < 0 );
684683

685684
//nextVertex
686685
QgsPointV2 p21( 3.0, 4.0 );
@@ -3014,6 +3013,12 @@ void TestQgsGeometry::multiPoint()
30143013
boundaryMP.addGeometry( new QgsPointV2( 0, 0 ) );
30153014
boundaryMP.addGeometry( new QgsPointV2( 1, 1 ) );
30163015
QVERIFY( !boundaryMP.boundary() );
3016+
3017+
// closestSegment
3018+
QgsPointV2 closest;
3019+
QgsVertexId after;
3020+
// return error - points have no segments
3021+
QVERIFY( boundaryMP.closestSegment( QgsPointV2( 0.5, 0.5 ), closest, after, 0, 0 ) < 0 );
30173022
}
30183023

30193024
void TestQgsGeometry::multiLineString()

0 commit comments

Comments
 (0)
Please sign in to comment.