Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix sip; add method using QgsGeometry, add tests, revert missing conv…
…ertTo/add
  • Loading branch information
lbartoletti authored and nyalldawson committed Jun 9, 2021
1 parent 6d5411b commit 65392c2
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 13 deletions.
5 changes: 3 additions & 2 deletions python/core/auto_generated/geometry/qgsgeometryutils.sip.in
Expand Up @@ -834,15 +834,16 @@ looping twice over the set of points.
.. versionadded:: 3.20
%End

static bool transferFirstZOrMValueToPoint( const QgsAbstractGeometry::vertex_iterator &verticesBegin, const QgsAbstractGeometry::vertex_iterator &verticesEnd, QgsPoint &point );

static bool transferFirstZOrMValueToPoint( const QgsGeometry &geom, QgsPoint &point );
%Docstring
A Z or M dimension is added to ``point`` if one of the points in the list
``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 geom: :py:class:`QgsGeometry` in which a Z or M point is searched.
:param point: The point to update with Z or M dimension and value.

:return: ``True`` if the point is updated, ``False`` otherwise
Expand Down
11 changes: 9 additions & 2 deletions src/core/geometry/qgsgeometryutils.cpp
Expand Up @@ -1832,6 +1832,11 @@ bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsPointSequence &po
return zFound || mFound;
}

bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsGeometry &geom, QgsPoint &point )
{
return QgsGeometryUtils::transferFirstZOrMValueToPoint( geom.vertices_begin(), geom.vertices_end(), point );
}

bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsAbstractGeometry::vertex_iterator &verticesBegin, const QgsAbstractGeometry::vertex_iterator &verticesEnd, QgsPoint &point )
{
bool zFound = false;
Expand All @@ -1841,12 +1846,14 @@ bool QgsGeometryUtils::transferFirstZOrMValueToPoint( const QgsAbstractGeometry:
{
if ( !mFound && ( *it ).isMeasure() )
{
point.addMValue( ( *it ).m() );
point.convertTo( QgsWkbTypes::addM( point.wkbType() ) );
point.setM( ( *it ).m() );
mFound = true;
}
if ( !zFound && ( *it ).is3D() )
{
point.addZValue( ( *it ).z() );
point.convertTo( QgsWkbTypes::addZ( point.wkbType() ) );
point.setZ( ( *it ).z() );
zFound = true;
}
if ( zFound && mFound )
Expand Down
25 changes: 23 additions & 2 deletions src/core/geometry/qgsgeometryutils.h
Expand Up @@ -22,6 +22,7 @@ email : marco.hugentobler at sourcepole dot com
#include "qgis_sip.h"
#include "qgspoint.h"
#include "qgsabstractgeometry.h"
#include "qgsgeometry.h"
#include "qgsvector3d.h"

#include <QJsonArray>
Expand Down Expand Up @@ -848,7 +849,27 @@ class CORE_EXPORT QgsGeometryUtils
* 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 verticesBegin begin vertex which a Z or M point is searched.
* \param verticesEnd end vertex 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
* \note Not available in Python bindings
*/
static bool transferFirstZOrMValueToPoint( const QgsAbstractGeometry::vertex_iterator &verticesBegin, const QgsAbstractGeometry::vertex_iterator &verticesEnd, QgsPoint &point ) SIP_SKIP;

/**
* 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 geom QgsGeometry 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
*
Expand All @@ -857,7 +878,7 @@ class CORE_EXPORT QgsGeometryUtils
*
* \since QGIS 3.20
*/
static bool transferFirstZOrMValueToPoint( const QgsAbstractGeometry::vertex_iterator &verticesBegin, const QgsAbstractGeometry::vertex_iterator &verticesEnd, QgsPoint &point );
static bool transferFirstZOrMValueToPoint( const QgsGeometry &geom, QgsPoint &point );

/**
* Returns the point (\a pointX, \a pointY) forming the bisector from segment (\a aX \a aY) (\a bX \a bY)
Expand Down
63 changes: 56 additions & 7 deletions tests/src/core/testqgsgeometryutils.cpp
Expand Up @@ -1720,59 +1720,108 @@ void TestQgsGeometryUtils::transferFirstZOrMValueToPoint()

void TestQgsGeometryUtils::transferFirstZOrMValueToPoint_iterator()
{

QgsPoint point( 1, 2 );
QgsGeometry geom;

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

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

// QgsGeometry
point = QgsPoint( 1, 2 );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom, point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );

// M
geom = QgsGeometry::fromWkt( "LineStringM( 0 2 3, 2 3 4)" );
// iterator
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 );

// QgsGeometry
point = QgsPoint( 1, 2 );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom, point );
QCOMPARE( ret, true );
QCOMPARE( point.m(), 3.0 );

// ZM
geom = QgsGeometry::fromWkt( "LineStringZM( 0 2 3 5, 2 3 4 6)" );
// iterator
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 );

// QgsGeometry
point = QgsPoint( 1, 2 );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom, point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );

// point is Z and linestring ZM
geom = QgsGeometry::fromWkt( "LineStringZM( 0 2 3 5, 2 3 4 6)" );
// iterator
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 );

// QgsGeometry
point = QgsPoint( 1, 2, 4 );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom, point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );

// point is M and linestring ZM
geom = QgsGeometry::fromWkt( "LineStringZM( 0 2 3 5, 2 3 4 6)" );
// iterator
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 );

// QgsGeometry
point = QgsPoint( QgsWkbTypes::PointM, 1, 2, 0, 4 );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom, point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );

// point is ZM and linestring ZM
geom = QgsGeometry::fromWkt( "LineStringZM( 0 2 3 5, 2 3 4 6)" );
// iterator
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 );

// QgsGeometry
point = QgsPoint( 1, 2, 5, 4 );
ret = QgsGeometryUtils::transferFirstZOrMValueToPoint( geom, point );
QCOMPARE( ret, true );
QCOMPARE( point.z(), 3.0 );
QCOMPARE( point.m(), 5.0 );
}

QGSTEST_MAIN( TestQgsGeometryUtils )
Expand Down

0 comments on commit 65392c2

Please sign in to comment.