= FDO RFC 39 - Spatial operator combinations support = This page contains an change request (RFC) for the FDO Open Source project. More FDO RFCs can be found on the [wiki:FDORfcs RFCs] page. == Status == ||RFC Template Version||(1.0)|| ||Submission Date|| June 08, 2009 || ||Last Modified|| Dan Stoica[[Timestamp]]|| ||Author||Dan Stoica, Orest Halustchak || ||RFC Status||draft|| ||Implementation Status||draft|| ||Proposed Milestone||3.5.0.0|| ||Assigned PSC guide(s)||Greg Boone|| ||'''Voting History'''|| || ||+1|| || ||+0|| || ||-0|| || ||-1|| || == Overview == This RFC is for adding spatial operator combinations support. == Motivation == Allows implementation of the RELATE spatial filter. [TODO] == Proposed Solution == A number of changes in FDO are proposed: 1) Add new FdoSpatialOperations_Relate to FdoSpatialOperations enumeration. 2) Assign values to FdoSpatialOperations so they can be bitmapped: {{{ enum FdoSpatialOperations { FdoSpatialOperations_EnvelopeIntersects = 0x0000, FdoSpatialOperations_Relate = 0x0001, FdoSpatialOperations_Contains = 0x0002, FdoSpatialOperations_Crosses = 0x0004, FdoSpatialOperations_Disjoint = 0x0008, FdoSpatialOperations_Equals = 0x0010, FdoSpatialOperations_Intersects = 0x0020, FdoSpatialOperations_Overlaps = 0x0040, FdoSpatialOperations_Touches = 0x0080, FdoSpatialOperations_Within = 0x0100, FdoSpatialOperations_CoveredBy = 0x0200, FdoSpatialOperations_Inside = 0x0400 }; }}} 3) Enhance FdoSpatialCondition class to handle a bitmapped mask of spatial operators. Avoid creating a new set of constructors just for RELATE, by adding an extra optional parameter to the existing constructors. Add setter and getter for the mask. {{{ class FdoSpatialCondition : public FdoGeometricCondition { ... /// \param relateMask /// Input bitmapped FdoSpatialOperations mask for the RELATE spatial operation /// /// \return /// Returns FdoSpatialCondition /// Throws "Invalid parameter" exception in case relateMask > 0 and the operation is not RELATE /// FDO_API static FdoSpatialCondition* Create(FdoIdentifier* propertyName, FdoSpatialOperations operation, FdoExpression* geometry, FdoInt32 relateMask = -1); ////\\\\ NOTE: the same extra optional parameter will be added to all the constructors. /// Sets the bitmapped value of combined spatial operator(s) for RELATE usage. /// Throws "Invalid parameter" exception in case: /// value > 0 and the spatial operation is not RELATE /// value <= 0 and the spatial operation is RELATE /// value is not a valid bitmapped FdoSpatialOperations mask FDO_API void SetRelateMask( FdoInt32 value ); /// Gets the bitmapped value of combined spatial operators. FDO_API FdoInt32 GetRelateMask(); } }}} 4) Provide a common implementation for computing the pattern matrix in FdoSpatialUtility class. The matrixes for individual operations are available on the OGS site. Given a combination of operators, the method will perform an OR operation for each element of the matrix, interatively for each matrix involved. {{{ class FdoSpatialUtility { ... /// \brief /// Computes the pattern matrix DE-9IM compliant. /// See the Extended Nine-Intersection Model (DE-9IM) of the spatial operation at /// http://portal.opengeospatial.org/files/?artifact_id=18241 , section 6.1.15. /// /// \param value /// Input the bitmapped mask of FdoSpatialOperations. /// /// \return /// Returns a valid 9 characters string representing the pattern matrix. /// Returns NULL in case the input is invalid. /// Example: 'T*F**F***' is returned for 'Within' spatial operation /// FDO_API static FdoString* GetOGSPatternMatrix(FdoInt32 value); }}} == Implications == The actual implementation of the RELATE operator in the providers is easy. First, retrieve {{{ FdoSpatialCondition* pFilter = ... FdoSpatialOperations op = pFilter->GetOperation(); if ( op == FdoSpatialOperations_Relate ) { Int32 mask = pFilter->GetRelateMask(); ... } }}} Depending on the provider the coding will be different: 1. RDBMS providers supporting natively the RELATE spatial operator can implement the new API by examining the mask: a) SqlServerSpatial or PostGIS providers need the string pattern matrix to pass it as input for STRelate() and ST_Relate() respectively: {{{ FdoString* matrix = FdoSpatialUtility::GetOGSPatternMatrix( mask ); // Build the SQL like: STRelate(' + matrix +'); }}} b) An Oracle provider will inspect the bitmapped mask and extract the spatial operators to build the SQL like: {{{ SDO_RELATE(... 'mask=touch+coveredby') = 'TRUE'; }}} 2) The providers not supporting natively RELATE will need to expand the RELATE filter into a OR filter with multiple basic spatial operations. == Test Plan == == Funding/Resources == Autodesk to provide resources / funding. == Referencies == [1] [http://portal.opengeospatial.org/files/?artifact_id=18241] - Extended Nine-Intersection Model (DE-9IM) [[BR]] [2] [http://download-west.oracle.com/docs/cd/B19306_01/appdev.102/b14255/sdo_operat.htm#i78531] - Oracle SDO_RELATE() operator[[BR]] [3] [http://msdn.microsoft.com/en-us/library/bb933915.aspx] - SqlServer STRelate() operator[[BR]] [4] [http://postgis.refractions.net/download/postgis-1.3.6.pdf] - PostGIS ST_Relate() operator[[BR]]