Skip to content

Commit 8c0fe47

Browse files
committed
Add tests for QgsPointV2, fix some issues:
- prevent creation of a QgsPointV2 with a non-point WKB type - fix bounding box was not invalidated for some modification routines - if WKT type is PointZ/M/ZM and not enough coordinates specified, initialise extra coordinates to 0
1 parent e1c3b4d commit 8c0fe47

File tree

6 files changed

+408
-56
lines changed

6 files changed

+408
-56
lines changed

python/core/geometry/qgspointv2.sip

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,19 @@ class QgsPointV2: public QgsAbstractGeometryV2
3333
* @param z z-coordinate of point, for PointZ or PointZM types
3434
* @param m m-value of point, for PointM or PointZM types
3535
*/
36-
QgsPointV2( QgsWKBTypes::Type type, double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0 );
36+
QgsPointV2( QgsWKBTypes::Type type, double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0 ) /Factory/;
37+
%MethodCode
38+
if ( QgsWKBTypes::flatType( a0 ) != QgsWKBTypes::Point )
39+
{
40+
PyErr_SetString(PyExc_ValueError,
41+
QString( "%1 is not a valid WKB type for point geometries" ).arg( QgsWKBTypes::displayString( a0 ) ).toUtf8().constData( ) );
42+
sipIsErr = 1;
43+
}
44+
else
45+
{
46+
sipCpp = new sipQgsPointV2( a0, a1, a2, a3, a4 );
47+
}
48+
%End
3749

3850
bool operator==( const QgsPointV2& pt ) const;
3951
bool operator!=( const QgsPointV2& pt ) const;

src/core/geometry/qgsabstractgeometryv2.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ QgsRectangle QgsAbstractGeometryV2::boundingBox() const
5555

5656
bool QgsAbstractGeometryV2::is3D() const
5757
{
58-
return(( mWkbType >= 1001 && mWkbType <= 1017 ) || ( mWkbType > 3000 || mWkbType & 0x80000000 ) );
58+
return QgsWKBTypes::hasZ( mWkbType );
5959
}
6060

6161
bool QgsAbstractGeometryV2::isMeasure() const
6262
{
63-
return ( mWkbType >= 2001 && mWkbType <= 3017 );
63+
return QgsWKBTypes::hasM( mWkbType );
6464
}
6565

6666
#if 0
@@ -86,15 +86,15 @@ void QgsAbstractGeometryV2::setZMTypeFromSubGeometry( const QgsAbstractGeometryV
8686

8787
if ( hasZ && hasM )
8888
{
89-
mWkbType = ( QgsWKBTypes::Type )( baseGeomType + 3000 );
89+
mWkbType = QgsWKBTypes::addM( QgsWKBTypes::addZ( baseGeomType ) );
9090
}
9191
else if ( hasZ )
9292
{
93-
mWkbType = ( QgsWKBTypes::Type )( baseGeomType + 1000 );
93+
mWkbType = QgsWKBTypes::addZ( baseGeomType );
9494
}
9595
else if ( hasM )
9696
{
97-
mWkbType = ( QgsWKBTypes::Type )( baseGeomType + 2000 );
97+
mWkbType = QgsWKBTypes::addM( baseGeomType );
9898
}
9999
else
100100
{

src/core/geometry/qgspointv2.cpp

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,44 @@
2424
#include "qgswkbptr.h"
2525
#include <QPainter>
2626

27-
QgsPointV2::QgsPointV2( double x, double y ): QgsAbstractGeometryV2(), mX( x ), mY( y ), mZ( 0.0 ), mM( 0.0 )
27+
QgsPointV2::QgsPointV2( double x, double y )
28+
: QgsAbstractGeometryV2()
29+
, mX( x )
30+
, mY( y )
31+
, mZ( 0.0 )
32+
, mM( 0.0 )
2833
{
2934
mWkbType = QgsWKBTypes::Point;
3035
}
3136

32-
QgsPointV2::QgsPointV2( const QgsPoint& p ): QgsAbstractGeometryV2(), mX( p.x() ), mY( p.y() ), mZ( 0.0 ), mM( 0.0 )
37+
QgsPointV2::QgsPointV2( const QgsPoint& p )
38+
: QgsAbstractGeometryV2()
39+
, mX( p.x() )
40+
, mY( p.y() )
41+
, mZ( 0.0 )
42+
, mM( 0.0 )
3343
{
3444
mWkbType = QgsWKBTypes::Point;
3545
}
3646

37-
QgsPointV2::QgsPointV2( const QPointF& p ): QgsAbstractGeometryV2(), mX( p.x() ), mY( p.y() ), mZ( 0.0 ), mM( 0.0 )
47+
QgsPointV2::QgsPointV2( const QPointF& p )
48+
: QgsAbstractGeometryV2()
49+
, mX( p.x() )
50+
, mY( p.y() )
51+
, mZ( 0.0 )
52+
, mM( 0.0 )
3853
{
3954
mWkbType = QgsWKBTypes::Point;
4055
}
4156

42-
QgsPointV2::QgsPointV2( QgsWKBTypes::Type type, double x, double y, double z, double m ): mX( x ), mY( y ), mZ( z ), mM( m )
57+
QgsPointV2::QgsPointV2( QgsWKBTypes::Type type, double x, double y, double z, double m )
58+
: mX( x )
59+
, mY( y )
60+
, mZ( z )
61+
, mM( m )
4362
{
63+
//protect against non-point WKB types
64+
Q_ASSERT( QgsWKBTypes::flatType( type ) == QgsWKBTypes::Point );
4465
mWkbType = type;
4566
}
4667

@@ -69,6 +90,7 @@ bool QgsPointV2::fromWkb( const unsigned char* wkb )
6990
QgsWKBTypes::Type type = wkbPtr.readHeader();
7091
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::Point )
7192
{
93+
clear();
7294
return false;
7395
}
7496
mWkbType = type;
@@ -80,7 +102,8 @@ bool QgsPointV2::fromWkb( const unsigned char* wkb )
80102
if ( isMeasure() )
81103
wkbPtr >> mM;
82104

83-
mBoundingBox = QgsRectangle(); //set bounding box invalid
105+
mBoundingBox = QgsRectangle();
106+
84107
return true;
85108
}
86109

@@ -95,7 +118,7 @@ bool QgsPointV2::fromWkt( const QString& wkt )
95118
mWkbType = parts.first;
96119

97120
QStringList coordinates = parts.second.split( ' ', QString::SkipEmptyParts );
98-
if ( coordinates.size() < 2 + is3D() + isMeasure() )
121+
if ( coordinates.size() < 2 )
99122
{
100123
clear();
101124
return false;
@@ -117,9 +140,9 @@ bool QgsPointV2::fromWkt( const QString& wkt )
117140
int idx = 0;
118141
mX = coordinates[idx++].toDouble();
119142
mY = coordinates[idx++].toDouble();
120-
if ( is3D() )
143+
if ( is3D() && coordinates.length() > 2 )
121144
mZ = coordinates[idx++].toDouble();
122-
if ( isMeasure() )
145+
if ( isMeasure() && coordinates.length() > 2 + is3D() )
123146
mM = coordinates[idx++].toDouble();
124147

125148
return true;
@@ -203,13 +226,13 @@ void QgsPointV2::clear()
203226
{
204227
mWkbType = QgsWKBTypes::Unknown;
205228
mX = mY = mZ = mM = 0.;
206-
mBoundingBox = QgsRectangle(); //set bounding box invalid
229+
mBoundingBox = QgsRectangle();
207230
}
208231

209232
void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
210233
{
234+
mBoundingBox = QgsRectangle();
211235
ct.transformInPlace( mX, mY, mZ, d );
212-
mBoundingBox = QgsRectangle(); //set bounding box invalid
213236
}
214237

215238
void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const
@@ -223,6 +246,7 @@ void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coor
223246
bool QgsPointV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newPos )
224247
{
225248
Q_UNUSED( position );
249+
mBoundingBox = QgsRectangle();
226250
mX = newPos.mX;
227251
mY = newPos.mY;
228252
if ( is3D() && newPos.is3D() )
@@ -233,13 +257,14 @@ bool QgsPointV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newP
233257
{
234258
mM = newPos.mM;
235259
}
236-
mBoundingBox = QgsRectangle(); //set bounding box invalid
237260
return true;
238261
}
239262

240263
double QgsPointV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
241264
{
242-
Q_UNUSED( segmentPt ); Q_UNUSED( vertexAfter ); Q_UNUSED( leftOf ); Q_UNUSED( leftOf ); Q_UNUSED( epsilon );
265+
Q_UNUSED( leftOf ); Q_UNUSED( epsilon );
266+
segmentPt = *this;
267+
vertexAfter = QgsVertexId( 0, 0, 0 );
243268
return QgsGeometryUtils::sqrDistance2D( *this, pt );
244269
}
245270

@@ -287,8 +312,8 @@ bool QgsPointV2::addMValue( double mValue )
287312

288313
void QgsPointV2::transform( const QTransform& t )
289314
{
315+
mBoundingBox = QgsRectangle();
290316
qreal x, y;
291317
t.map( mX, mY, &x, &y );
292318
mX = x; mY = y;
293-
mBoundingBox = QgsRectangle(); //set bounding box invalid
294319
}

src/core/geometry/qgspointv2.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
8585
* @see setX()
8686
* @note not available in Python bindings
8787
*/
88-
double &rx() { return mX; }
88+
double &rx() { mBoundingBox = QgsRectangle(); return mX; }
8989

9090
/** Returns a reference to the y-coordinate of this point.
9191
* Using a reference makes it possible to directly manipulate y in place.
9292
* @see y()
9393
* @see setY()
9494
* @note not available in Python bindings
9595
*/
96-
double &ry() { return mY; }
96+
double &ry() { mBoundingBox = QgsRectangle(); return mY; }
9797

9898
/** Returns a reference to the z-coordinate of this point.
9999
* Using a reference makes it possible to directly manipulate z in place.

0 commit comments

Comments
 (0)