[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