122 changes: 42 additions & 80 deletions src/analysis/interpolation/qgstininterpolator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
//parse WKB. It is ugly, but we cannot use the methods with QgsPoint because they don't contain z-values for 25D types
bool hasZValue = false;
double x, y, z;
const unsigned char* currentWkbPtr = g->asWkb();
QgsConstWkbPtr currentWkbPtr( g->asWkb() + 1 + sizeof( int ) );
//maybe a structure or break line
Line3D* line = 0;

Expand All @@ -211,14 +211,10 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
hasZValue = true;
case QGis::WKBPoint:
{
currentWkbPtr += ( 1 + sizeof( int ) );
x = *(( double * )( currentWkbPtr ) );
currentWkbPtr += sizeof( double );
y = *(( double * )( currentWkbPtr ) );
currentWkbPtr >> x >> y;
if ( zCoord && hasZValue )
{
currentWkbPtr += sizeof( double );
z = *(( double * )( currentWkbPtr ) );
currentWkbPtr >> z;
}
else
{
Expand All @@ -235,20 +231,15 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
hasZValue = true;
case QGis::WKBMultiPoint:
{
currentWkbPtr += ( 1 + sizeof( int ) );
int* npoints = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
for ( int index = 0; index < *npoints; ++index )
int nPoints;
currentWkbPtr >> nPoints;
for ( int index = 0; index < nPoints; ++index )
{
currentWkbPtr += ( 1 + sizeof( int ) ); //skip endian and point type
x = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
y = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
currentWkbPtr += 1 + sizeof( int );
currentWkbPtr >> x >> y;
if ( hasZValue ) //skip z-coordinate for 25D geometries
{
z = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
currentWkbPtr >> z;
}
else
{
Expand All @@ -265,27 +256,19 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
{
line = new Line3D();
}
currentWkbPtr += ( 1 + sizeof( int ) );
int* npoints = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
for ( int index = 0; index < *npoints; ++index )
int nPoints;
currentWkbPtr >> nPoints;
for ( int index = 0; index < nPoints; ++index )
{
x = *(( double * )( currentWkbPtr ) );
currentWkbPtr += sizeof( double );
y = *(( double * )( currentWkbPtr ) );
currentWkbPtr += sizeof( double );
currentWkbPtr >> x >> y;
if ( zCoord && hasZValue ) //skip z-coordinate for 25D geometries
{
z = *(( double * )( currentWkbPtr ) );
currentWkbPtr >> z;
}
else
{
z = attributeValue;
}
if ( hasZValue )
{
currentWkbPtr += sizeof( double );
}

if ( type == POINTS )
{
Expand All @@ -308,30 +291,22 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
hasZValue = true;
case QGis::WKBMultiLineString:
{
currentWkbPtr += ( 1 + sizeof( int ) );
int* nlines = ( int* )currentWkbPtr;
int* npoints = 0;
currentWkbPtr += sizeof( int );
for ( int index = 0; index < *nlines; ++index )
int nLines;
currentWkbPtr >> nLines;
for ( int index = 0; index < nLines; ++index )
{
if ( type != POINTS )
{
line = new Line3D();
}
currentWkbPtr += ( sizeof( int ) + 1 );
npoints = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
for ( int index2 = 0; index2 < *npoints; ++index2 )
int nPoints;
currentWkbPtr >> nPoints;
for ( int index2 = 0; index2 < nPoints; ++index2 )
{
x = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
y = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );

currentWkbPtr >> x >> y;
if ( hasZValue ) //skip z-coordinate for 25D geometries
{
z = *(( double* ) currentWkbPtr );
currentWkbPtr += sizeof( double );
currentWkbPtr >> z;
}
else
{
Expand Down Expand Up @@ -359,29 +334,23 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
hasZValue = true;
case QGis::WKBPolygon:
{
currentWkbPtr += ( 1 + sizeof( int ) );
int* nrings = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
int* npoints;
for ( int index = 0; index < *nrings; ++index )
int nRings;
currentWkbPtr >> nRings;
for ( int index = 0; index < nRings; ++index )
{
if ( type != POINTS )
{
line = new Line3D();
}

npoints = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
for ( int index2 = 0; index2 < *npoints; ++index2 )
int nPoints;
currentWkbPtr >> nPoints;
for ( int index2 = 0; index2 < nPoints; ++index2 )
{
x = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
y = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
currentWkbPtr >> x >> y;
if ( hasZValue ) //skip z-coordinate for 25D geometries
{
z = *(( double* )currentWkbPtr );;
currentWkbPtr += sizeof( double );
currentWkbPtr >> z;
}
else
{
Expand Down Expand Up @@ -410,34 +379,27 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
hasZValue = true;
case QGis::WKBMultiPolygon:
{
currentWkbPtr += ( 1 + sizeof( int ) );
int* npolys = ( int* )currentWkbPtr;
int* nrings;
int* npoints;
currentWkbPtr += sizeof( int );
for ( int index = 0; index < *npolys; ++index )
int nPolys;
currentWkbPtr >> nPolys;
for ( int index = 0; index < nPolys; ++index )
{
currentWkbPtr += ( 1 + sizeof( int ) ); //skip endian and polygon type
nrings = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
for ( int index2 = 0; index2 < *nrings; ++index2 )
currentWkbPtr += 1 + sizeof( int );
int nRings;
currentWkbPtr >> nRings;
for ( int index2 = 0; index2 < nRings; ++index2 )
{
if ( type != POINTS )
{
line = new Line3D();
}
npoints = ( int* )currentWkbPtr;
currentWkbPtr += sizeof( int );
for ( int index3 = 0; index3 < *npoints; ++index3 )
int nPoints;
currentWkbPtr >> nPoints;
for ( int index3 = 0; index3 < nPoints; ++index3 )
{
x = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
y = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
currentWkbPtr >> x >> y;
if ( hasZValue ) //skip z-coordinate for 25D geometries
{
z = *(( double* )currentWkbPtr );
currentWkbPtr += sizeof( double );
currentWkbPtr >> z;
}
else
{
Expand Down
86 changes: 39 additions & 47 deletions src/core/qgsdistancearea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,6 @@ bool QgsDistanceArea::setEllipsoid( double semiMajor, double semiMinor )
return true;
}



double QgsDistanceArea::measure( QgsGeometry* geometry )
{
if ( !geometry )
Expand All @@ -266,13 +264,14 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
if ( !wkb )
return 0.0;

const unsigned char* ptr;
unsigned int wkbType;
QgsConstWkbPtr wkbPtr( wkb + 1 );

QGis::WkbType wkbType;
wkbPtr >> wkbType;

double res, resTotal = 0;
int count, i;

memcpy( &wkbType, ( wkb + 1 ), sizeof( wkbType ) );

// measure distance or area based on what is the type of geometry
bool hasZptr = false;

Expand All @@ -288,11 +287,10 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
case QGis::WKBMultiLineString25D:
hasZptr = true;
case QGis::WKBMultiLineString:
count = *(( int* )( wkb + 5 ) );
ptr = wkb + 9;
wkbPtr >> count;
for ( i = 0; i < count; i++ )
{
ptr = measureLine( ptr, &res, hasZptr );
wkbPtr = measureLine( wkbPtr, &res, hasZptr );
resTotal += res;
}
QgsDebugMsg( "returning " + QString::number( resTotal ) );
Expand All @@ -308,12 +306,11 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
case QGis::WKBMultiPolygon25D:
hasZptr = true;
case QGis::WKBMultiPolygon:
count = *(( int* )( wkb + 5 ) );
ptr = wkb + 9;
wkbPtr >> count;
for ( i = 0; i < count; i++ )
{
ptr = measurePolygon( ptr, &res, 0, hasZptr );
if ( !ptr )
wkbPtr = measurePolygon( wkbPtr, &res, 0, hasZptr );
if ( !wkbPtr )
{
QgsDebugMsg( "measurePolygon returned 0" );
break;
Expand All @@ -338,13 +335,13 @@ double QgsDistanceArea::measurePerimeter( QgsGeometry* geometry )
if ( !wkb )
return 0.0;

const unsigned char* ptr;
unsigned int wkbType;
QgsConstWkbPtr wkbPtr( wkb + 1 );
QGis::WkbType wkbType;
wkbPtr >> wkbType;

double res = 0.0, resTotal = 0.0;
int count, i;

memcpy( &wkbType, ( wkb + 1 ), sizeof( wkbType ) );

// measure distance or area based on what is the type of geometry
bool hasZptr = false;

Expand All @@ -366,12 +363,11 @@ double QgsDistanceArea::measurePerimeter( QgsGeometry* geometry )
case QGis::WKBMultiPolygon25D:
hasZptr = true;
case QGis::WKBMultiPolygon:
count = *(( int* )( wkb + 5 ) );
ptr = wkb + 9;
wkbPtr >> count;
for ( i = 0; i < count; i++ )
{
ptr = measurePolygon( ptr, 0, &res, hasZptr );
if ( !ptr )
wkbPtr = measurePolygon( wkbPtr, 0, &res, hasZptr );
if ( !wkbPtr )
{
QgsDebugMsg( "measurePolygon returned 0" );
break;
Expand All @@ -390,35 +386,32 @@ double QgsDistanceArea::measurePerimeter( QgsGeometry* geometry )

const unsigned char* QgsDistanceArea::measureLine( const unsigned char* feature, double* area, bool hasZptr )
{
const unsigned char *ptr = feature + 5;
unsigned int nPoints = *(( int* )ptr );
ptr = feature + 9;
QgsConstWkbPtr wkbPtr( feature + 1 + sizeof( int ) );
int nPoints;
wkbPtr >> nPoints;

QList<QgsPoint> points;
double x, y;

QgsDebugMsg( "This feature WKB has " + QString::number( nPoints ) + " points" );
// Extract the points from the WKB format into the vector
for ( unsigned int i = 0; i < nPoints; ++i )
for ( int i = 0; i < nPoints; ++i )
{
x = *(( double * ) ptr );
ptr += sizeof( double );
y = *(( double * ) ptr );
ptr += sizeof( double );
wkbPtr >> x >> y;
if ( hasZptr )
{
// totally ignore Z value
ptr += sizeof( double );
wkbPtr += sizeof( double );
}

points.append( QgsPoint( x, y ) );
}

*area = measureLine( points );
return ptr;
return wkbPtr;
}

double QgsDistanceArea::measureLine( const QList<QgsPoint>& points )
double QgsDistanceArea::measureLine( const QList<QgsPoint> &points )
{
if ( points.size() < 2 )
return 0;
Expand Down Expand Up @@ -460,7 +453,7 @@ double QgsDistanceArea::measureLine( const QList<QgsPoint>& points )

}

double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2 )
double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
{
double result;

Expand Down Expand Up @@ -496,16 +489,19 @@ double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2 )
}


const unsigned char* QgsDistanceArea::measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr )
const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr )
{
if ( !feature )
{
QgsDebugMsg( "no feature to measure" );
return 0;
}

QgsConstWkbPtr wkbPtr( feature + 1 + sizeof( int ) );

// get number of rings in the polygon
unsigned int numRings = *(( int* )( feature + 1 + sizeof( int ) ) );
int numRings;
wkbPtr >> numRings;

if ( numRings == 0 )
{
Expand All @@ -514,8 +510,6 @@ const unsigned char* QgsDistanceArea::measurePolygon( const unsigned char* featu
}

// Set pointer to the first ring
const unsigned char* ptr = feature + 1 + 2 * sizeof( int );

QList<QgsPoint> points;
QgsPoint pnt;
double x, y;
Expand All @@ -526,23 +520,20 @@ const unsigned char* QgsDistanceArea::measurePolygon( const unsigned char* featu

try
{
for ( unsigned int idx = 0; idx < numRings; idx++ )
for ( int idx = 0; idx < numRings; idx++ )
{
int nPoints = *(( int* )ptr );
ptr += 4;
int nPoints;
wkbPtr >> nPoints;

// Extract the points from the WKB and store in a pair of
// vectors.
for ( int jdx = 0; jdx < nPoints; jdx++ )
{
x = *(( double * ) ptr );
ptr += sizeof( double );
y = *(( double * ) ptr );
ptr += sizeof( double );
wkbPtr >> x >> y;
if ( hasZptr )
{
// totally ignore Z value
ptr += sizeof( double );
wkbPtr += sizeof( double );
}

pnt = QgsPoint( x, y );
Expand Down Expand Up @@ -589,7 +580,7 @@ const unsigned char* QgsDistanceArea::measurePolygon( const unsigned char* featu
QgsMessageLog::logMessage( QObject::tr( "Caught a coordinate system exception while trying to transform a point. Unable to calculate polygon area or perimeter." ) );
}

return ptr;
return wkbPtr;
}


Expand Down Expand Up @@ -1003,7 +994,8 @@ void QgsDistanceArea::convertMeasurement( double &measure, QGis::UnitType &measu

// Gets the conversion factor between the specified units
double factorUnits = QGis::fromUnitToUnitFactor( measureUnits, displayUnits );
if ( isArea ) factorUnits *= factorUnits;
if ( isArea )
factorUnits *= factorUnits;

QgsDebugMsg( QString( "Converting %1 %2" ).arg( QString::number( measure ), QGis::toLiteral( measureUnits ) ) );
measure *= factorUnits;
Expand Down
3,932 changes: 1,460 additions & 2,472 deletions src/core/qgsgeometry.cpp

Large diffs are not rendered by default.

60 changes: 53 additions & 7 deletions src/core/qgsgeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class QgsRectangle;
*
* @author Brendan Morley
*/
class QgsConstWkbPtr;
class QgsWkbPtr;

class CORE_EXPORT QgsGeometry
{
Expand Down Expand Up @@ -174,7 +176,6 @@ class CORE_EXPORT QgsGeometry
*/
QgsPoint closestVertex( const QgsPoint& point, int& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist );


/**
Returns the indexes of the vertices before and after the given vertex index.
Expand All @@ -189,7 +190,6 @@ class CORE_EXPORT QgsGeometry
*/
void adjacentVertices( int atVertex, int& beforeVertex, int& afterVertex );


/** Insert a new vertex before the given vertex index,
* ring and item (first number is index 0)
* If the requested vertex number (beforeVertex.back()) is greater
Expand Down Expand Up @@ -535,13 +535,13 @@ class CORE_EXPORT QgsGeometry
@param dx translation of x-coordinate
@param dy translation of y-coordinate
@param hasZValue 25D type?*/
void translateVertex( int& wkbPosition, double dx, double dy, bool hasZValue );
void translateVertex( QgsWkbPtr &wkbPtr, double dx, double dy, bool hasZValue );

/**Transforms a single vertex by ct.
@param wkbPosition position in wkb array. Is increased automatically by the function
@param ct the QgsCoordinateTransform
@param hasZValue 25D type?*/
void transformVertex( int& wkbPosition, const QgsCoordinateTransform& ct, bool hasZValue );
void transformVertex( QgsWkbPtr &wkbPtr, const QgsCoordinateTransform& ct, bool hasZValue );

//helper functions for geometry splitting

Expand Down Expand Up @@ -594,21 +594,67 @@ class CORE_EXPORT QgsGeometry
int mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry*>& splitResult );

/** return point from wkb */
QgsPoint asPoint( unsigned char*& ptr, bool hasZValue ) const;
QgsPoint asPoint( QgsConstWkbPtr &wkbPtr, bool hasZValue ) const;

/** return polyline from wkb */
QgsPolyline asPolyline( unsigned char*& ptr, bool hasZValue ) const;
QgsPolyline asPolyline( QgsConstWkbPtr &wkbPtr, bool hasZValue ) const;

/** return polygon from wkb */
QgsPolygon asPolygon( unsigned char*& ptr, bool hasZValue ) const;
QgsPolygon asPolygon( QgsConstWkbPtr &wkbPtr, bool hasZValue ) const;

static bool geosRelOp( char( *op )( const GEOSGeometry*, const GEOSGeometry * ),
const QgsGeometry* a, const QgsGeometry* b );

/**Returns < 0 if point(x/y) is left of the line x1,y1 -> x1,y2*/
double leftOf( double x, double y, double& x1, double& y1, double& x2, double& y2 );

static inline bool moveVertex( QgsWkbPtr &wkbPtr, const double &x, const double &y, int atVertex, bool hasZValue, int &pointIndex, bool isRing );
static inline bool deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int atVertex, bool hasZValue, int &pointIndex, bool isRing, bool lastItem );
static inline bool insertVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int beforeVertex, const double &x, const double &y, bool hasZValue, int &pointIndex, bool isRing );
}; // class QgsGeometry

Q_DECLARE_METATYPE( QgsGeometry );

class CORE_EXPORT QgsWkbPtr
{
mutable unsigned char *mP;

public:
QgsWkbPtr( unsigned char *p ) { mP = p; }

inline const QgsWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }

inline QgsWkbPtr &operator<<( const double &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline QgsWkbPtr &operator<<( const int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline QgsWkbPtr &operator<<( const unsigned int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline QgsWkbPtr &operator<<( const char &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline QgsWkbPtr &operator<<( const QGis::WkbType &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }

inline void operator+=( int n ) { mP += n; }

inline operator unsigned char *() const { return mP; }
};

class CORE_EXPORT QgsConstWkbPtr
{
mutable unsigned char *mP;

public:
QgsConstWkbPtr( const unsigned char *p ) { mP = ( unsigned char * ) p; }

inline const QgsConstWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsConstWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsConstWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
inline const QgsConstWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }

inline void operator+=( int n ) { mP += n; }

inline operator const unsigned char *() const { return mP; }
};

#endif
200 changes: 92 additions & 108 deletions src/core/qgsogcutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1061,8 +1061,8 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
QDomElement baseCoordElem;

bool hasZValue = false;
double *x, *y;
const unsigned char* wkb = geometry->asWkb();

QgsConstWkbPtr wkbPtr( geometry->asWkb() + 1 + sizeof( int ) );

if ( format == "GML3" )
{
Expand Down Expand Up @@ -1095,13 +1095,11 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
{
QDomElement pointElem = doc.createElement( "gml:Point" );
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
QString coordString;
x = ( double * )( wkb + 5 );
coordString += qgsDoubleToString( *x );
coordString += cs;
y = ( double * )( wkb + 5 + sizeof( double ) );
coordString += qgsDoubleToString( *y );
QDomText coordText = doc.createTextNode( coordString );

double x, y;
wkbPtr >> x >> y;
QDomText coordText = doc.createTextNode( qgsDoubleToString( x ) + cs + qgsDoubleToString( y ) );

coordElem.appendChild( coordText );
pointElem.appendChild( coordElem );
return pointElem;
Expand All @@ -1110,34 +1108,28 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
hasZValue = true;
case QGis::WKBMultiPoint:
{
const unsigned char *ptr;
int idx;
int *nPoints;

QDomElement multiPointElem = doc.createElement( "gml:MultiPoint" );
nPoints = ( int* )( wkb + 5 );
ptr = wkb + 5 + sizeof( int );
for ( idx = 0; idx < *nPoints; ++idx )

int nPoints;
wkbPtr >> nPoints;

for ( int idx = 0; idx < nPoints; ++idx )
{
ptr += ( 1 + sizeof( int ) );
wkbPtr += 1 + sizeof( int );
QDomElement pointMemberElem = doc.createElement( "gml:pointMember" );
QDomElement pointElem = doc.createElement( "gml:Point" );
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
QString coordString;
x = ( double * )( ptr );
coordString += qgsDoubleToString( *x );
coordString += cs;
ptr += sizeof( double );
y = ( double * )( ptr );
coordString += qgsDoubleToString( *y );
QDomText coordText = doc.createTextNode( coordString );

double x, y;
wkbPtr >> x >> y;
QDomText coordText = doc.createTextNode( qgsDoubleToString( x ) + cs + qgsDoubleToString( y ) );

coordElem.appendChild( coordText );
pointElem.appendChild( coordElem );

ptr += sizeof( double );
if ( hasZValue )
{
ptr += sizeof( double );
wkbPtr += sizeof( double );
}
pointMemberElem.appendChild( pointElem );
multiPointElem.appendChild( pointMemberElem );
Expand All @@ -1148,33 +1140,28 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
hasZValue = true;
case QGis::WKBLineString:
{
const unsigned char *ptr;
int *nPoints;
int idx;

QDomElement lineStringElem = doc.createElement( "gml:LineString" );
// get number of points in the line
ptr = wkb + 5;
nPoints = ( int * ) ptr;
ptr = wkb + 1 + 2 * sizeof( int );

int nPoints;
wkbPtr >> nPoints;

QDomElement coordElem = baseCoordElem.cloneNode().toElement();
QString coordString;
for ( idx = 0; idx < *nPoints; ++idx )
for ( int idx = 0; idx < nPoints; ++idx )
{
if ( idx != 0 )
{
coordString += ts;
}
x = ( double * ) ptr;
coordString += qgsDoubleToString( *x );
coordString += cs;
ptr += sizeof( double );
y = ( double * ) ptr;
coordString += qgsDoubleToString( *y );
ptr += sizeof( double );

double x, y;
wkbPtr >> x >> y;
coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );

if ( hasZValue )
{
ptr += sizeof( double );
wkbPtr += sizeof( double );
}
}
QDomText coordText = doc.createTextNode( coordString );
Expand All @@ -1186,38 +1173,37 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
hasZValue = true;
case QGis::WKBMultiLineString:
{
const unsigned char *ptr;
int idx, jdx, numLineStrings;
int *nPoints;

QDomElement multiLineStringElem = doc.createElement( "gml:MultiLineString" );
numLineStrings = ( int )( wkb[5] );
ptr = wkb + 9;
for ( jdx = 0; jdx < numLineStrings; jdx++ )

int nLines;
wkbPtr >> nLines;

for ( int jdx = 0; jdx < nLines; jdx++ )
{
QDomElement lineStringMemberElem = doc.createElement( "gml:lineStringMember" );
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
ptr += 5; // skip type since we know its 2
nPoints = ( int * ) ptr;
ptr += sizeof( int );
wkbPtr += 1 + sizeof( int ); // skip type since we know its 2

int nPoints;
wkbPtr >> nPoints;

QDomElement coordElem = baseCoordElem.cloneNode().toElement();
QString coordString;
for ( idx = 0; idx < *nPoints; idx++ )
for ( int idx = 0; idx < nPoints; idx++ )
{
if ( idx != 0 )
{
coordString += ts;
}
x = ( double * ) ptr;
coordString += qgsDoubleToString( *x );
ptr += sizeof( double );
coordString += cs;
y = ( double * ) ptr;
coordString += qgsDoubleToString( *y );
ptr += sizeof( double );

double x, y;
wkbPtr >> x >> y;

coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );

if ( hasZValue )
{
ptr += sizeof( double );
wkbPtr += sizeof( double );
}
}
QDomText coordText = doc.createTextNode( coordString );
Expand All @@ -1232,20 +1218,18 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
hasZValue = true;
case QGis::WKBPolygon:
{
const unsigned char *ptr;
int idx, jdx;
int *numRings, *nPoints;

QDomElement polygonElem = doc.createElement( "gml:Polygon" );

// get number of rings in the polygon
numRings = ( int * )( wkb + 1 + sizeof( int ) );
if ( !( *numRings ) ) // sanity check for zero rings in polygon
{
int numRings;
wkbPtr >> numRings;

if ( numRings == 0 ) // sanity check for zero rings in polygon
return QDomElement();
}
int *ringNumPoints = new int[*numRings]; // number of points in each ring
ptr = wkb + 1 + 2 * sizeof( int ); // set pointer to the first ring
for ( idx = 0; idx < *numRings; idx++ )

int *ringNumPoints = new int[numRings]; // number of points in each ring

for ( int idx = 0; idx < numRings; idx++ )
{
QString boundaryName = "gml:outerBoundaryIs";
if ( idx != 0 )
Expand All @@ -1255,27 +1239,26 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
QDomElement boundaryElem = doc.createElement( boundaryName );
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
// get number of points in the ring
nPoints = ( int * ) ptr;
ringNumPoints[idx] = *nPoints;
ptr += 4;
int nPoints;
wkbPtr >> nPoints;
ringNumPoints[idx] = nPoints;

QDomElement coordElem = baseCoordElem.cloneNode().toElement();
QString coordString;
for ( jdx = 0; jdx < *nPoints; jdx++ )
for ( int jdx = 0; jdx < nPoints; jdx++ )
{
if ( jdx != 0 )
{
coordString += ts;
}
x = ( double * ) ptr;
coordString += qgsDoubleToString( *x );
coordString += cs;
ptr += sizeof( double );
y = ( double * ) ptr;
coordString += qgsDoubleToString( *y );
ptr += sizeof( double );

double x, y;
wkbPtr >> x >> y;

coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );
if ( hasZValue )
{
ptr += sizeof( double );
wkbPtr += sizeof( double );
}
}
QDomText coordText = doc.createTextNode( coordString );
Expand All @@ -1291,22 +1274,22 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
hasZValue = true;
case QGis::WKBMultiPolygon:
{
const unsigned char *ptr;
int idx, jdx, kdx;
int *numPolygons, *numRings, *nPoints;

QDomElement multiPolygonElem = doc.createElement( "gml:MultiPolygon" );
ptr = wkb + 5;
numPolygons = ( int * ) ptr;
ptr = wkb + 9;
for ( kdx = 0; kdx < *numPolygons; kdx++ )

int numPolygons;
wkbPtr >> numPolygons;

for ( int kdx = 0; kdx < numPolygons; kdx++ )
{
QDomElement polygonMemberElem = doc.createElement( "gml:polygonMember" );
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
ptr += 5;
numRings = ( int * ) ptr;
ptr += 4;
for ( idx = 0; idx < *numRings; idx++ )

wkbPtr += 1 + sizeof( int );

int numRings;
wkbPtr >> numRings;

for ( int idx = 0; idx < numRings; idx++ )
{
QString boundaryName = "gml:outerBoundaryIs";
if ( idx != 0 )
Expand All @@ -1315,26 +1298,27 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
}
QDomElement boundaryElem = doc.createElement( boundaryName );
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
nPoints = ( int * ) ptr;
ptr += 4;

int nPoints;
wkbPtr >> nPoints;

QDomElement coordElem = baseCoordElem.cloneNode().toElement();
QString coordString;
for ( jdx = 0; jdx < *nPoints; jdx++ )
for ( int jdx = 0; jdx < nPoints; jdx++ )
{
if ( jdx != 0 )
{
coordString += ts;
}
x = ( double * ) ptr;
coordString += qgsDoubleToString( *x );
ptr += sizeof( double );
coordString += cs;
y = ( double * ) ptr;
coordString += qgsDoubleToString( *y );
ptr += sizeof( double );

double x, y;
wkbPtr >> x >> y;

coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );

if ( hasZValue )
{
ptr += sizeof( double );
wkbPtr += sizeof( double );
}
}
QDomText coordText = doc.createTextNode( coordString );
Expand Down
2 changes: 1 addition & 1 deletion tests/src/python/test_qgsgeometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()

class TestQgsGeometry(TestCase):
wkbPtr = 0
wkbPtr = 1

def testWktPointLoading(self):
myWKT='POINT(10 10)'
Expand Down