Opened 11 years ago

Closed 11 years ago

#4948 closed enhancement (fixed)

ExecuteSQL producing features with missing spatial reference.

Reported by: digimap2k Owned by: warmerdam
Priority: normal Milestone: 1.10.0
Component: OGR_SF Version: 1.9.2
Severity: normal Keywords:
Cc:

Description

I call the OGRDataSource method "ExecuteSQL" with "NULL" as the spatial filter geometry. The returned layer is iterated and extracted features do not include a valid spatial reference object. When I do the same call with a valid spatial filter geometry the extracted features are spatially referenced to match the database table.

The reason this is important is that when implementing the full filter specification of WFS 1.1.0 the filters demand a more complex SELECT than can be achieved through passing a geometry as a spatial filter and we are forced to NULL the geometry and do it all through the SQL statement.

It would be nice if the datasource class could attempt to set the spatial filter on the layer irrespective of whether the caller is supplying a spatial filter geometry. The assumption being that if an SRS is extractable from the table it should always be made available and used for outgoing features.

The workaround for the time being is simply to call "GetSpatialReference" on the layer (and then garbage the return) immediately after SQL execution and prior to feature iteration. This establishes the spatial reference object on the layer and features come out correctly referenced ready for transformation.

Change History (3)

comment:1 by Even Rouault, 11 years ago

You have to be more specific because ExecuteSQL() can be implemented differently in different driver. Which driver is used by your datasource ?

comment:2 by digimap2k, 11 years ago

I am using the PostGreSQL driver.

The problem seems to be in the construction of the OGRPGResultLayer object. I've stepped through the constructor and the following is happening:

  1. poFeatureDefn is returning correctly with "bHasPostGISGeometry = true" from the ReadResultDefinition call.
  1. The "table" and "tableSchema" are found correctly.
  1. The constructor then hits this section which does nothing as we have a geometry rather than a geography.

if (bHasPostGISGeography) {

FIXME? But for the moment, PostGIS 1.5 only handles SRID:4326. nSRSId = 4326;

}

So far so good.... But then when we call "getNextFeature" on the PG Layer it hits this:

OGRFeature *OGRPGResultLayer::GetNextFeature()

{
    if( m_poFilterGeom != NULL &&
        (bHasPostGISGeometry || bHasPostGISGeography) && nSRSId == UNDETERMINED_SRID )
    {
        GetSpatialRef(); /* make sure that we fetch the SRID if not already done */
    }

    for( ; TRUE; )
    {
        OGRFeature      *poFeature;

        poFeature = GetNextRawFeature();
        if( poFeature == NULL )
            return NULL;

        if( (m_poFilterGeom == NULL
            || ((bHasPostGISGeometry || bHasPostGISGeography) && nSRSId != UNDETERMINED_SRID)
            || FilterGeometry( poFeature->GetGeometryRef() ) )
            && (m_poAttrQuery == NULL
                || m_poAttrQuery->Evaluate( poFeature )) )
            return poFeature;

        delete poFeature;
    }
}


Which is only bothering with the spatial reference when the filter geometry is set. In our case the filter geometry is NULL as the SQL is handling a much more complex geometry operation.

Hope that helps.

comment:3 by Even Rouault, 11 years ago

Component: defaultOGR_SF
Milestone: 1.10.0
Resolution: fixed
Status: newclosed

You were almost to the point of providing the patch ;-)

trunk r25488 "PG result layer: always fetch the SRS to attach it to feature geometry (and not only when a spatial filter is set) (#4948)"

Note: See TracTickets for help on using tickets.