Skip to content
Permalink
Browse files

Fix calculation of distance to vertex for multi part, multi ring

and curved geometries
  • Loading branch information
nyalldawson committed Nov 14, 2017
1 parent 5d476e5 commit fc6c69bedf72a79380fc3e6acf9d6035f913d1f6
Showing with 461 additions and 249 deletions.
  1. +7 −0 python/core/geometry/qgsabstractgeometry.sip
  2. +1 −23 python/core/geometry/qgscircularstring.sip
  3. +1 −7 python/core/geometry/qgscompoundcurve.sip
  4. +4 −1 python/core/geometry/qgscurve.sip
  5. +2 −0 python/core/geometry/qgscurvepolygon.sip
  6. +1 −6 python/core/geometry/qgsgeometrycollection.sip
  7. +1 −0 python/core/geometry/qgslinestring.sip
  8. +1 −0 python/core/geometry/qgsmultipoint.sip
  9. +2 −0 python/core/geometry/qgspoint.sip
  10. +33 −33 python/plugins/processing/tests/testdata/expected/extract_nodes_multilines.gml
  11. +49 −49 python/plugins/processing/tests/testdata/expected/extract_nodes_multipolys.gml
  12. +61 −61 python/plugins/processing/tests/testdata/expected/extract_nodes_polys.gml
  13. +22 −22 python/plugins/processing/tests/testdata/expected/extract_specific_nodes_polys.gml
  14. +6 −0 src/core/geometry/qgsabstractgeometry.h
  15. +17 −0 src/core/geometry/qgscircularstring.cpp
  16. +1 −21 src/core/geometry/qgscircularstring.h
  17. +11 −0 src/core/geometry/qgscompoundcurve.cpp
  18. +1 −6 src/core/geometry/qgscompoundcurve.h
  19. +5 −1 src/core/geometry/qgscurve.h
  20. +11 −0 src/core/geometry/qgscurvepolygon.cpp
  21. +1 −0 src/core/geometry/qgscurvepolygon.h
  22. +16 −0 src/core/geometry/qgsgeometrycollection.cpp
  23. +1 −6 src/core/geometry/qgsgeometrycollection.h
  24. +1 −11 src/core/geometry/qgsgeometryutils.cpp
  25. +10 −0 src/core/geometry/qgslinestring.cpp
  26. +1 −1 src/core/geometry/qgslinestring.h
  27. +5 −0 src/core/geometry/qgsmultipoint.cpp
  28. +1 −1 src/core/geometry/qgsmultipoint.h
  29. +5 −0 src/core/geometry/qgspoint.cpp
  30. +1 −0 src/core/geometry/qgspoint.h
  31. +182 −0 tests/src/core/testqgsgeometry.cpp
@@ -366,6 +366,13 @@ class QgsAbstractGeometry
:rtype: float
%End

virtual double segmentLength( QgsVertexId startVertex ) const = 0;
%Docstring
Returns the length of the segment of the geometry which begins at ``startVertex``.
.. versionadded:: 3.0
:rtype: float
%End

virtual QgsPoint centroid() const;
%Docstring
Returns the centroid of the geometry
@@ -79,23 +79,10 @@ class QgsCircularString: QgsCurve

virtual QgsPoint endPoint() const;


virtual QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;

%Docstring
Returns a new line string geometry corresponding to a segmentized approximation
of the curve.
\param tolerance segmentation tolerance
\param toleranceType maximum segmentation angle or maximum difference between approximation and curve

Uses a MaximumAngle tolerance of 1 degrees by default (360
segments in a full circle)
:rtype: QgsLineString
%End

virtual QgsCircularString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const /Factory/;


virtual void draw( QPainter &p ) const;

virtual void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform,
@@ -120,29 +107,20 @@ class QgsCircularString: QgsCurve

virtual bool hasCurvedSegments() const;


virtual double vertexAngle( QgsVertexId vertex ) const;

%Docstring
Returns approximate rotation angle for a vertex. Usually average angle between adjacent segments.
\param vertex the vertex id
:return: rotation in radians, clockwise from north*
:rtype: float
%End
virtual double segmentLength( QgsVertexId startVertex ) const;

virtual QgsCircularString *reversed() const /Factory/;


virtual bool addZValue( double zValue = 0 );

virtual bool addMValue( double mValue = 0 );


virtual bool dropZValue();

virtual bool dropMValue();


virtual double xAt( int index ) const;

virtual double yAt( int index ) const;
@@ -138,15 +138,9 @@ Appends first point if not already closed.

virtual bool hasCurvedSegments() const;


virtual double vertexAngle( QgsVertexId vertex ) const;

%Docstring
Returns approximate rotation angle for a vertex. Usually average angle between adjacent segments.
\param vertex the vertex id
:return: rotation in radians, clockwise from north*
:rtype: float
%End
virtual double segmentLength( QgsVertexId startVertex ) const;

virtual QgsCompoundCurve *reversed() const /Factory/;

@@ -67,7 +67,10 @@ class QgsCurve: QgsAbstractGeometry
Returns a new line string geometry corresponding to a segmentized approximation
of the curve.
\param tolerance segmentation tolerance
\param toleranceType maximum segmentation angle or maximum difference between approximation and curve*
\param toleranceType maximum segmentation angle or maximum difference between approximation and curve

Uses a MaximumAngle tolerance of 1 degrees by default (360
segments in a full circle)
:rtype: QgsLineString
%End

@@ -185,6 +185,8 @@ Adds an interior ring to the geometry (takes ownership)

virtual QgsPoint vertexAt( QgsVertexId id ) const;

virtual double segmentLength( QgsVertexId startVertex ) const;


virtual bool addZValue( double zValue = 0 );

@@ -145,12 +145,7 @@ Adds a geometry and takes ownership. Returns true in case of success.

virtual double vertexAngle( QgsVertexId vertex ) const;

%Docstring
Returns approximate rotation angle for a vertex. Usually average angle between adjacent segments.
\param vertex the vertex id
:return: rotation in radians, clockwise from north
:rtype: float
%End
virtual double segmentLength( QgsVertexId startVertex ) const;

virtual int vertexCount( int part = 0, int ring = 0 ) const;

@@ -255,6 +255,7 @@ Closes the line string by appending the first point to the end of the line, if i

virtual double vertexAngle( QgsVertexId vertex ) const;

virtual double segmentLength( QgsVertexId startVertex ) const;

virtual bool addZValue( double zValue = 0 );

@@ -47,6 +47,7 @@ class QgsMultiPoint: QgsGeometryCollection

virtual int vertexNumberFromVertexId( QgsVertexId id ) const;

virtual double segmentLength( QgsVertexId startVertex ) const;


protected:
@@ -403,6 +403,8 @@ class QgsPoint: QgsAbstractGeometry

virtual QgsPoint *toCurveType() const /Factory/;

virtual double segmentLength( QgsVertexId startVertex ) const;


virtual bool addZValue( double zValue = 0 );

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xsi:schemaLocation="http://ogr.maptools.org/ extract_nodes_multilines.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
@@ -15,48 +15,48 @@
<ogr:extract_nodes_multilines fid="lines.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>-1,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>0</ogr:node_index>
<ogr:distance>0</ogr:distance>
<ogr:angle>90</ogr:angle>
<ogr:distance>0.00000000000000</ogr:distance>
<ogr:angle>90.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>1</ogr:node_index>
<ogr:distance>2</ogr:distance>
<ogr:angle>90</ogr:angle>
<ogr:distance>2.00000000000000</ogr:distance>
<ogr:angle>90.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>0</ogr:node_index>
<ogr:distance>0</ogr:distance>
<ogr:angle>90</ogr:angle>
<ogr:distance>0.00000000000000</ogr:distance>
<ogr:angle>90.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>1</ogr:node_index>
<ogr:distance>2</ogr:distance>
<ogr:angle>90</ogr:angle>
<ogr:distance>2.00000000000000</ogr:distance>
<ogr:angle>90.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.024184261036468,2.414779270633399</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.02418426103647,2.4147792706334</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>2</ogr:node_index>
<ogr:distance>3.41498595862145</ogr:distance>
<ogr:angle>180.979319654339</ogr:angle>
<ogr:distance>2.00000000000000</ogr:distance>
<ogr:angle>180.97931965433949</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>3</ogr:node_index>
<ogr:distance>4.82997191724289</ogr:distance>
<ogr:angle>180.979319654339</ogr:angle>
<ogr:distance>3.41498595862145</ogr:distance>
<ogr:angle>180.97931965433949</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
@@ -67,64 +67,64 @@
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,0</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>0</ogr:node_index>
<ogr:distance>0</ogr:distance>
<ogr:angle>0</ogr:angle>
<ogr:distance>0.00000000000000</ogr:distance>
<ogr:angle>0.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>1</ogr:node_index>
<ogr:distance>2</ogr:distance>
<ogr:angle>45</ogr:angle>
<ogr:distance>2.00000000000000</ogr:distance>
<ogr:angle>45.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>2</ogr:node_index>
<ogr:distance>3</ogr:distance>
<ogr:angle>45</ogr:angle>
<ogr:distance>3.00000000000000</ogr:distance>
<ogr:angle>45.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>3</ogr:node_index>
<ogr:distance>4</ogr:distance>
<ogr:angle>0</ogr:angle>
<ogr:distance>4.00000000000000</ogr:distance>
<ogr:angle>0.00000000000000</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2.944337811900192,4.04721689059501</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2.94433781190019,4.04721689059501</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>4</ogr:node_index>
<ogr:distance>5.04869513927144</ogr:distance>
<ogr:angle>88.3476953223487</ogr:angle>
<ogr:distance>4.00000000000000</ogr:distance>
<ogr:angle>88.34769532234870</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.459500959692898,4.119769673704415</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.4595009596929,4.11976967370441</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>5</ogr:node_index>
<ogr:distance>7.56490450384177</ogr:distance>
<ogr:angle>88.3476953223487</ogr:angle>
<ogr:distance>6.51620936457033</ogr:distance>
<ogr:angle>88.34769532234870</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>6</ogr:node_index>
<ogr:distance>10.2673162217113</ogr:distance>
<ogr:angle>91.1803544802029</ogr:angle>
<ogr:distance>6.51620936457033</ogr:distance>
<ogr:angle>91.18035448020294</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_nodes_multilines fid="lines.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.58042226487524,2.946833013435702</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.58042226487524,2.9468330134357</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:node_index>7</ogr:node_index>
<ogr:distance>12.8482861544157</ogr:distance>
<ogr:angle>91.1803544802029</ogr:angle>
<ogr:distance>9.09717929727474</ogr:distance>
<ogr:angle>91.18035448020294</ogr:angle>
</ogr:extract_nodes_multilines>
</gml:featureMember>
</ogr:FeatureCollection>

0 comments on commit fc6c69b

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