[mapserver-dev] WFS + GEOS + native Oracle Spatial + <ogc:Intersects> = not working?

Vitali Diatchkov vitali at arbonaut.com
Thu Mar 11 18:23:48 EST 2010


Hello.

I have several issues about MapServer as a WFS service.

I am using MapServer as a WFS service from UDIG.
Recently I have found that  raw <ogc:Intersects>  filter doesn't work on 
latest MapServer that I compile myself against layer with native Oracle 
Spatial connection. The reason was absence of GEOS support, so I 
complied MapServer with GEOS. And things became even more unexpected.

First of all after switching debug tracing in MAP file I have found that 
the log file contains:
-------------------------------------------------------------------------------
[Thu Mar 11 22:03:29 2010].859000 msOracleSpatialLayerResultGetShape(): 
OracleSpatial error. msOracleSpatialLayerResultGetShape record out of range
[Thu Mar 11 22:03:29 2010].859000 msOracleSpatialLayerResultGetShape(): 
OracleSpatial error. msOracleSpatialLayerResultGetShape record out of range
-------------------------------------------------------------------------------

The next step was debugging from Visual Studio and what a surprise.
Well it seems native Oracle  Spatial connector can directly deal only 
with WINDOW-based queries (or BBOX). All spatial filters like 
<ogc:Intersects> are processed in GEOS. But this is implemented in 
context of legacy architecture and I wouldn't be the first to mention 
that is is not efficient at all.
What I have found that if Intersects filter provided (as an example of 
non BBOX filter) then during first iteration all records are extracted 
from the table in  msOracleSpatialLayerWhichShapes function. At the same 
time an extent of the whole layer is used to get those records. If there 
are 1000000 records, means all are loaded. Intersection is done then 
using GEOS spatial predicates with a geometry provided in filter for all 
loaded records. Resuts are somehow cached.

Then the next step starts in FLTLayerApplyPlainFilterToLayer calling 
FLTAddToLayerResultCache. And there a bug is in: a) architecture b) 
"maporaclespatial.c" logic.
Let's assume there are 1300 records in Oracle table. The buffer in 
msOracleSpatialStatement structure is 1024 by default.  When last 
element in buffer is processed then the next bunch of items are fetched 
from a result set. In our case first time buffer is fully loaded and has 
1024 items. In next fetching the rest 276 items are loaded into the 
buffer starting from 1st cell. Fetching I am talking about takes place 
in msOracleSpatialLayerNextShape function.
What information is cached?
-------------------------------------------------------------
addResult(lp->resultcache, shape.classindex, shape.index, shape.tileindex);
-------------------------------------------------------------
in msQueryByOperator function.

In my test case shape.index is a primary key of a feature from a  
database, like "214789" and shape.tileindex is a kind of index of the 
cell in a buffer "msOracleSpatialStatemen.obj".  Let's assume 5 features 
are actually in a result of intersction operation. In current logic 
their shape.tileindex value might be 45, 567 or 1238 e.g. that is out of 
mentioned buffer limits. Actually is is assigned in
-------------------------------------------------------------------
shape->tileindex = sthand->row_num; /* Index into cursor */
-------------------------------------------------------------------
where row_num just grows permanently.

FLTAddToLayerResultCache leads to a call of
----------------------------------------------------------------------
int msOracleSpatialLayerResultGetShape( layerObj *layer, shapeObj 
*shape, int record, long pkey )
----------------------------------------------------------------------
where arguments are sort of:
record=-1 (always)
pkey=214789

where "record" is equal to -1 (always, comes from  "status = 
msLayerResultsGetShape(psLayer, &shape, -1, anValues[i]);")

this -1 actually kills all the logic in msOracleSpatialLayerResultGetShape.

In a result we have nothing to return as a WFS response and dummy XML is 
output:
--------------------------------------------------------------------
<wfs:FeatureCollection xsi:schemaLocation="http://www.opengis.net/wfs 
http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd" >
<gml:boundedBy>
<gml:Box srsName="EPSG:2393">
<gml:coordinates>-1.000000,-1.000000 -1.000000,-1.000000</gml:coordinates>
</gml:Box>
</gml:boundedBy>
</wfs:FeatureCollection>
------------------------------------------------------------------------------

After some studying of code in maporaclespatial.c I can not understand 
how this scenario might work at all. Is it so that WFS with GEOS and 
MapServer's native Oracle Spatial is not a solution for this use case 
and only simple BBOX queries works?
But even if to imagine that Intersects filter works and there is no 
problem with buffer and ietms indexing overlapping, loading of all 
records during first step for processing by GEOS is not appropriate also.

The codebase of MapServer is large and I could miss something 
important.. Any comments on that?

Regards,
Vitali Diatchkov.

P.S. Latest branch-5-6 codebase is used.


More information about the mapserver-dev mailing list