Skip to content

Commit 85f6fb8

Browse files
committedFeb 11, 2014
postgres provider: convert M to Z geometries (fixes #9032)
1 parent c9a88c1 commit 85f6fb8

File tree

3 files changed

+39
-75
lines changed

3 files changed

+39
-75
lines changed
 

‎src/providers/postgres/qgspostgresconn.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,30 @@ QGis::WkbType QgsPostgresConn::wkbTypeFromPostgis( QString type )
13671367
}
13681368
}
13691369

1370+
QGis::WkbType QgsPostgresConn::wkbTypeFromOgcWkbType( unsigned int wkbType )
1371+
{
1372+
// polyhedralsurface / TIN / triangle => Polygon
1373+
if ( wkbType % 100 >= 15 )
1374+
wkbType = wkbType / 1000 * 1000 + QGis::WKBPolygon;
1375+
1376+
switch ( wkbType / 1000 )
1377+
{
1378+
case 0:
1379+
break;
1380+
case 1: // Z
1381+
wkbType = 0x80000000 + wkbType % 100;
1382+
break;
1383+
case 2: // M => Z
1384+
wkbType = 0x80000000 + wkbType % 100;
1385+
break;
1386+
case 3: // ZM
1387+
wkbType = 0xc0000000 + wkbType % 100;
1388+
break;
1389+
}
1390+
1391+
return ( QGis::WkbType ) wkbType;
1392+
}
1393+
13701394
QString QgsPostgresConn::displayStringForWkbType( QGis::WkbType type )
13711395
{
13721396
switch ( type )

‎src/providers/postgres/qgspostgresconn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ class QgsPostgresConn : public QObject
246246
static QString postgisTypeFilter( QString geomCol, QGis::WkbType wkbType, bool isGeography );
247247

248248
static QGis::WkbType wkbTypeFromGeomType( QGis::GeometryType geomType );
249+
static QGis::WkbType wkbTypeFromOgcWkbType( unsigned int ogcWkbType );
249250

250251
static QStringList connectionList();
251252
static QString selectedConnection();

‎src/providers/postgres/qgspostgresfeatureiterator.cpp

Lines changed: 14 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -410,84 +410,22 @@ bool QgsPostgresFeatureIterator::getFeature( QgsPostgresResult &queryResult, int
410410
// modify 2.5D WKB types to make them compliant with OGR
411411
unsigned int wkbType;
412412
memcpy( &wkbType, featureGeom + 1, sizeof( wkbType ) );
413-
414-
// convert unsupported types to supported ones
415-
switch ( wkbType )
416-
{
417-
case 15:
418-
// 2D polyhedral => multipolygon
419-
wkbType = 6;
420-
break;
421-
case 1015:
422-
// 3D polyhedral => multipolygon
423-
wkbType = 1006;
424-
break;
425-
case 17:
426-
// 2D triangle => polygon
427-
wkbType = 3;
428-
break;
429-
case 1017:
430-
// 3D triangle => polygon
431-
wkbType = 1003;
432-
break;
433-
case 16:
434-
// 2D TIN => multipolygon
435-
wkbType = 6;
436-
break;
437-
case 1016:
438-
// TIN => multipolygon
439-
wkbType = 1006;
440-
break;
441-
}
442-
// convert from postgis types to qgis types
443-
if ( wkbType >= 1000 )
444-
{
445-
wkbType = wkbType - 1000 + QGis::WKBPoint25D - 1;
446-
}
413+
wkbType = QgsPostgresConn::wkbTypeFromOgcWkbType( wkbType );
447414
memcpy( featureGeom + 1, &wkbType, sizeof( wkbType ) );
448415

449416
// change wkb type of inner geometries
450417
if ( wkbType == QGis::WKBMultiPoint25D ||
451418
wkbType == QGis::WKBMultiLineString25D ||
452419
wkbType == QGis::WKBMultiPolygon25D )
453420
{
454-
unsigned int numGeoms = *(( int* )( featureGeom + 5 ) );
455-
unsigned char* wkb = featureGeom + 9;
421+
unsigned int numGeoms;
422+
memcpy( &numGeoms, featureGeom + 5, sizeof( unsigned int ) );
423+
unsigned char *wkb = featureGeom + 9;
456424
for ( unsigned int i = 0; i < numGeoms; ++i )
457425
{
458426
unsigned int localType;
459427
memcpy( &localType, wkb + 1, sizeof( localType ) );
460-
switch ( localType )
461-
{
462-
case 15:
463-
// 2D polyhedral => multipolygon
464-
localType = 6;
465-
break;
466-
case 1015:
467-
// 3D polyhedral => multipolygon
468-
localType = 1006;
469-
break;
470-
case 17:
471-
// 2D triangle => polygon
472-
localType = 3;
473-
break;
474-
case 1017:
475-
// 3D triangle => polygon
476-
localType = 1003;
477-
break;
478-
case 16:
479-
// 2D TIN => multipolygon
480-
localType = 6;
481-
break;
482-
case 1016:
483-
// TIN => multipolygon
484-
localType = 1006;
485-
break;
486-
}
487-
if ( localType >= 1000 )
488-
{
489-
localType = localType - 1000 + QGis::WKBPoint25D - 1;
490-
}
428+
localType = QgsPostgresConn::wkbTypeFromOgcWkbType( localType );
491429
memcpy( wkb + 1, &localType, sizeof( localType ) );
492430

493431
// skip endian and type info
@@ -501,21 +439,22 @@ bool QgsPostgresFeatureIterator::getFeature( QgsPostgresResult &queryResult, int
501439
break;
502440
case QGis::WKBMultiLineString25D:
503441
{
504-
unsigned int nPoints = *(( int* ) wkb );
505-
wkb += sizeof( nPoints );
506-
wkb += sizeof( double ) * 3 * nPoints;
442+
unsigned int nPoints;
443+
memcpy( &nPoints, wkb, sizeof( int ) );
444+
wkb += sizeof( int ) + sizeof( double ) * 3 * nPoints;
507445
}
508446
break;
509447
default:
510448
case QGis::WKBMultiPolygon25D:
511449
{
512-
unsigned int nRings = *(( int* ) wkb );
513-
wkb += sizeof( nRings );
450+
unsigned int nRings;
451+
memcpy( &nRings, wkb, sizeof( int ) );
452+
wkb += sizeof( int );
514453
for ( unsigned int j = 0; j < nRings; ++j )
515454
{
516-
unsigned int nPoints = *(( int* ) wkb );
517-
wkb += sizeof( nPoints );
518-
wkb += sizeof( double ) * 3 * nPoints;
455+
unsigned int nPoints;
456+
memcpy( &nPoints, wkb, sizeof( int ) );
457+
wkb += sizeof( nPoints ) + sizeof( double ) * 3 * nPoints;
519458
}
520459
}
521460
break;

0 commit comments

Comments
 (0)
Please sign in to comment.