@@ -205,6 +205,7 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
205
205
, extent_( 0 )
206
206
, ogrLayer( 0 )
207
207
, ogrOrigLayer( 0 )
208
+ , mOgrGeometryTypeFilter( wkbUnknown )
208
209
, ogrDriver( 0 )
209
210
, valid( false )
210
211
, featuresCounted( -1 )
@@ -267,6 +268,11 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
267
268
{
268
269
mSubsetString = value;
269
270
}
271
+
272
+ if ( field == " geometrytype" )
273
+ {
274
+ mOgrGeometryTypeFilter = ogrWkbGeometryTypeFromName ( value );
275
+ }
270
276
}
271
277
}
272
278
@@ -424,6 +430,11 @@ bool QgsOgrProvider::setSubsetString( QString theSQL, bool updateFeatureCount )
424
430
uri += QString ( " |subset=%1" ).arg ( mSubsetString );
425
431
}
426
432
433
+ if ( mOgrGeometryTypeFilter != wkbUnknown )
434
+ {
435
+ uri += QString ( " |geometrytype=%1" ).arg ( ogrWkbGeometryTypeName ( mOgrGeometryTypeFilter ) );
436
+ }
437
+
427
438
setDataSourceUri ( uri );
428
439
429
440
OGR_L_ResetReading ( ogrLayer );
@@ -454,8 +465,54 @@ QString QgsOgrProvider::subsetString()
454
465
return mSubsetString ;
455
466
}
456
467
468
+ QString QgsOgrProvider::ogrWkbGeometryTypeName ( OGRwkbGeometryType type ) const
469
+ {
470
+ QString geom;
471
+ switch ( type )
472
+ {
473
+ case wkbUnknown: geom = " Unknown" ; break ;
474
+ case wkbPoint: geom = " Point" ; break ;
475
+ case wkbLineString: geom = " LineString" ; break ;
476
+ case wkbPolygon: geom = " Polygon" ; break ;
477
+ case wkbMultiPoint: geom = " MultiPoint" ; break ;
478
+ case wkbMultiLineString: geom = " MultiLineString" ; break ;
479
+ case wkbMultiPolygon: geom = " MultiPolygon" ; break ;
480
+ case wkbGeometryCollection: geom = " GeometryCollection" ; break ;
481
+ case wkbNone: geom = " None" ; break ;
482
+ case wkbPoint25D: geom = " Point25D" ; break ;
483
+ case wkbLineString25D: geom = " LineString25D" ; break ;
484
+ case wkbPolygon25D: geom = " Polygon25D" ; break ;
485
+ case wkbMultiPoint25D: geom = " MultiPoint25D" ; break ;
486
+ case wkbMultiLineString25D: geom = " MultiLineString25D" ; break ;
487
+ case wkbMultiPolygon25D: geom = " MultiPolygon25D" ; break ;
488
+ default : geom = QString ( " Unknown WKB: %1" ).arg ( type );
489
+ }
490
+ return geom;
491
+ }
492
+
493
+ OGRwkbGeometryType QgsOgrProvider::ogrWkbGeometryTypeFromName ( QString typeName ) const
494
+ {
495
+ if ( typeName == " Point" ) return wkbPoint;
496
+ else if ( typeName == " LineString" ) return wkbLineString;
497
+ else if ( typeName == " Polygon" ) return wkbPolygon;
498
+ else if ( typeName == " MultiPoint" ) return wkbMultiPoint;
499
+ else if ( typeName == " MultiLineString" ) return wkbMultiLineString;
500
+ else if ( typeName == " MultiPolygon" ) return wkbMultiPolygon;
501
+ else if ( typeName == " GeometryCollection" ) return wkbGeometryCollection;
502
+ else if ( typeName == " None" ) return wkbNone;
503
+ else if ( typeName == " Point25D" ) return wkbPoint25D;
504
+ else if ( typeName == " LineString25D" ) return wkbLineString25D;
505
+ else if ( typeName == " Polygon25D" ) return wkbPolygon25D;
506
+ else if ( typeName == " MultiPoint25D" ) return wkbMultiPoint25D;
507
+ else if ( typeName == " MultiLineString25D" ) return wkbMultiLineString25D;
508
+ else if ( typeName == " MultiPolygon25D" ) return wkbMultiPolygon25D;
509
+ else if ( typeName == " GeometryCollection25D" ) return wkbGeometryCollection25D;
510
+ return wkbUnknown;
511
+ }
512
+
457
513
QStringList QgsOgrProvider::subLayers () const
458
514
{
515
+ QgsDebugMsg ( " Entered." );
459
516
if ( !valid )
460
517
{
461
518
return QStringList ();
@@ -471,29 +528,47 @@ QStringList QgsOgrProvider::subLayers() const
471
528
QString theLayerName = FROM8 ( OGR_FD_GetName ( fdef ) );
472
529
OGRwkbGeometryType layerGeomType = OGR_FD_GetGeomType ( fdef );
473
530
474
- int theLayerFeatureCount = OGR_L_GetFeatureCount ( layer, 0 );
475
-
476
- QString geom;
477
- switch ( layerGeomType )
531
+ if ( layerGeomType != wkbUnknown )
478
532
{
479
- case wkbUnknown: geom = " Unknown" ; break ;
480
- case wkbPoint: geom = " Point" ; break ;
481
- case wkbLineString: geom = " LineString" ; break ;
482
- case wkbPolygon: geom = " Polygon" ; break ;
483
- case wkbMultiPoint: geom = " MultiPoint" ; break ;
484
- case wkbMultiLineString: geom = " MultiLineString" ; break ;
485
- case wkbGeometryCollection: geom = " GeometryCollection" ; break ;
486
- case wkbNone: geom = " None" ; break ;
487
- case wkbPoint25D: geom = " Point25D" ; break ;
488
- case wkbLineString25D: geom = " LineString25D" ; break ;
489
- case wkbPolygon25D: geom = " Polygon25D" ; break ;
490
- case wkbMultiPoint25D: geom = " MultiPoint25D" ; break ;
491
- case wkbMultiLineString25D: geom = " MultiLineString25D" ; break ;
492
- case wkbMultiPolygon25D: geom = " MultiPolygon25D" ; break ;
493
- default : geom = QString ( " Unknown WKB: %1" ).arg ( layerGeomType );
533
+ int theLayerFeatureCount = OGR_L_GetFeatureCount ( layer, 0 );
534
+
535
+ QString geom = ogrWkbGeometryTypeName ( layerGeomType );
536
+
537
+ mSubLayerList << QString ( " %1:%2:%3:%4" ).arg ( i ).arg ( theLayerName ).arg ( theLayerFeatureCount == -1 ? tr ( " Unknown" ) : QString::number ( theLayerFeatureCount ) ).arg ( geom );
538
+ QgsDebugMsg ( " Unknown geometry type, count features for each geometry type" );
494
539
}
540
+ else
541
+ {
542
+ // Add virtual sublayers for supported geometry types if layer type is unknown
543
+ // Count features for geometry types
544
+ QMap<OGRwkbGeometryType, int > fCount ;
545
+ // TODO: avoid reading attributes, setRelevantFields cannot be called here because it is not constant
546
+ // setRelevantFields( true, QgsAttributeList() );
547
+ OGR_L_ResetReading ( ogrLayer );
548
+ OGRFeatureH fet;
549
+ while (( fet = OGR_L_GetNextFeature ( ogrLayer ) ) )
550
+ {
551
+ if ( !fet ) continue ;
552
+ OGRGeometryH geom = OGR_F_GetGeometryRef ( fet );
553
+ if ( geom )
554
+ {
555
+ OGRwkbGeometryType gType = OGR_G_GetGeometryType ( geom );
556
+ fCount [gType ] = fCount .value ( gType ) + 1 ;
557
+ }
558
+ OGR_F_Destroy ( fet );
559
+ }
560
+ OGR_L_ResetReading ( ogrLayer );
561
+ int i = 0 ;
562
+ foreach ( OGRwkbGeometryType gType , fCount .keys () )
563
+ {
564
+ QString geom = ogrWkbGeometryTypeName ( gType );
495
565
496
- mSubLayerList << QString ( " %1:%2:%3:%4" ).arg ( i ).arg ( theLayerName ).arg ( theLayerFeatureCount == -1 ? tr ( " Unknown" ) : QString::number ( theLayerFeatureCount ) ).arg ( geom );
566
+ QString sl = QString ( " %1:%2:%3:%4" ).arg ( i ).arg ( theLayerName ).arg ( fCount .value ( gType ) ).arg ( geom );
567
+ QgsDebugMsg ( " sub layer: " + sl );
568
+ mSubLayerList << sl;
569
+ i++;
570
+ }
571
+ }
497
572
}
498
573
499
574
return mSubLayerList ;
@@ -528,7 +603,9 @@ int QgsOgrProvider::getOgrGeomType( OGRLayerH ogrLayer )
528
603
geomType = OGR_FD_GetGeomType ( fdef );
529
604
530
605
// Some ogr drivers (e.g. GML) are not able to determine the geometry type of a layer like this.
531
- // In such cases, we examine the first feature
606
+ // In such cases, we use virtual sublayers for each geometry (originally the type was
607
+ // guessed from the first feature which resulted in loss of other formats)
608
+ /*
532
609
if ( geomType == wkbUnknown )
533
610
{
534
611
OGR_L_ResetReading( ogrLayer );
@@ -544,6 +621,7 @@ int QgsOgrProvider::getOgrGeomType( OGRLayerH ogrLayer )
544
621
}
545
622
OGR_L_ResetReading( ogrLayer );
546
623
}
624
+ */
547
625
}
548
626
return geomType;
549
627
}
@@ -553,7 +631,14 @@ void QgsOgrProvider::loadFields()
553
631
// the attribute fields need to be read again when the encoding changes
554
632
mAttributeFields .clear ();
555
633
556
- geomType = getOgrGeomType ( ogrLayer );
634
+ if ( mOgrGeometryTypeFilter != wkbUnknown )
635
+ {
636
+ geomType = mOgrGeometryTypeFilter ;
637
+ }
638
+ else
639
+ {
640
+ geomType = getOgrGeomType ( ogrLayer );
641
+ }
557
642
OGRFeatureDefnH fdef = OGR_L_GetLayerDefn ( ogrLayer );
558
643
if ( fdef )
559
644
{
@@ -733,7 +818,7 @@ QGis::WkbType QgsOgrProvider::geometryType() const
733
818
}
734
819
735
820
/* *
736
- * Return the feature type
821
+ * Return the feature count
737
822
*/
738
823
long QgsOgrProvider::featureCount () const
739
824
{
@@ -2190,7 +2275,31 @@ void QgsOgrProvider::recalculateFeatureCount()
2190
2275
2191
2276
// feature count returns number of features within current spatial filter
2192
2277
// so we remove it if there's any and then put it back
2193
- featuresCounted = OGR_L_GetFeatureCount ( ogrLayer, true );
2278
+ if ( mOgrGeometryTypeFilter == wkbUnknown )
2279
+ {
2280
+ featuresCounted = OGR_L_GetFeatureCount ( ogrLayer, true );
2281
+ }
2282
+ else
2283
+ {
2284
+ featuresCounted = 0 ;
2285
+ OGR_L_ResetReading ( ogrLayer );
2286
+ setRelevantFields ( true , QgsAttributeList () );
2287
+ OGR_L_ResetReading ( ogrLayer );
2288
+ OGRFeatureH fet;
2289
+ while (( fet = OGR_L_GetNextFeature ( ogrLayer ) ) )
2290
+ {
2291
+ if ( !fet ) continue ;
2292
+ OGRGeometryH geom = OGR_F_GetGeometryRef ( fet );
2293
+ if ( geom )
2294
+ {
2295
+ OGRwkbGeometryType gType = OGR_G_GetGeometryType ( geom );
2296
+ if ( gType == mOgrGeometryTypeFilter ) featuresCounted++;
2297
+ }
2298
+ OGR_F_Destroy ( fet );
2299
+ }
2300
+ OGR_L_ResetReading ( ogrLayer );
2301
+
2302
+ }
2194
2303
2195
2304
if ( filter )
2196
2305
{
0 commit comments