Skip to content

Commit 6bbd17c

Browse files
committedJan 23, 2014
QgsGeometry refactoring:
* rework wkb parsing using Qgs(Const)WkbPtr * replaces pointer dereferencing with memcpy * should work on platform that don't allow unaligned accesses * "fix" adjacentVertices() for invalid inputs * improved support for MULTIPOINT * fixes insertion of first vertex into linestrings * fixes inserting into multipolygons
1 parent 37df792 commit 6bbd17c

File tree

7 files changed

+1744
-2805
lines changed

7 files changed

+1744
-2805
lines changed
 

‎src/analysis/interpolation/qgsinterpolator.cpp

Lines changed: 57 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,10 @@ int QgsInterpolator::cacheBaseData()
103103
int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double attributeValue )
104104
{
105105
if ( !geom )
106-
{
107106
return 1;
108-
}
109107

110108
bool hasZValue = false;
111-
const unsigned char* currentWkbPtr = geom->asWkb();
109+
QgsConstWkbPtr currentWkbPtr( geom->asWkb() + 1 + sizeof( int ) );
112110
vertexData theVertex; //the current vertex
113111

114112
QGis::WkbType wkbType = geom->wkbType();
@@ -118,14 +116,10 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
118116
hasZValue = true;
119117
case QGis::WKBPoint:
120118
{
121-
currentWkbPtr += ( 1 + sizeof( int ) );
122-
theVertex.x = *(( double * )( currentWkbPtr ) );
123-
currentWkbPtr += sizeof( double );
124-
theVertex.y = *(( double * )( currentWkbPtr ) );
119+
currentWkbPtr >> theVertex.x >> theVertex.y;
125120
if ( zCoord && hasZValue )
126121
{
127-
currentWkbPtr += sizeof( double );
128-
theVertex.z = *(( double * )( currentWkbPtr ) );
122+
currentWkbPtr >> theVertex.z;
129123
}
130124
else
131125
{
@@ -138,19 +132,14 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
138132
hasZValue = true;
139133
case QGis::WKBLineString:
140134
{
141-
currentWkbPtr += ( 1 + sizeof( int ) );
142-
int* npoints = ( int* )currentWkbPtr;
143-
currentWkbPtr += sizeof( int );
144-
for ( int index = 0; index < *npoints; ++index )
135+
int nPoints;
136+
currentWkbPtr >> nPoints;
137+
for ( int index = 0; index < nPoints; ++index )
145138
{
146-
theVertex.x = *(( double * )( currentWkbPtr ) );
147-
currentWkbPtr += sizeof( double );
148-
theVertex.y = *(( double * )( currentWkbPtr ) );
149-
currentWkbPtr += sizeof( double );
139+
currentWkbPtr >> theVertex.x >> theVertex.y;
150140
if ( zCoord && hasZValue ) //skip z-coordinate for 25D geometries
151141
{
152-
theVertex.z = *(( double * )( currentWkbPtr ) );
153-
currentWkbPtr += sizeof( double );
142+
currentWkbPtr >> theVertex.z;
154143
}
155144
else
156145
{
@@ -165,23 +154,19 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
165154
hasZValue = true;
166155
case QGis::WKBPolygon:
167156
{
168-
int* nrings = ( int* )( mGeometry + 5 );
169-
int* npoints;
170-
unsigned char* ptr = mGeometry + 9;
171-
for ( int index = 0; index < *nrings; ++index )
157+
int nRings;
158+
wkbPtr >> nRings;
159+
for ( int index = 0; index < nRings; ++index )
172160
{
173-
npoints = ( int* )ptr;
174-
ptr += sizeof( int );
161+
int nPoints;
162+
wkbPtr >> nPoints;
175163
for ( int index2 = 0; index2 < *npoints; ++index2 )
176164
{
177-
tempx = ( double* )ptr;
178-
ptr += sizeof( double );
179-
tempy = ( double* )ptr;
180-
if ( point.sqrDist( *tempx, *tempy ) < actdist )
165+
double x, y;
166+
wkbPtr >> x >> y;
167+
if ( point.sqrDist( x, y ) < actdist )
181168
{
182-
x = *tempx;
183-
y = *tempy;
184-
actdist = point.sqrDist( *tempx, *tempy );
169+
actdist = point.sqrDist( x, y );
185170
vertexnr = vertexcounter;
186171
//assign the rubber band indices
187172
if ( index2 == 0 )
@@ -200,10 +185,9 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
200185
afterVertex = vertexcounter + 1;
201186
}
202187
}
203-
ptr += sizeof( double );
204188
if ( hasZValue ) //skip z-coordinate for 25D geometries
205189
{
206-
ptr += sizeof( double );
190+
wkbPtr += sizeof( double );
207191
}
208192
++vertexcounter;
209193
}
@@ -214,25 +198,22 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
214198
hasZValue = true;
215199
case QGis::WKBMultiPoint:
216200
{
217-
unsigned char* ptr = mGeometry + 5;
218-
int* npoints = ( int* )ptr;
219-
ptr += sizeof( int );
220-
for ( int index = 0; index < *npoints; ++index )
201+
int nPoints;
202+
wkbPtr >> nPoints;
203+
for ( int index = 0; index < nPoints; ++index )
221204
{
222-
ptr += ( 1 + sizeof( int ) ); //skip endian and point type
223-
tempx = ( double* )ptr;
224-
tempy = ( double* )( ptr + sizeof( double ) );
225-
if ( point.sqrDist( *tempx, *tempy ) < actdist )
205+
wkbPtr += 1 + sizeof( int ); //skip endian and point type
206+
207+
double x, y;
208+
wkbPtr >> x >> y;
209+
if ( point.sqrDist( x, y ) < actdist )
226210
{
227-
x = *tempx;
228-
y = *tempy;
229-
actdist = point.sqrDist( *tempx, *tempy );
211+
actdist = point.sqrDist( x, y );
230212
vertexnr = index;
231213
}
232-
ptr += ( 2 * sizeof( double ) );
233214
if ( hasZValue ) //skip z-coordinate for 25D geometries
234215
{
235-
ptr += sizeof( double );
216+
wkbPtr += sizeof( double );
236217
}
237218
}
238219
break;
@@ -241,26 +222,19 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
241222
hasZValue = true;
242223
case QGis::WKBMultiLineString:
243224
{
244-
unsigned char* ptr = mGeometry + 5;
245-
int* nlines = ( int* )ptr;
246-
int* npoints = 0;
247-
ptr += sizeof( int );
248-
for ( int index = 0; index < *nlines; ++index )
225+
int nLines;
226+
wkbPtr >> nLines;
227+
for ( int index = 0; index < nLines; ++index )
249228
{
250-
ptr += ( sizeof( int ) + 1 );
251-
npoints = ( int* )ptr;
252-
ptr += sizeof( int );
253-
for ( int index2 = 0; index2 < *npoints; ++index2 )
229+
int nPoints;
230+
wkbPtr >> nPoints;
231+
for ( int index2 = 0; index2 < nPoints; ++index2 )
254232
{
255-
tempx = ( double* )ptr;
256-
ptr += sizeof( double );
257-
tempy = ( double* )ptr;
258-
ptr += sizeof( double );
259-
if ( point.sqrDist( *tempx, *tempy ) < actdist )
233+
double x, y;
234+
wkbPtr >> x >> y;
235+
if ( point.sqrDist( x, y ) < actdist )
260236
{
261-
x = *tempx;
262-
y = *tempy;
263-
actdist = point.sqrDist( *tempx, *tempy );
237+
actdist = point.sqrDist( x, y );
264238
vertexnr = vertexcounter;
265239

266240
if ( index2 == 0 )//assign the rubber band indices
@@ -271,7 +245,7 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
271245
{
272246
beforeVertex = vertexnr - 1;
273247
}
274-
if ( index2 == ( *npoints ) - 1 )
248+
if ( index2 == nPoints - 1 )
275249
{
276250
afterVertex = -1;
277251
}
@@ -282,7 +256,7 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
282256
}
283257
if ( hasZValue ) //skip z-coordinate for 25D geometries
284258
{
285-
ptr += sizeof( double );
259+
wkbPtr += sizeof( double );
286260
}
287261
++vertexcounter;
288262
}
@@ -293,53 +267,46 @@ int QgsInterpolator::addVerticesToCache( QgsGeometry* geom, bool zCoord, double
293267
hasZValue = true;
294268
case QGis::WKBMultiPolygon:
295269
{
296-
unsigned char* ptr = mGeometry + 5;
297-
int* npolys = ( int* )ptr;
298-
int* nrings;
299-
int* npoints;
300-
ptr += sizeof( int );
301-
for ( int index = 0; index < *npolys; ++index )
270+
int nPolys;
271+
wkbPtr >> nPolys;
272+
for ( int index = 0; index < nPolys; ++index )
302273
{
303-
ptr += ( 1 + sizeof( int ) ); //skip endian and polygon type
304-
nrings = ( int* )ptr;
305-
ptr += sizeof( int );
306-
for ( int index2 = 0; index2 < *nrings; ++index2 )
274+
wkbPtr += 1 + sizeof( int ); //skip endian and polygon type
275+
int nRings;
276+
wkbPtr >> nRings;
277+
for ( int index2 = 0; index2 < nRings; ++index2 )
307278
{
308-
npoints = ( int* )ptr;
309-
ptr += sizeof( int );
310-
for ( int index3 = 0; index3 < *npoints; ++index3 )
279+
int nPoints;
280+
wkbPtr >> nPoints;
281+
for ( int index3 = 0; index3 < nPoints; ++index3 )
311282
{
312-
tempx = ( double* )ptr;
313-
ptr += sizeof( double );
314-
tempy = ( double* )ptr;
315-
if ( point.sqrDist( *tempx, *tempy ) < actdist )
283+
double x, y;
284+
wkbPtr >> x >> y;
285+
if ( point.sqrDist( x, y ) < actdist )
316286
{
317-
x = *tempx;
318-
y = *tempy;
319-
actdist = point.sqrDist( *tempx, *tempy );
287+
actdist = point.sqrDist( x, y );
320288
vertexnr = vertexcounter;
321289

322290
//assign the rubber band indices
323291
if ( index3 == 0 )
324292
{
325-
beforeVertex = vertexcounter + ( *npoints - 2 );
293+
beforeVertex = vertexcounter + ( nPoints - 2 );
326294
afterVertex = vertexcounter + 1;
327295
}
328296
else if ( index3 == ( *npoints - 1 ) )
329297
{
330298
beforeVertex = vertexcounter - 1;
331-
afterVertex = vertexcounter - ( *npoints - 2 );
299+
afterVertex = vertexcounter - ( nPoints - 2 );
332300
}
333301
else
334302
{
335303
beforeVertex = vertexcounter - 1;
336304
afterVertex = vertexcounter + 1;
337305
}
338306
}
339-
ptr += sizeof( double );
340307
if ( hasZValue ) //skip z-coordinate for 25D geometries
341308
{
342-
ptr += sizeof( double );
309+
wkbPtr += sizeof( double );
343310
}
344311
++vertexcounter;
345312
}

‎src/analysis/interpolation/qgstininterpolator.cpp

Lines changed: 42 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
200200
//parse WKB. It is ugly, but we cannot use the methods with QgsPoint because they don't contain z-values for 25D types
201201
bool hasZValue = false;
202202
double x, y, z;
203-
const unsigned char* currentWkbPtr = g->asWkb();
203+
QgsConstWkbPtr currentWkbPtr( g->asWkb() + 1 + sizeof( int ) );
204204
//maybe a structure or break line
205205
Line3D* line = 0;
206206

@@ -211,14 +211,10 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
211211
hasZValue = true;
212212
case QGis::WKBPoint:
213213
{
214-
currentWkbPtr += ( 1 + sizeof( int ) );
215-
x = *(( double * )( currentWkbPtr ) );
216-
currentWkbPtr += sizeof( double );
217-
y = *(( double * )( currentWkbPtr ) );
214+
currentWkbPtr >> x >> y;
218215
if ( zCoord && hasZValue )
219216
{
220-
currentWkbPtr += sizeof( double );
221-
z = *(( double * )( currentWkbPtr ) );
217+
currentWkbPtr >> z;
222218
}
223219
else
224220
{
@@ -235,20 +231,15 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
235231
hasZValue = true;
236232
case QGis::WKBMultiPoint:
237233
{
238-
currentWkbPtr += ( 1 + sizeof( int ) );
239-
int* npoints = ( int* )currentWkbPtr;
240-
currentWkbPtr += sizeof( int );
241-
for ( int index = 0; index < *npoints; ++index )
234+
int nPoints;
235+
currentWkbPtr >> nPoints;
236+
for ( int index = 0; index < nPoints; ++index )
242237
{
243-
currentWkbPtr += ( 1 + sizeof( int ) ); //skip endian and point type
244-
x = *(( double* )currentWkbPtr );
245-
currentWkbPtr += sizeof( double );
246-
y = *(( double* )currentWkbPtr );
247-
currentWkbPtr += sizeof( double );
238+
currentWkbPtr += 1 + sizeof( int );
239+
currentWkbPtr >> x >> y;
248240
if ( hasZValue ) //skip z-coordinate for 25D geometries
249241
{
250-
z = *(( double* )currentWkbPtr );
251-
currentWkbPtr += sizeof( double );
242+
currentWkbPtr >> z;
252243
}
253244
else
254245
{
@@ -265,27 +256,19 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
265256
{
266257
line = new Line3D();
267258
}
268-
currentWkbPtr += ( 1 + sizeof( int ) );
269-
int* npoints = ( int* )currentWkbPtr;
270-
currentWkbPtr += sizeof( int );
271-
for ( int index = 0; index < *npoints; ++index )
259+
int nPoints;
260+
currentWkbPtr >> nPoints;
261+
for ( int index = 0; index < nPoints; ++index )
272262
{
273-
x = *(( double * )( currentWkbPtr ) );
274-
currentWkbPtr += sizeof( double );
275-
y = *(( double * )( currentWkbPtr ) );
276-
currentWkbPtr += sizeof( double );
263+
currentWkbPtr >> x >> y;
277264
if ( zCoord && hasZValue ) //skip z-coordinate for 25D geometries
278265
{
279-
z = *(( double * )( currentWkbPtr ) );
266+
currentWkbPtr >> z;
280267
}
281268
else
282269
{
283270
z = attributeValue;
284271
}
285-
if ( hasZValue )
286-
{
287-
currentWkbPtr += sizeof( double );
288-
}
289272

290273
if ( type == POINTS )
291274
{
@@ -308,30 +291,22 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
308291
hasZValue = true;
309292
case QGis::WKBMultiLineString:
310293
{
311-
currentWkbPtr += ( 1 + sizeof( int ) );
312-
int* nlines = ( int* )currentWkbPtr;
313-
int* npoints = 0;
314-
currentWkbPtr += sizeof( int );
315-
for ( int index = 0; index < *nlines; ++index )
294+
int nLines;
295+
currentWkbPtr >> nLines;
296+
for ( int index = 0; index < nLines; ++index )
316297
{
317298
if ( type != POINTS )
318299
{
319300
line = new Line3D();
320301
}
321-
currentWkbPtr += ( sizeof( int ) + 1 );
322-
npoints = ( int* )currentWkbPtr;
323-
currentWkbPtr += sizeof( int );
324-
for ( int index2 = 0; index2 < *npoints; ++index2 )
302+
int nPoints;
303+
currentWkbPtr >> nPoints;
304+
for ( int index2 = 0; index2 < nPoints; ++index2 )
325305
{
326-
x = *(( double* )currentWkbPtr );
327-
currentWkbPtr += sizeof( double );
328-
y = *(( double* )currentWkbPtr );
329-
currentWkbPtr += sizeof( double );
330-
306+
currentWkbPtr >> x >> y;
331307
if ( hasZValue ) //skip z-coordinate for 25D geometries
332308
{
333-
z = *(( double* ) currentWkbPtr );
334-
currentWkbPtr += sizeof( double );
309+
currentWkbPtr >> z;
335310
}
336311
else
337312
{
@@ -359,29 +334,23 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
359334
hasZValue = true;
360335
case QGis::WKBPolygon:
361336
{
362-
currentWkbPtr += ( 1 + sizeof( int ) );
363-
int* nrings = ( int* )currentWkbPtr;
364-
currentWkbPtr += sizeof( int );
365-
int* npoints;
366-
for ( int index = 0; index < *nrings; ++index )
337+
int nRings;
338+
currentWkbPtr >> nRings;
339+
for ( int index = 0; index < nRings; ++index )
367340
{
368341
if ( type != POINTS )
369342
{
370343
line = new Line3D();
371344
}
372345

373-
npoints = ( int* )currentWkbPtr;
374-
currentWkbPtr += sizeof( int );
375-
for ( int index2 = 0; index2 < *npoints; ++index2 )
346+
int nPoints;
347+
currentWkbPtr >> nPoints;
348+
for ( int index2 = 0; index2 < nPoints; ++index2 )
376349
{
377-
x = *(( double* )currentWkbPtr );
378-
currentWkbPtr += sizeof( double );
379-
y = *(( double* )currentWkbPtr );
380-
currentWkbPtr += sizeof( double );
350+
currentWkbPtr >> x >> y;
381351
if ( hasZValue ) //skip z-coordinate for 25D geometries
382352
{
383-
z = *(( double* )currentWkbPtr );;
384-
currentWkbPtr += sizeof( double );
353+
currentWkbPtr >> z;
385354
}
386355
else
387356
{
@@ -410,34 +379,27 @@ int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputT
410379
hasZValue = true;
411380
case QGis::WKBMultiPolygon:
412381
{
413-
currentWkbPtr += ( 1 + sizeof( int ) );
414-
int* npolys = ( int* )currentWkbPtr;
415-
int* nrings;
416-
int* npoints;
417-
currentWkbPtr += sizeof( int );
418-
for ( int index = 0; index < *npolys; ++index )
382+
int nPolys;
383+
currentWkbPtr >> nPolys;
384+
for ( int index = 0; index < nPolys; ++index )
419385
{
420-
currentWkbPtr += ( 1 + sizeof( int ) ); //skip endian and polygon type
421-
nrings = ( int* )currentWkbPtr;
422-
currentWkbPtr += sizeof( int );
423-
for ( int index2 = 0; index2 < *nrings; ++index2 )
386+
currentWkbPtr += 1 + sizeof( int );
387+
int nRings;
388+
currentWkbPtr >> nRings;
389+
for ( int index2 = 0; index2 < nRings; ++index2 )
424390
{
425391
if ( type != POINTS )
426392
{
427393
line = new Line3D();
428394
}
429-
npoints = ( int* )currentWkbPtr;
430-
currentWkbPtr += sizeof( int );
431-
for ( int index3 = 0; index3 < *npoints; ++index3 )
395+
int nPoints;
396+
currentWkbPtr >> nPoints;
397+
for ( int index3 = 0; index3 < nPoints; ++index3 )
432398
{
433-
x = *(( double* )currentWkbPtr );
434-
currentWkbPtr += sizeof( double );
435-
y = *(( double* )currentWkbPtr );
436-
currentWkbPtr += sizeof( double );
399+
currentWkbPtr >> x >> y;
437400
if ( hasZValue ) //skip z-coordinate for 25D geometries
438401
{
439-
z = *(( double* )currentWkbPtr );
440-
currentWkbPtr += sizeof( double );
402+
currentWkbPtr >> z;
441403
}
442404
else
443405
{

‎src/core/qgsdistancearea.cpp

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,6 @@ bool QgsDistanceArea::setEllipsoid( double semiMajor, double semiMinor )
255255
return true;
256256
}
257257

258-
259-
260258
double QgsDistanceArea::measure( QgsGeometry* geometry )
261259
{
262260
if ( !geometry )
@@ -266,13 +264,14 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
266264
if ( !wkb )
267265
return 0.0;
268266

269-
const unsigned char* ptr;
270-
unsigned int wkbType;
267+
QgsConstWkbPtr wkbPtr( wkb + 1 );
268+
269+
QGis::WkbType wkbType;
270+
wkbPtr >> wkbType;
271+
271272
double res, resTotal = 0;
272273
int count, i;
273274

274-
memcpy( &wkbType, ( wkb + 1 ), sizeof( wkbType ) );
275-
276275
// measure distance or area based on what is the type of geometry
277276
bool hasZptr = false;
278277

@@ -288,11 +287,10 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
288287
case QGis::WKBMultiLineString25D:
289288
hasZptr = true;
290289
case QGis::WKBMultiLineString:
291-
count = *(( int* )( wkb + 5 ) );
292-
ptr = wkb + 9;
290+
wkbPtr >> count;
293291
for ( i = 0; i < count; i++ )
294292
{
295-
ptr = measureLine( ptr, &res, hasZptr );
293+
wkbPtr = measureLine( wkbPtr, &res, hasZptr );
296294
resTotal += res;
297295
}
298296
QgsDebugMsg( "returning " + QString::number( resTotal ) );
@@ -308,12 +306,11 @@ double QgsDistanceArea::measure( QgsGeometry* geometry )
308306
case QGis::WKBMultiPolygon25D:
309307
hasZptr = true;
310308
case QGis::WKBMultiPolygon:
311-
count = *(( int* )( wkb + 5 ) );
312-
ptr = wkb + 9;
309+
wkbPtr >> count;
313310
for ( i = 0; i < count; i++ )
314311
{
315-
ptr = measurePolygon( ptr, &res, 0, hasZptr );
316-
if ( !ptr )
312+
wkbPtr = measurePolygon( wkbPtr, &res, 0, hasZptr );
313+
if ( !wkbPtr )
317314
{
318315
QgsDebugMsg( "measurePolygon returned 0" );
319316
break;
@@ -338,13 +335,13 @@ double QgsDistanceArea::measurePerimeter( QgsGeometry* geometry )
338335
if ( !wkb )
339336
return 0.0;
340337

341-
const unsigned char* ptr;
342-
unsigned int wkbType;
338+
QgsConstWkbPtr wkbPtr( wkb + 1 );
339+
QGis::WkbType wkbType;
340+
wkbPtr >> wkbType;
341+
343342
double res = 0.0, resTotal = 0.0;
344343
int count, i;
345344

346-
memcpy( &wkbType, ( wkb + 1 ), sizeof( wkbType ) );
347-
348345
// measure distance or area based on what is the type of geometry
349346
bool hasZptr = false;
350347

@@ -366,12 +363,11 @@ double QgsDistanceArea::measurePerimeter( QgsGeometry* geometry )
366363
case QGis::WKBMultiPolygon25D:
367364
hasZptr = true;
368365
case QGis::WKBMultiPolygon:
369-
count = *(( int* )( wkb + 5 ) );
370-
ptr = wkb + 9;
366+
wkbPtr >> count;
371367
for ( i = 0; i < count; i++ )
372368
{
373-
ptr = measurePolygon( ptr, 0, &res, hasZptr );
374-
if ( !ptr )
369+
wkbPtr = measurePolygon( wkbPtr, 0, &res, hasZptr );
370+
if ( !wkbPtr )
375371
{
376372
QgsDebugMsg( "measurePolygon returned 0" );
377373
break;
@@ -390,35 +386,32 @@ double QgsDistanceArea::measurePerimeter( QgsGeometry* geometry )
390386

391387
const unsigned char* QgsDistanceArea::measureLine( const unsigned char* feature, double* area, bool hasZptr )
392388
{
393-
const unsigned char *ptr = feature + 5;
394-
unsigned int nPoints = *(( int* )ptr );
395-
ptr = feature + 9;
389+
QgsConstWkbPtr wkbPtr( feature + 1 + sizeof( int ) );
390+
int nPoints;
391+
wkbPtr >> nPoints;
396392

397393
QList<QgsPoint> points;
398394
double x, y;
399395

400396
QgsDebugMsg( "This feature WKB has " + QString::number( nPoints ) + " points" );
401397
// Extract the points from the WKB format into the vector
402-
for ( unsigned int i = 0; i < nPoints; ++i )
398+
for ( int i = 0; i < nPoints; ++i )
403399
{
404-
x = *(( double * ) ptr );
405-
ptr += sizeof( double );
406-
y = *(( double * ) ptr );
407-
ptr += sizeof( double );
400+
wkbPtr >> x >> y;
408401
if ( hasZptr )
409402
{
410403
// totally ignore Z value
411-
ptr += sizeof( double );
404+
wkbPtr += sizeof( double );
412405
}
413406

414407
points.append( QgsPoint( x, y ) );
415408
}
416409

417410
*area = measureLine( points );
418-
return ptr;
411+
return wkbPtr;
419412
}
420413

421-
double QgsDistanceArea::measureLine( const QList<QgsPoint>& points )
414+
double QgsDistanceArea::measureLine( const QList<QgsPoint> &points )
422415
{
423416
if ( points.size() < 2 )
424417
return 0;
@@ -460,7 +453,7 @@ double QgsDistanceArea::measureLine( const QList<QgsPoint>& points )
460453

461454
}
462455

463-
double QgsDistanceArea::measureLine( const QgsPoint& p1, const QgsPoint& p2 )
456+
double QgsDistanceArea::measureLine( const QgsPoint &p1, const QgsPoint &p2 )
464457
{
465458
double result;
466459

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

498491

499-
const unsigned char* QgsDistanceArea::measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr )
492+
const unsigned char *QgsDistanceArea::measurePolygon( const unsigned char* feature, double* area, double* perimeter, bool hasZptr )
500493
{
501494
if ( !feature )
502495
{
503496
QgsDebugMsg( "no feature to measure" );
504497
return 0;
505498
}
506499

500+
QgsConstWkbPtr wkbPtr( feature + 1 + sizeof( int ) );
501+
507502
// get number of rings in the polygon
508-
unsigned int numRings = *(( int* )( feature + 1 + sizeof( int ) ) );
503+
int numRings;
504+
wkbPtr >> numRings;
509505

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

516512
// Set pointer to the first ring
517-
const unsigned char* ptr = feature + 1 + 2 * sizeof( int );
518-
519513
QList<QgsPoint> points;
520514
QgsPoint pnt;
521515
double x, y;
@@ -526,23 +520,20 @@ const unsigned char* QgsDistanceArea::measurePolygon( const unsigned char* featu
526520

527521
try
528522
{
529-
for ( unsigned int idx = 0; idx < numRings; idx++ )
523+
for ( int idx = 0; idx < numRings; idx++ )
530524
{
531-
int nPoints = *(( int* )ptr );
532-
ptr += 4;
525+
int nPoints;
526+
wkbPtr >> nPoints;
533527

534528
// Extract the points from the WKB and store in a pair of
535529
// vectors.
536530
for ( int jdx = 0; jdx < nPoints; jdx++ )
537531
{
538-
x = *(( double * ) ptr );
539-
ptr += sizeof( double );
540-
y = *(( double * ) ptr );
541-
ptr += sizeof( double );
532+
wkbPtr >> x >> y;
542533
if ( hasZptr )
543534
{
544535
// totally ignore Z value
545-
ptr += sizeof( double );
536+
wkbPtr += sizeof( double );
546537
}
547538

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

592-
return ptr;
583+
return wkbPtr;
593584
}
594585

595586

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

1004995
// Gets the conversion factor between the specified units
1005996
double factorUnits = QGis::fromUnitToUnitFactor( measureUnits, displayUnits );
1006-
if ( isArea ) factorUnits *= factorUnits;
997+
if ( isArea )
998+
factorUnits *= factorUnits;
1007999

10081000
QgsDebugMsg( QString( "Converting %1 %2" ).arg( QString::number( measure ), QGis::toLiteral( measureUnits ) ) );
10091001
measure *= factorUnits;

‎src/core/qgsgeometry.cpp

Lines changed: 1460 additions & 2472 deletions
Large diffs are not rendered by default.

‎src/core/qgsgeometry.h

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class QgsRectangle;
6868
*
6969
* @author Brendan Morley
7070
*/
71+
class QgsConstWkbPtr;
72+
class QgsWkbPtr;
7173

7274
class CORE_EXPORT QgsGeometry
7375
{
@@ -174,7 +176,6 @@ class CORE_EXPORT QgsGeometry
174176
*/
175177
QgsPoint closestVertex( const QgsPoint& point, int& atVertex, int& beforeVertex, int& afterVertex, double& sqrDist );
176178

177-
178179
/**
179180
Returns the indexes of the vertices before and after the given vertex index.
180181
@@ -189,7 +190,6 @@ class CORE_EXPORT QgsGeometry
189190
*/
190191
void adjacentVertices( int atVertex, int& beforeVertex, int& afterVertex );
191192

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

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

546546
//helper functions for geometry splitting
547547

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

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

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

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

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

608608
/**Returns < 0 if point(x/y) is left of the line x1,y1 -> x1,y2*/
609609
double leftOf( double x, double y, double& x1, double& y1, double& x2, double& y2 );
610+
611+
static inline bool moveVertex( QgsWkbPtr &wkbPtr, const double &x, const double &y, int atVertex, bool hasZValue, int &pointIndex, bool isRing );
612+
static inline bool deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int atVertex, bool hasZValue, int &pointIndex, bool isRing, bool lastItem );
613+
static inline bool insertVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int beforeVertex, const double &x, const double &y, bool hasZValue, int &pointIndex, bool isRing );
610614
}; // class QgsGeometry
611615

612616
Q_DECLARE_METATYPE( QgsGeometry );
613617

618+
class CORE_EXPORT QgsWkbPtr
619+
{
620+
mutable unsigned char *mP;
621+
622+
public:
623+
QgsWkbPtr( unsigned char *p ) { mP = p; }
624+
625+
inline const QgsWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
626+
inline const QgsWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
627+
inline const QgsWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
628+
inline const QgsWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
629+
inline const QgsWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
630+
631+
inline QgsWkbPtr &operator<<( const double &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
632+
inline QgsWkbPtr &operator<<( const int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
633+
inline QgsWkbPtr &operator<<( const unsigned int &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
634+
inline QgsWkbPtr &operator<<( const char &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
635+
inline QgsWkbPtr &operator<<( const QGis::WkbType &v ) { memcpy( mP, &v, sizeof( v ) ); mP += sizeof( v ); return *this; }
636+
637+
inline void operator+=( int n ) { mP += n; }
638+
639+
inline operator unsigned char *() const { return mP; }
640+
};
641+
642+
class CORE_EXPORT QgsConstWkbPtr
643+
{
644+
mutable unsigned char *mP;
645+
646+
public:
647+
QgsConstWkbPtr( const unsigned char *p ) { mP = ( unsigned char * ) p; }
648+
649+
inline const QgsConstWkbPtr &operator>>( double &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
650+
inline const QgsConstWkbPtr &operator>>( int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
651+
inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
652+
inline const QgsConstWkbPtr &operator>>( char &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
653+
inline const QgsConstWkbPtr &operator>>( QGis::WkbType &v ) const { memcpy( &v, mP, sizeof( v ) ); mP += sizeof( v ); return *this; }
654+
655+
inline void operator+=( int n ) { mP += n; }
656+
657+
inline operator const unsigned char *() const { return mP; }
658+
};
659+
614660
#endif

‎src/core/qgsogcutils.cpp

Lines changed: 92 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,8 +1061,8 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
10611061
QDomElement baseCoordElem;
10621062

10631063
bool hasZValue = false;
1064-
double *x, *y;
1065-
const unsigned char* wkb = geometry->asWkb();
1064+
1065+
QgsConstWkbPtr wkbPtr( geometry->asWkb() + 1 + sizeof( int ) );
10661066

10671067
if ( format == "GML3" )
10681068
{
@@ -1095,13 +1095,11 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
10951095
{
10961096
QDomElement pointElem = doc.createElement( "gml:Point" );
10971097
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1098-
QString coordString;
1099-
x = ( double * )( wkb + 5 );
1100-
coordString += qgsDoubleToString( *x );
1101-
coordString += cs;
1102-
y = ( double * )( wkb + 5 + sizeof( double ) );
1103-
coordString += qgsDoubleToString( *y );
1104-
QDomText coordText = doc.createTextNode( coordString );
1098+
1099+
double x, y;
1100+
wkbPtr >> x >> y;
1101+
QDomText coordText = doc.createTextNode( qgsDoubleToString( x ) + cs + qgsDoubleToString( y ) );
1102+
11051103
coordElem.appendChild( coordText );
11061104
pointElem.appendChild( coordElem );
11071105
return pointElem;
@@ -1110,34 +1108,28 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
11101108
hasZValue = true;
11111109
case QGis::WKBMultiPoint:
11121110
{
1113-
const unsigned char *ptr;
1114-
int idx;
1115-
int *nPoints;
1116-
11171111
QDomElement multiPointElem = doc.createElement( "gml:MultiPoint" );
1118-
nPoints = ( int* )( wkb + 5 );
1119-
ptr = wkb + 5 + sizeof( int );
1120-
for ( idx = 0; idx < *nPoints; ++idx )
1112+
1113+
int nPoints;
1114+
wkbPtr >> nPoints;
1115+
1116+
for ( int idx = 0; idx < nPoints; ++idx )
11211117
{
1122-
ptr += ( 1 + sizeof( int ) );
1118+
wkbPtr += 1 + sizeof( int );
11231119
QDomElement pointMemberElem = doc.createElement( "gml:pointMember" );
11241120
QDomElement pointElem = doc.createElement( "gml:Point" );
11251121
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
1126-
QString coordString;
1127-
x = ( double * )( ptr );
1128-
coordString += qgsDoubleToString( *x );
1129-
coordString += cs;
1130-
ptr += sizeof( double );
1131-
y = ( double * )( ptr );
1132-
coordString += qgsDoubleToString( *y );
1133-
QDomText coordText = doc.createTextNode( coordString );
1122+
1123+
double x, y;
1124+
wkbPtr >> x >> y;
1125+
QDomText coordText = doc.createTextNode( qgsDoubleToString( x ) + cs + qgsDoubleToString( y ) );
1126+
11341127
coordElem.appendChild( coordText );
11351128
pointElem.appendChild( coordElem );
11361129

1137-
ptr += sizeof( double );
11381130
if ( hasZValue )
11391131
{
1140-
ptr += sizeof( double );
1132+
wkbPtr += sizeof( double );
11411133
}
11421134
pointMemberElem.appendChild( pointElem );
11431135
multiPointElem.appendChild( pointMemberElem );
@@ -1148,33 +1140,28 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
11481140
hasZValue = true;
11491141
case QGis::WKBLineString:
11501142
{
1151-
const unsigned char *ptr;
1152-
int *nPoints;
1153-
int idx;
1154-
11551143
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
11561144
// get number of points in the line
1157-
ptr = wkb + 5;
1158-
nPoints = ( int * ) ptr;
1159-
ptr = wkb + 1 + 2 * sizeof( int );
1145+
1146+
int nPoints;
1147+
wkbPtr >> nPoints;
1148+
11601149
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
11611150
QString coordString;
1162-
for ( idx = 0; idx < *nPoints; ++idx )
1151+
for ( int idx = 0; idx < nPoints; ++idx )
11631152
{
11641153
if ( idx != 0 )
11651154
{
11661155
coordString += ts;
11671156
}
1168-
x = ( double * ) ptr;
1169-
coordString += qgsDoubleToString( *x );
1170-
coordString += cs;
1171-
ptr += sizeof( double );
1172-
y = ( double * ) ptr;
1173-
coordString += qgsDoubleToString( *y );
1174-
ptr += sizeof( double );
1157+
1158+
double x, y;
1159+
wkbPtr >> x >> y;
1160+
coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );
1161+
11751162
if ( hasZValue )
11761163
{
1177-
ptr += sizeof( double );
1164+
wkbPtr += sizeof( double );
11781165
}
11791166
}
11801167
QDomText coordText = doc.createTextNode( coordString );
@@ -1186,38 +1173,37 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
11861173
hasZValue = true;
11871174
case QGis::WKBMultiLineString:
11881175
{
1189-
const unsigned char *ptr;
1190-
int idx, jdx, numLineStrings;
1191-
int *nPoints;
1192-
11931176
QDomElement multiLineStringElem = doc.createElement( "gml:MultiLineString" );
1194-
numLineStrings = ( int )( wkb[5] );
1195-
ptr = wkb + 9;
1196-
for ( jdx = 0; jdx < numLineStrings; jdx++ )
1177+
1178+
int nLines;
1179+
wkbPtr >> nLines;
1180+
1181+
for ( int jdx = 0; jdx < nLines; jdx++ )
11971182
{
11981183
QDomElement lineStringMemberElem = doc.createElement( "gml:lineStringMember" );
11991184
QDomElement lineStringElem = doc.createElement( "gml:LineString" );
1200-
ptr += 5; // skip type since we know its 2
1201-
nPoints = ( int * ) ptr;
1202-
ptr += sizeof( int );
1185+
wkbPtr += 1 + sizeof( int ); // skip type since we know its 2
1186+
1187+
int nPoints;
1188+
wkbPtr >> nPoints;
1189+
12031190
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
12041191
QString coordString;
1205-
for ( idx = 0; idx < *nPoints; idx++ )
1192+
for ( int idx = 0; idx < nPoints; idx++ )
12061193
{
12071194
if ( idx != 0 )
12081195
{
12091196
coordString += ts;
12101197
}
1211-
x = ( double * ) ptr;
1212-
coordString += qgsDoubleToString( *x );
1213-
ptr += sizeof( double );
1214-
coordString += cs;
1215-
y = ( double * ) ptr;
1216-
coordString += qgsDoubleToString( *y );
1217-
ptr += sizeof( double );
1198+
1199+
double x, y;
1200+
wkbPtr >> x >> y;
1201+
1202+
coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );
1203+
12181204
if ( hasZValue )
12191205
{
1220-
ptr += sizeof( double );
1206+
wkbPtr += sizeof( double );
12211207
}
12221208
}
12231209
QDomText coordText = doc.createTextNode( coordString );
@@ -1232,20 +1218,18 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
12321218
hasZValue = true;
12331219
case QGis::WKBPolygon:
12341220
{
1235-
const unsigned char *ptr;
1236-
int idx, jdx;
1237-
int *numRings, *nPoints;
1238-
12391221
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
1222+
12401223
// get number of rings in the polygon
1241-
numRings = ( int * )( wkb + 1 + sizeof( int ) );
1242-
if ( !( *numRings ) ) // sanity check for zero rings in polygon
1243-
{
1224+
int numRings;
1225+
wkbPtr >> numRings;
1226+
1227+
if ( numRings == 0 ) // sanity check for zero rings in polygon
12441228
return QDomElement();
1245-
}
1246-
int *ringNumPoints = new int[*numRings]; // number of points in each ring
1247-
ptr = wkb + 1 + 2 * sizeof( int ); // set pointer to the first ring
1248-
for ( idx = 0; idx < *numRings; idx++ )
1229+
1230+
int *ringNumPoints = new int[numRings]; // number of points in each ring
1231+
1232+
for ( int idx = 0; idx < numRings; idx++ )
12491233
{
12501234
QString boundaryName = "gml:outerBoundaryIs";
12511235
if ( idx != 0 )
@@ -1255,27 +1239,26 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
12551239
QDomElement boundaryElem = doc.createElement( boundaryName );
12561240
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
12571241
// get number of points in the ring
1258-
nPoints = ( int * ) ptr;
1259-
ringNumPoints[idx] = *nPoints;
1260-
ptr += 4;
1242+
int nPoints;
1243+
wkbPtr >> nPoints;
1244+
ringNumPoints[idx] = nPoints;
1245+
12611246
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
12621247
QString coordString;
1263-
for ( jdx = 0; jdx < *nPoints; jdx++ )
1248+
for ( int jdx = 0; jdx < nPoints; jdx++ )
12641249
{
12651250
if ( jdx != 0 )
12661251
{
12671252
coordString += ts;
12681253
}
1269-
x = ( double * ) ptr;
1270-
coordString += qgsDoubleToString( *x );
1271-
coordString += cs;
1272-
ptr += sizeof( double );
1273-
y = ( double * ) ptr;
1274-
coordString += qgsDoubleToString( *y );
1275-
ptr += sizeof( double );
1254+
1255+
double x, y;
1256+
wkbPtr >> x >> y;
1257+
1258+
coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );
12761259
if ( hasZValue )
12771260
{
1278-
ptr += sizeof( double );
1261+
wkbPtr += sizeof( double );
12791262
}
12801263
}
12811264
QDomText coordText = doc.createTextNode( coordString );
@@ -1291,22 +1274,22 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
12911274
hasZValue = true;
12921275
case QGis::WKBMultiPolygon:
12931276
{
1294-
const unsigned char *ptr;
1295-
int idx, jdx, kdx;
1296-
int *numPolygons, *numRings, *nPoints;
1297-
12981277
QDomElement multiPolygonElem = doc.createElement( "gml:MultiPolygon" );
1299-
ptr = wkb + 5;
1300-
numPolygons = ( int * ) ptr;
1301-
ptr = wkb + 9;
1302-
for ( kdx = 0; kdx < *numPolygons; kdx++ )
1278+
1279+
int numPolygons;
1280+
wkbPtr >> numPolygons;
1281+
1282+
for ( int kdx = 0; kdx < numPolygons; kdx++ )
13031283
{
13041284
QDomElement polygonMemberElem = doc.createElement( "gml:polygonMember" );
13051285
QDomElement polygonElem = doc.createElement( "gml:Polygon" );
1306-
ptr += 5;
1307-
numRings = ( int * ) ptr;
1308-
ptr += 4;
1309-
for ( idx = 0; idx < *numRings; idx++ )
1286+
1287+
wkbPtr += 1 + sizeof( int );
1288+
1289+
int numRings;
1290+
wkbPtr >> numRings;
1291+
1292+
for ( int idx = 0; idx < numRings; idx++ )
13101293
{
13111294
QString boundaryName = "gml:outerBoundaryIs";
13121295
if ( idx != 0 )
@@ -1315,26 +1298,27 @@ QDomElement QgsOgcUtils::geometryToGML( QgsGeometry* geometry, QDomDocument& doc
13151298
}
13161299
QDomElement boundaryElem = doc.createElement( boundaryName );
13171300
QDomElement ringElem = doc.createElement( "gml:LinearRing" );
1318-
nPoints = ( int * ) ptr;
1319-
ptr += 4;
1301+
1302+
int nPoints;
1303+
wkbPtr >> nPoints;
1304+
13201305
QDomElement coordElem = baseCoordElem.cloneNode().toElement();
13211306
QString coordString;
1322-
for ( jdx = 0; jdx < *nPoints; jdx++ )
1307+
for ( int jdx = 0; jdx < nPoints; jdx++ )
13231308
{
13241309
if ( jdx != 0 )
13251310
{
13261311
coordString += ts;
13271312
}
1328-
x = ( double * ) ptr;
1329-
coordString += qgsDoubleToString( *x );
1330-
ptr += sizeof( double );
1331-
coordString += cs;
1332-
y = ( double * ) ptr;
1333-
coordString += qgsDoubleToString( *y );
1334-
ptr += sizeof( double );
1313+
1314+
double x, y;
1315+
wkbPtr >> x >> y;
1316+
1317+
coordString += qgsDoubleToString( x ) + cs + qgsDoubleToString( y );
1318+
13351319
if ( hasZValue )
13361320
{
1337-
ptr += sizeof( double );
1321+
wkbPtr += sizeof( double );
13381322
}
13391323
}
13401324
QDomText coordText = doc.createTextNode( coordString );

‎tests/src/python/test_qgsgeometry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()
4141

4242
class TestQgsGeometry(TestCase):
43-
wkbPtr = 0
43+
wkbPtr = 1
4444

4545
def testWktPointLoading(self):
4646
myWKT='POINT(10 10)'

0 commit comments

Comments
 (0)
Please sign in to comment.