[gdal-dev] OGR OCI Driver improvement about CoordinateDimension

Nicolas Simon nicolas.simon at spw.wallonie.be
Wed Aug 5 08:54:58 EDT 2009


Dear developpers, 

This problem is not actually well handled when we use feature with 2D and 3D coordinate.
(I provide test file with  Ticket #3025)  

1) When we WRITE data into Oracle, TranslateTOSDOGeometry() and TranslateElemGroup()
   use nDimension member variable of OCIWritableLayer to handle the translation.
   Unfortunaly nDimension initisation is
   nDimension = MAX(2,MIN(3,atoi(CPLGetConfigOption("OCI_DEFAULT_DIM","3"))));
   which is good when creating layer but not if we update feature table and
   if we have different feature table with different dimension 
   (OCI_DEFAULT_DIM cannot be set to handle both 2D and 3D simultanously). 

   The solution is to query ALL_SDO_GEOM_METADATA to get the dimension of existing table and
   overwrite the default value.

   The best place I found to put this check is in OGROCITableLayer::ReadTableDefinition() because it does not concern OGROCILoaderLayer.

   I attach the patch to Ticket #3025  (file is OCIWrite3025.diff )
    
2) When we READ data from Oracle, TranslateGeometry() and TranslateGeometryElement() take the dimension
   from Gtype of the SDO_GEOMETRY (That's right).
The dimension is well used in decoding sdo_ordinates (see GetOrdinalPoint for exemple).
The problem is when we create OGRGeometry because it always construct 3D geometry even if we have 2D geometry. 

For exemple (in TranslateGeometryElement())

    ...
    double dfX, dfY, dfZ = 0.0;

    GetOrdinalPoint( nStartOrdinal, nDimension, &dfX, &dfY, &dfZ );

    poPoint->setX( dfX );
    poPoint->setY( dfY );
    poPoint->setZ( dfZ ); 

 Many strategies exist to fix this problem.

The simplest one is to force to 2D if dimension = 2 before returning from TranslateGeometry() but this solution does a lot of extra work (building a dummy 3D and deleting the 3rd dimension)

To apply this solution a call to Flatten2D maintains the Z dimention but set it to 0. Not the solution I would like => Bad solution

An other way is to call setCoordinateDimension() but the doc says "Setting the dimension of a geometry collection will not necessarily affect the children geometries.". Not a definitive solution.

My conclusion is that I should insert test on dimension when creating the geometry to prevent the cretion of a 3rd dimension.

For exemple (in TranslateGeometryElement())

    ...
    double dfX, dfY, dfZ = 0.0;

    GetOrdinalPoint( nStartOrdinal, nDimension, &dfX, &dfY, &dfZ );

    poPoint->setX( dfX );
    poPoint->setY( dfY );
    if ( nDimension>2 ) poPoint->setZ( dfZ ); 

If you agree with this last strategie, I would provide a patch with this kind of test for all geometries created in TranslateGeometry() 

    Note: The test "nDimension>2" seems beter than "nDimension=3" because if SDO_GEOMETRY is 4 (permitted), we will generate a 3D OGRGeometry insteed of a 2D. 

    Best regards,

    Nicolas

================================================== 
Nicolas Simon, Informaticien 
Service Public de Wallonie (SPW)
Direction générale opérationnelle Agriculture, Ressources Naturelles et Environnement (DGARNE)
Département des Aides
Direction de l'Octroi des Aides agricoles - Service Informatique
14, Chaussée de Louvain - 4e étage 
5000 Namur 
BELGIUM 



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/gdal-dev/attachments/20090805/c9731752/attachment-0001.html


More information about the gdal-dev mailing list