Skip to content

Commit 76a57b8

Browse files
committedFeb 16, 2018
The first point in 3D is used to propagate Z dimension
1 parent ce9e012 commit 76a57b8

File tree

6 files changed

+71
-79
lines changed

6 files changed

+71
-79
lines changed
 

‎python/core/geometry/qgsgeometryutils.sip.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,17 @@ Return the coefficients (a, b, c for equation "ax + by + c = 0") of a line defin
388388
:return: A line (segment) from p to perpendicular point on segment [s1, s2]
389389
%End
390390

391+
static bool setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point );
392+
%Docstring
393+
A Z dimension is added to ``point`` if one of the point in the list
394+
``points`` is in 3D. Moreover, the Z value of ``point`` is updated with.
395+
396+
:param points: List of points in which a 3D point is searched.
397+
:param point: The point to update with Z dimension and value.
398+
399+
:return: true if the point is updated, false otherwise
400+
%End
401+
391402

392403
};
393404

‎src/core/geometry/qgscircle.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ QgsCircle QgsCircle::from2Points( const QgsPoint &pt1, const QgsPoint &pt2 )
4040
double azimuth = QgsGeometryUtils::lineAngle( pt1.x(), pt1.y(), pt2.x(), pt2.y() ) * 180.0 / M_PI;
4141
double radius = pt1.distance( pt2 ) / 2.0;
4242

43+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1 << pt2, center );
44+
4345
return QgsCircle( center, radius, azimuth );
4446
}
4547

@@ -138,26 +140,8 @@ QgsCircle QgsCircle::from3Points( const QgsPoint &pt1, const QgsPoint &pt2, cons
138140
double aSlope = yDelta_a / xDelta_a;
139141
double bSlope = yDelta_b / xDelta_b;
140142

141-
// set z cooridnate for center
142-
double z = std::numeric_limits<double>::quiet_NaN();
143-
if ( p1.is3D() )
144-
{
145-
z = p1.z();
146-
}
147-
else if ( p2.is3D() )
148-
{
149-
z = p2.z();
150-
}
151-
else if ( p3.is3D() )
152-
{
153-
z = p3.z();
154-
}
155-
156-
if ( ! std::isnan( z ) )
157-
{
158-
center.convertTo( QgsWkbTypes::addZ( center.wkbType() ) );
159-
center.setZ( z );
160-
}
143+
// set z coordinate for center
144+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << p1 << p2 << p3, center );
161145

162146
if ( ( std::fabs( xDelta_a ) <= epsilon ) && ( std::fabs( yDelta_b ) <= epsilon ) )
163147
{
@@ -197,7 +181,11 @@ QgsCircle QgsCircle::fromCenterDiameter( const QgsPoint &center, double diameter
197181
QgsCircle QgsCircle::fromCenterPoint( const QgsPoint &center, const QgsPoint &pt1 )
198182
{
199183
double azimuth = QgsGeometryUtils::lineAngle( center.x(), center.y(), pt1.x(), pt1.y() ) * 180.0 / M_PI;
200-
return QgsCircle( center, center.distance( pt1 ), azimuth );
184+
185+
QgsPoint centerPt( center );
186+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1, centerPt );
187+
188+
return QgsCircle( centerPt, centerPt.distance( pt1 ), azimuth );
201189
}
202190

203191
QgsCircle QgsCircle::from3Tangents( const QgsPoint &pt1_tg1, const QgsPoint &pt2_tg1, const QgsPoint &pt1_tg2, const QgsPoint &pt2_tg2, const QgsPoint &pt1_tg3, const QgsPoint &pt2_tg3, double epsilon )
@@ -242,7 +230,10 @@ QgsCircle QgsCircle::fromExtent( const QgsPoint &pt1, const QgsPoint &pt2 )
242230
return QgsCircle();
243231
}
244232

245-
return QgsCircle( QgsGeometryUtils::midpoint( pt1, pt2 ), delta_x / 2.0, 0 );
233+
QgsPoint center = QgsGeometryUtils::midpoint( pt1, pt2 );
234+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1 << pt2, center );
235+
236+
return QgsCircle( center, delta_x / 2.0, 0 );
246237
}
247238

248239
double QgsCircle::area() const

‎src/core/geometry/qgsellipse.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ QgsEllipse QgsEllipse::fromFoci( const QgsPoint &pt1, const QgsPoint &pt2, const
5757
double axis_a = dist / 2.0;
5858
double axis_b = std::sqrt( std::pow( axis_a, 2.0 ) - std::pow( dist_p1p2 / 2.0, 2.0 ) );
5959

60+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1 << pt2 << pt3, center );
61+
6062
return QgsEllipse( center, axis_a, axis_b, azimuth );
6163
}
6264

@@ -67,6 +69,8 @@ QgsEllipse QgsEllipse::fromExtent( const QgsPoint &pt1, const QgsPoint &pt2 )
6769
double axis_b = std::fabs( pt2.y() - pt1.y() ) / 2.0;
6870
double azimuth = 90.0;
6971

72+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1 << pt2, center );
73+
7074
return QgsEllipse( center, axis_a, axis_b, azimuth );
7175
}
7276

@@ -76,7 +80,10 @@ QgsEllipse QgsEllipse::fromCenterPoint( const QgsPoint &center, const QgsPoint &
7680
double axis_b = std::fabs( pt1.y() - center.y() );
7781
double azimuth = 90.0;
7882

79-
return QgsEllipse( center, axis_a, axis_b, azimuth );
83+
QgsPoint centerPt( center );
84+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1, centerPt );
85+
86+
return QgsEllipse( centerPt, axis_a, axis_b, azimuth );
8087
}
8188

8289
QgsEllipse QgsEllipse::fromCenter2Points( const QgsPoint &center, const QgsPoint &pt1, const QgsPoint &pt2 )
@@ -88,7 +95,10 @@ QgsEllipse QgsEllipse::fromCenter2Points( const QgsPoint &center, const QgsPoint
8895
QgsPoint pp = center.project( length, 90 + azimuth );
8996
double axis_b = center.distance( pp );
9097

91-
return QgsEllipse( center, axis_a, axis_b, azimuth );
98+
QgsPoint centerPt( center );
99+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << pt1 << pt2, centerPt );
100+
101+
return QgsEllipse( centerPt, axis_a, axis_b, azimuth );
92102
}
93103

94104
bool QgsEllipse::operator ==( const QgsEllipse &elp ) const

‎src/core/geometry/qgsgeometryutils.cpp

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -248,22 +248,8 @@ bool QgsGeometryUtils::lineIntersection( const QgsPoint &p1, QgsVector v1, const
248248

249249
intersection = QgsPoint( p1.x() + v1.x() * k, p1.y() + v1.y() * k );
250250

251-
// z support for inter point
252-
double z = std::numeric_limits<double>::quiet_NaN();
253-
if ( p1.is3D() )
254-
{
255-
z = p1.z();
256-
}
257-
else if ( p2.is3D() )
258-
{
259-
z = p2.z();
260-
}
261-
262-
if ( ! std::isnan( z ) )
263-
{
264-
intersection.convertTo( QgsWkbTypes::addZ( intersection.wkbType() ) );
265-
intersection.setZ( z );
266-
}
251+
// z support for intersection point
252+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << p1 << p2, intersection );
267253

268254
return true;
269255
}
@@ -623,26 +609,7 @@ bool QgsGeometryUtils::segmentMidPoint( const QgsPoint &p1, const QgsPoint &p2,
623609
result = possibleMidPoints.at( minDistIndex );
624610

625611
// add z support if necessary
626-
double z = std::numeric_limits<double>::quiet_NaN();
627-
628-
if ( p1.is3D() && p2.is3D() )
629-
{
630-
z = ( p1.z() + p2.z() ) / 2.;
631-
}
632-
else if ( p1.is3D() && !p2.is3D() )
633-
{
634-
z = p1.z();
635-
}
636-
else if ( !p1.is3D() && p2.is3D() )
637-
{
638-
z = p2.z();
639-
}
640-
641-
if ( ! std::isnan( z ) )
642-
{
643-
result.convertTo( QgsWkbTypes::addZ( result.wkbType() ) );
644-
result.setZ( z );
645-
}
612+
QgsGeometryUtils::setZValueFromPoints( QgsPointSequence() << p1 << p2, result );
646613

647614
return true;
648615
}
@@ -1205,3 +1172,21 @@ double QgsGeometryUtils::averageAngle( double a1, double a2 )
12051172
}
12061173
return normalizedAngle( resultAngle );
12071174
}
1175+
1176+
bool QgsGeometryUtils::setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point )
1177+
{
1178+
bool rc = false;
1179+
1180+
for ( const QgsPoint &pt : points )
1181+
{
1182+
if ( pt.is3D() )
1183+
{
1184+
point.convertTo( QgsWkbTypes::addZ( point.wkbType() ) );
1185+
point.setZ( pt.z() );
1186+
rc = true;
1187+
break;
1188+
}
1189+
}
1190+
1191+
return rc;
1192+
}

‎src/core/geometry/qgsgeometryutils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,16 @@ class CORE_EXPORT QgsGeometryUtils
410410
*/
411411
static QgsLineString perpendicularSegment( const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2 );
412412

413+
/**
414+
* A Z dimension is added to \a point if one of the point in the list
415+
* \a points is in 3D. Moreover, the Z value of \a point is updated with.
416+
*
417+
* \param points List of points in which a 3D point is searched.
418+
* \param point The point to update with Z dimension and value.
419+
* \returns true if the point is updated, false otherwise
420+
*/
421+
static bool setZValueFromPoints( const QgsPointSequence &points, QgsPoint &point );
422+
413423
//! \note not available in Python bindings
414424
enum ComponentType SIP_SKIP
415425
{

‎src/core/geometry/qgstriangle.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -574,26 +574,11 @@ QgsPoint QgsTriangle::inscribedCenter() const
574574
l.at( 1 ) * vertexAt( 0 ).y() +
575575
l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();
576576

577-
double z = std::numeric_limits<double>::quiet_NaN();
578-
if ( vertexAt( 0 ).is3D() )
579-
{
580-
z = vertexAt( 0 ).z();
581-
}
582-
else if ( vertexAt( 1 ).is3D() )
583-
{
584-
z = vertexAt( 1 ).z();
585-
}
586-
else if ( vertexAt( 2 ).is3D() )
587-
{
588-
z = vertexAt( 2 ).z();
589-
}
590-
591577
QgsPoint center( x, y );
592-
if ( !std::isnan( z ) )
593-
{
594-
center.convertTo( QgsWkbTypes::PointZ );
595-
center.setZ( z );
596-
}
578+
579+
QgsPointSequence points;
580+
points << vertexAt( 0 ) << vertexAt( 1 ) << vertexAt( 2 );
581+
QgsGeometryUtils::setZValueFromPoints( points, center );
597582

598583
return center;
599584
}

0 commit comments

Comments
 (0)