Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
add method using iterator
  • Loading branch information
lbartoletti authored and nyalldawson committed Jun 9, 2021
1 parent 1dd6a8f commit b9a6c0c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/core/geometry/qgsgeometryutils.cpp
Expand Up @@ -1813,12 +1813,12 @@ bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsPointSequence &po

for ( const QgsPoint &pt : points )
{
if ( !m_passed && pt.isMeasure() )
if ( !mFound && pt.isMeasure() )
{
point.addMValue( pt.m() );
mFound = true;
}
if ( !z_passed && pt.is3D() )
if ( !zFound && pt.is3D() )
{
point.addZValue( pt.z() );
zFound = true;
Expand All @@ -1830,6 +1830,30 @@ bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsPointSequence &po
return zFound || mFound;
}

bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsAbstractGeometry::vertex_iterator &verticesBegin, const QgsAbstractGeometry::vertex_iterator &verticesEnd, QgsPoint &point )
{
bool zFound = false;
bool mFound = false;

for ( QgsAbstractGeometry::vertex_iterator it = verticesBegin ; it != verticesEnd ; it++ )
{
if ( !mFound && ( *it ).isMeasure() )
{
point.addMValue( ( *it ).m() );
mFound = true;
}
if ( !zFound && ( *it ).is3D() )
{
point.addZValue( ( *it ).z() );
zFound = true;
}
if ( zFound && mFound )
break;
}

return zFound || mFound;
}

bool QgsGeometryUtils::transferFirstMValueToPoint( const QgsPointSequence &points, QgsPoint &point )
{
bool rc = false;
Expand Down
18 changes: 18 additions & 0 deletions src/core/geometry/qgsgeometryutils.h
Expand Up @@ -841,6 +841,24 @@ class CORE_EXPORT QgsGeometryUtils
*/
static bool transferFirstZOrMValueToPoint( const QgsPointSequence &points, QgsPoint &point );

/**
* A Z or M dimension is added to \a point if one of the points in the list
* \a points contains Z or M value.
*
* This method is equivalent to successively calling Z and M but avoiding
* looping twice over the set of points.
*
* \param points List of points in which a Z or M point is searched.
* \param point The point to update with Z or M dimension and value.
* \returns TRUE if the point is updated, FALSE otherwise
*
* \warning This method does not copy the z or m value of the coordinate from the
* points whose z or m value is closest to the original x/y point, but only the first one found.
*
* \since QGIS 3.20
*/
static bool transferFirstZOrMValueToPoint( const QgsAbstractGeometry::vertex_iterator &verticesBegin, const QgsAbstractGeometry::vertex_iterator &verticesEnd, QgsPoint &point );

/**
* Returns the point (\a pointX, \a pointY) forming the bisector from segment (\a aX \a aY) (\a bX \a bY)
* and segment (\a bX, \a bY) (\a dX, \a dY).
Expand Down
58 changes: 58 additions & 0 deletions tests/src/core/testqgsgeometryutils.cpp
Expand Up @@ -17,6 +17,7 @@

#include "qgstest.h"
#include <QObject>
#include "qgsgeometry.h"
#include "qgsgeometryutils.h"
#include "qgslinestring.h"
#include "qgspolygon.h"
Expand Down Expand Up @@ -88,6 +89,7 @@ class TestQgsGeometryUtils: public QObject
void transferFirstZValueToPoint();
void transferFirstMValueToPoint();
void transferFirstZOrMValueToPoint();
void transferFirstZOrMValueToPoint_iterator();
};


Expand Down Expand Up @@ -1714,7 +1716,63 @@ void TestQgsGeometryUtils::transferFirstZOrMValueToPoint()
QCOMPARE( point.wkbType(), QgsWkbTypes::PointZM );
QCOMPARE( point.z(), 9.0 );
QCOMPARE( point.m(), 5.0 );
}

void TestQgsGeometryUtils::transferFirstZOrMValueToPoint_iterator()
{

QgsPoint point( 1, 2 );
QgsGeometry geom;

geom = QgsGeometry::fromWkt( "LineString( 0 2, 2 3)" );
bool ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, false );

// Z
point = QgsPoint( 1, 2 );
geom = QgsGeometry::fromWkt( "LineStringZ( 0 2 3, 2 3 4)" );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );

// M
point = QgsPoint( 1, 2 );
geom = QgsGeometry::fromWkt( "LineStringZ( 0 2 3, 2 3 4)" );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, true );
QCOMPARE( point.m(), 3.0 );

// ZM
point = QgsPoint( 1, 2 );
geom = QgsGeometry::fromWkt( "LineStringZ( 0 2 3 5, 2 3 4 6)" );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );

// point is Z and linestring ZM
point = QgsPoint( 1, 2, 4 );
geom = QgsGeometry::fromWkt( "LineStringZ( 0 2 3 5, 2 3 4 6)" );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );

// point is M and linestring ZM
point = QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 );
geom = QgsGeometry::fromWkt( "LineStringZ( 0 2 3 5, 2 3 4 6)" );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );

// point is ZM and linestring ZM
point = QgsPoint( 1, 2, 5, 4 );
geom = QgsGeometry::fromWkt( "LineStringZ( 0 2 3 5, 2 3 4 6)" );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );
}

QGSTEST_MAIN( TestQgsGeometryUtils )
Expand Down

0 comments on commit b9a6c0c

Please sign in to comment.