Skip to content

Commit

Permalink
Add tests for QgsPointV2, fix some issues:
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
nyalldawson committed Nov 19, 2015
1 parent e1c3b4d commit 8c0fe47
Show file tree
Hide file tree
Showing 6 changed files with 408 additions and 56 deletions.
14 changes: 13 additions & 1 deletion python/core/geometry/qgspointv2.sip
Expand Up @@ -33,7 +33,19 @@ class QgsPointV2: public QgsAbstractGeometryV2
* @param z z-coordinate of point, for PointZ or PointZM types
* @param m m-value of point, for PointM or PointZM types
*/
QgsPointV2( QgsWKBTypes::Type type, double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0 );
QgsPointV2( QgsWKBTypes::Type type, double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0 ) /Factory/;
%MethodCode
if ( QgsWKBTypes::flatType( a0 ) != QgsWKBTypes::Point )
{
PyErr_SetString(PyExc_ValueError,
QString( "%1 is not a valid WKB type for point geometries" ).arg( QgsWKBTypes::displayString( a0 ) ).toUtf8().constData( ) );
sipIsErr = 1;
}
else
{
sipCpp = new sipQgsPointV2( a0, a1, a2, a3, a4 );
}
%End

bool operator==( const QgsPointV2& pt ) const;
bool operator!=( const QgsPointV2& pt ) const;
Expand Down
10 changes: 5 additions & 5 deletions src/core/geometry/qgsabstractgeometryv2.cpp
Expand Up @@ -55,12 +55,12 @@ QgsRectangle QgsAbstractGeometryV2::boundingBox() const

bool QgsAbstractGeometryV2::is3D() const
{
return(( mWkbType >= 1001 && mWkbType <= 1017 ) || ( mWkbType > 3000 || mWkbType & 0x80000000 ) );
return QgsWKBTypes::hasZ( mWkbType );
}

bool QgsAbstractGeometryV2::isMeasure() const
{
return ( mWkbType >= 2001 && mWkbType <= 3017 );
return QgsWKBTypes::hasM( mWkbType );
}

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

if ( hasZ && hasM )
{
mWkbType = ( QgsWKBTypes::Type )( baseGeomType + 3000 );
mWkbType = QgsWKBTypes::addM( QgsWKBTypes::addZ( baseGeomType ) );
}
else if ( hasZ )
{
mWkbType = ( QgsWKBTypes::Type )( baseGeomType + 1000 );
mWkbType = QgsWKBTypes::addZ( baseGeomType );
}
else if ( hasM )
{
mWkbType = ( QgsWKBTypes::Type )( baseGeomType + 2000 );
mWkbType = QgsWKBTypes::addM( baseGeomType );
}
else
{
Expand Down
51 changes: 38 additions & 13 deletions src/core/geometry/qgspointv2.cpp
Expand Up @@ -24,23 +24,44 @@
#include "qgswkbptr.h"
#include <QPainter>

QgsPointV2::QgsPointV2( double x, double y ): QgsAbstractGeometryV2(), mX( x ), mY( y ), mZ( 0.0 ), mM( 0.0 )
QgsPointV2::QgsPointV2( double x, double y )
: QgsAbstractGeometryV2()
, mX( x )
, mY( y )
, mZ( 0.0 )
, mM( 0.0 )
{
mWkbType = QgsWKBTypes::Point;
}

QgsPointV2::QgsPointV2( const QgsPoint& p ): QgsAbstractGeometryV2(), mX( p.x() ), mY( p.y() ), mZ( 0.0 ), mM( 0.0 )
QgsPointV2::QgsPointV2( const QgsPoint& p )
: QgsAbstractGeometryV2()
, mX( p.x() )
, mY( p.y() )
, mZ( 0.0 )
, mM( 0.0 )
{
mWkbType = QgsWKBTypes::Point;
}

QgsPointV2::QgsPointV2( const QPointF& p ): QgsAbstractGeometryV2(), mX( p.x() ), mY( p.y() ), mZ( 0.0 ), mM( 0.0 )
QgsPointV2::QgsPointV2( const QPointF& p )
: QgsAbstractGeometryV2()
, mX( p.x() )
, mY( p.y() )
, mZ( 0.0 )
, mM( 0.0 )
{
mWkbType = QgsWKBTypes::Point;
}

QgsPointV2::QgsPointV2( QgsWKBTypes::Type type, double x, double y, double z, double m ): mX( x ), mY( y ), mZ( z ), mM( m )
QgsPointV2::QgsPointV2( QgsWKBTypes::Type type, double x, double y, double z, double m )
: mX( x )
, mY( y )
, mZ( z )
, mM( m )
{
//protect against non-point WKB types
Q_ASSERT( QgsWKBTypes::flatType( type ) == QgsWKBTypes::Point );
mWkbType = type;
}

Expand Down Expand Up @@ -69,6 +90,7 @@ bool QgsPointV2::fromWkb( const unsigned char* wkb )
QgsWKBTypes::Type type = wkbPtr.readHeader();
if ( QgsWKBTypes::flatType( type ) != QgsWKBTypes::Point )
{
clear();
return false;
}
mWkbType = type;
Expand All @@ -80,7 +102,8 @@ bool QgsPointV2::fromWkb( const unsigned char* wkb )
if ( isMeasure() )
wkbPtr >> mM;

mBoundingBox = QgsRectangle(); //set bounding box invalid
mBoundingBox = QgsRectangle();

return true;
}

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

QStringList coordinates = parts.second.split( ' ', QString::SkipEmptyParts );
if ( coordinates.size() < 2 + is3D() + isMeasure() )
if ( coordinates.size() < 2 )
{
clear();
return false;
Expand All @@ -117,9 +140,9 @@ bool QgsPointV2::fromWkt( const QString& wkt )
int idx = 0;
mX = coordinates[idx++].toDouble();
mY = coordinates[idx++].toDouble();
if ( is3D() )
if ( is3D() && coordinates.length() > 2 )
mZ = coordinates[idx++].toDouble();
if ( isMeasure() )
if ( isMeasure() && coordinates.length() > 2 + is3D() )
mM = coordinates[idx++].toDouble();

return true;
Expand Down Expand Up @@ -203,13 +226,13 @@ void QgsPointV2::clear()
{
mWkbType = QgsWKBTypes::Unknown;
mX = mY = mZ = mM = 0.;
mBoundingBox = QgsRectangle(); //set bounding box invalid
mBoundingBox = QgsRectangle();
}

void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
{
mBoundingBox = QgsRectangle();
ct.transformInPlace( mX, mY, mZ, d );
mBoundingBox = QgsRectangle(); //set bounding box invalid
}

void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const
Expand All @@ -223,6 +246,7 @@ void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coor
bool QgsPointV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newPos )
{
Q_UNUSED( position );
mBoundingBox = QgsRectangle();
mX = newPos.mX;
mY = newPos.mY;
if ( is3D() && newPos.is3D() )
Expand All @@ -233,13 +257,14 @@ bool QgsPointV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newP
{
mM = newPos.mM;
}
mBoundingBox = QgsRectangle(); //set bounding box invalid
return true;
}

double QgsPointV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
Q_UNUSED( segmentPt ); Q_UNUSED( vertexAfter ); Q_UNUSED( leftOf ); Q_UNUSED( leftOf ); Q_UNUSED( epsilon );
Q_UNUSED( leftOf ); Q_UNUSED( epsilon );
segmentPt = *this;
vertexAfter = QgsVertexId( 0, 0, 0 );
return QgsGeometryUtils::sqrDistance2D( *this, pt );
}

Expand Down Expand Up @@ -287,8 +312,8 @@ bool QgsPointV2::addMValue( double mValue )

void QgsPointV2::transform( const QTransform& t )
{
mBoundingBox = QgsRectangle();
qreal x, y;
t.map( mX, mY, &x, &y );
mX = x; mY = y;
mBoundingBox = QgsRectangle(); //set bounding box invalid
}
4 changes: 2 additions & 2 deletions src/core/geometry/qgspointv2.h
Expand Up @@ -85,15 +85,15 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
* @see setX()
* @note not available in Python bindings
*/
double &rx() { return mX; }
double &rx() { mBoundingBox = QgsRectangle(); return mX; }

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

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

0 comments on commit 8c0fe47

Please sign in to comment.