@@ -362,7 +362,124 @@ bool QgsPostgresFeatureIterator::getFeature( QgsPostgresResult &queryResult, int
362
362
unsigned char *featureGeom = new unsigned char [returnedLength + 1 ];
363
363
memset ( featureGeom, 0 , returnedLength + 1 );
364
364
memcpy ( featureGeom, PQgetvalue ( queryResult.result (), row, col ), returnedLength );
365
- feature.setGeometryAndOwnership ( featureGeom, returnedLength + 1 );
365
+
366
+ // modify 2.5D WKB types to make them compliant with OGR
367
+ unsigned int wkbType;
368
+ memcpy ( &wkbType, featureGeom + 1 , sizeof ( wkbType) );
369
+
370
+ // convert unsupported types to supported ones
371
+ switch ( wkbType )
372
+ {
373
+ case 15 :
374
+ // 2D polyhedral => multipolygon
375
+ wkbType = 6 ;
376
+ break ;
377
+ case 1015 :
378
+ // 3D polyhedral => multipolygon
379
+ wkbType = 1006 ;
380
+ break ;
381
+ case 17 :
382
+ // 2D triangle => polygon
383
+ wkbType = 3 ;
384
+ break ;
385
+ case 1017 :
386
+ // 3D triangle => polygon
387
+ wkbType = 1003 ;
388
+ break ;
389
+ case 16 :
390
+ // 2D TIN => multipolygon
391
+ wkbType = 6 ;
392
+ break ;
393
+ case 1016 :
394
+ // TIN => multipolygon
395
+ wkbType = 1006 ;
396
+ break ;
397
+ }
398
+ // convert from postgis types to qgis types
399
+ if ( wkbType >= 1000 )
400
+ {
401
+ wkbType = wkbType - 1000 + QGis::WKBPoint25D - 1 ;
402
+ }
403
+ memcpy ( featureGeom + 1 , &wkbType, sizeof ( wkbType) );
404
+
405
+ // change wkb type of inner geometries
406
+ if ( wkbType == QGis::WKBMultiPoint25D ||
407
+ wkbType == QGis::WKBMultiLineString25D ||
408
+ wkbType == QGis::WKBMultiPolygon25D )
409
+ {
410
+ unsigned int numGeoms = *(( int * )( featureGeom + 5 ));
411
+ unsigned char * wkb = featureGeom + 9 ;
412
+ for ( unsigned int i = 0 ; i < numGeoms; ++i )
413
+ {
414
+ unsigned int localType;
415
+ memcpy ( &localType, wkb + 1 , sizeof ( localType) );
416
+ switch ( localType )
417
+ {
418
+ case 15 :
419
+ // 2D polyhedral => multipolygon
420
+ localType = 6 ;
421
+ break ;
422
+ case 1015 :
423
+ // 3D polyhedral => multipolygon
424
+ localType = 1006 ;
425
+ break ;
426
+ case 17 :
427
+ // 2D triangle => polygon
428
+ localType = 3 ;
429
+ break ;
430
+ case 1017 :
431
+ // 3D triangle => polygon
432
+ localType = 1003 ;
433
+ break ;
434
+ case 16 :
435
+ // 2D TIN => multipolygon
436
+ localType = 6 ;
437
+ break ;
438
+ case 1016 :
439
+ // TIN => multipolygon
440
+ localType = 1006 ;
441
+ break ;
442
+ }
443
+ if ( localType >= 1000 )
444
+ {
445
+ localType = localType - 1000 + QGis::WKBPoint25D - 1 ;
446
+ }
447
+ memcpy ( wkb + 1 , &localType, sizeof ( localType) );
448
+
449
+ // skip endian and type info
450
+ wkb += sizeof ( unsigned int ) + 1 ;
451
+
452
+ // skip coordinates
453
+ switch ( wkbType )
454
+ {
455
+ case QGis::WKBMultiPoint25D:
456
+ wkb += sizeof ( double ) * 3 ;
457
+ break ;
458
+ case QGis::WKBMultiLineString25D:
459
+ {
460
+ unsigned int nPoints = *(( int * ) wkb );
461
+ wkb += sizeof ( nPoints );
462
+ wkb += sizeof ( double ) * 3 * nPoints;
463
+ }
464
+ break ;
465
+ default :
466
+ case QGis::WKBMultiPolygon25D:
467
+ {
468
+ unsigned int nRings = *(( int * ) wkb );
469
+ wkb += sizeof ( nRings );
470
+ for ( unsigned int j = 0 ; j < nRings; ++j )
471
+ {
472
+ unsigned int nPoints = *(( int * ) wkb );
473
+ wkb += sizeof ( nPoints );
474
+ wkb += sizeof ( double ) * 3 * nPoints;
475
+ }
476
+ }
477
+ break ;
478
+ }
479
+ }
480
+ }
481
+
482
+ feature.setGeometryAndOwnership ( featureGeom, returnedLength + 1 );
366
483
}
367
484
else
368
485
{
0 commit comments