[QGIS-Developer] OGR: sqlite with subset query, QgsOgrFeatureIterator::fetchFeature with SpatialFilterRect always returns feature with id 0

Sandro Mani manisandro at gmail.com
Sat Sep 2 12:19:14 PDT 2017


Hi

I'm debugging an issue with a sqlite layer, loaded with a subset query, 
where the attribute values in the identify results table don't match the 
ones presented in the feature form (if auto show feature form is enabled).

Upon closer inspection, I noticed that the feature id of the feature 
picked by the feature info tool is always 0 (though it's remaining 
attributes are correct), this leads to the feature form displaying the 
attributes of feature fid=0, hence the mistmatch.

Stepping through the featureRequest performed by the identify tool shows 
that indeed OGR_F_GetFID( fet ) in QgsOgrFeatureIterator::readFeature 
always returns zero.

To isolate the problem, I created a small standalone program which 
replicates what the feature iterator does as a result of the identify 
query (see below), the odd thing is that there it works, and the fid is 
the expected one.

Is there some other global logic implemented in the ogr provider which 
could cause this behaviour?

Thanks
Sandro

-- 

   const char layerName[] = "S2Q_N_K_BW_F_HAUPT_F";
   const char filePath[] = "test.sqlite";
   const char subsetQuery[] = "SELECT * FROM \"s2q_n_k_bw_f_haupt_f\" 
WHERE \"OBJECTTYPE\"=6901";

   double xmin = 493070.74903165392;
   double xmax = 493071.83368281781;
   double ymin = 5763998.7917103767;
   double ymax = 5763997.707059212;

   // Specific to test.sqlite
   int fieldCount = 41;
   bool firstAttrIsFid = false;
   std::vector<int> fetchAttributes;
   for(int i = 0; i < fieldCount; ++i) {
     fetchAttributes.push_back(i);
   }

   OGRDataSourceH ds = OGROpen( filePath, FALSE, NULL );
   OGRLayerH ogrLayer = OGR_DS_GetLayerByName( ds, layerName );

   OGR_DS_ExecuteSQL( ds, subsetQuery, NULL, NULL );


   if ( OGR_L_TestCapability( ogrLayer, OLCIgnoreFields ) )
   {
     std::vector<const char *> ignoredFields;
     OGRFeatureDefnH featDefn = OGR_L_GetLayerDefn( ogrLayer );
     for ( int i = ( firstAttrIsFid ? 1 : 0 ); i < fieldCount; i++ )
     {
       if ( std::find(fetchAttributes.begin(), fetchAttributes.end(), i) 
== fetchAttributes.end() )
       {
         // add to ignored fields
         ignoredFields.push_back( OGR_Fld_GetNameRef( 
OGR_FD_GetFieldDefn( featDefn, firstAttrIsFid ? i - 1 : i ) ) );
       }
     }

     ignoredFields.push_back( "OGR_STYLE" ); // not used by QGIS
     ignoredFields.push_back( nullptr );

     OGR_L_SetIgnoredFields( ogrLayer, ignoredFields.data() );
   }

   OGR_L_SetSpatialFilterRect( ogrLayer, xmin, ymin, xmax, ymax );

   OGR_L_SetAttributeFilter( ogrLayer, nullptr );

   OGR_L_ResetReading( ogrLayer );

   OGRFeatureH fet;
   while ( ( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) {
     fprintf(stdout, "FID: %lld\n", OGR_F_GetFID( fet ));
     OGR_F_Destroy( fet );
   }

   OGR_DS_Destroy( ds );



More information about the QGIS-Developer mailing list