= FDO RFC 66 - Support coordinate system transformation when serialize XML = This page contains a request for comments document (RFC) for the FDO Open Source project. More FDO RFCs can be found on the [wiki:FDORfcs RFCs] page. == Status == ||RFC Template Version||1.1|| ||Submission Date||April 19, 2013|| ||Last Modified||Christine Bao - April 25, 2013|| ||Author||Christine Bao|| ||RFC Status||Adopted|| ||Implementation Status||In Progress|| ||Proposed Milestone||3.8.1|| ||Assigned PSC guide(s)||Greg Boone|| ||'''Voting History'''||May 16, 2013|| ||+1||Greg Boone, Orest Halustchak, Jackie Ng || ||+0|||| ||-0|||| ||-1|||| == Overview == This proposal adds coordinate system transformation support when serialize XML using FdoXmlFeatureSerializer::!XmlSerialize(...). == Motivation == !FdoXmlFeatureSerializer is used for serializing FDO features into XML, for example it can serialize FDO features into WFS GML format. {{{ void FdoXmlFeatureSerializer::XmlSerialize( FdoIFeatureReader* reader, FdoXmlFeatureWriter* writer, FdoXmlFeatureFlags* flags) }}} However currently it can only reads the features and write the native data in data source coordinate system. If user request the data in another coordinate system, it fails to return the right value. For example, if the data source SDF's coordinate system is ca83, and published as WFS service. Customer can request this WFS in LL84 coordinate system. Currently the returned WFS GML still ca83, not expected as customer wants. == Proposed Solution == FDO does not have coordinate system transformation capability. It should provide a way to let the caller to coordinate system transformation. A solution is to define a pseudo method in FDO: {{{ class FdoCoordinateSystemTransform : public FdoDisposable { public: FDO_API virtual FdoIDirectPosition* CoordinateSystemTransform(FdoIDirectPosition* sourceGeometry); }; }}} And !FdoXmlFeatureFlags adopt this if the caller wants to do coordinate system transformation. {{{ FDO_API virtual void SetSrsName(FdoString* srsName); FDO_API virtual FdoString* GetSrsName(); FDO_API virtual void SetCoordinateSystemTransform(FdoCoordinateSystemTransform *transform); FDO_API virtual FdoCoordinateSystemTransform* GetCoordinateSystemTransform(); }}} This srs name and transform is called during FDO serializing XML. The default value is NULL, so if caller does not set it, it's ignored and work as before. The caller can make a class inherit from !FdoCoordinateSystemTransform and implement real !CoordinateSystemTransform(...) function, set the instance to !FdoXmlFeatureFlags, and the feature data is transformed. == Managed FDO API == The managed FDO API is a little tricky because it needs to allow the caller create managed child class and implement the coordinate system transformation in its own child class. A solution is to make a VirtualFdoCoordinateSystemTransform which inherits from !VirtualObject, a template in OSGeo.Fdo.Common for forwarding unmanaged methods to managed one: {{{ class VirtualFdoCoordinateSystemTransform : public VirtualObject { public: FdoIDirectPosition* CoordinateSystemTransform(FdoIDirectPosition* sourceGeometry); private: enum WrapperCallBits { TransformBit = 0x01, }; mutable FdoInt32 wrapperCallBits; }; FdoIDirectPosition* VirtualFdoCoordinateSystemTransform::CoordinateSystemTransform(FdoIDirectPosition* sourceGeometry) { if (!WrapperCallWrapper::IsCalling(wrapperCallBits, TransformBit)) { WrapperCallWrapper ctx(wrapperCallBits, TransformBit); NAMESPACE_OSGEO_GEOMETRY::IDirectPosition ^managedSourceGeometry = gcnew NAMESPACE_OSGEO_GEOMETRY::IDirectPositionImp(IntPtr(sourceGeometry), true); NAMESPACE_OSGEO_GEOMETRY::IDirectPositionImp^ destGeometry = static_cast(GetWrapper()->CoordinateSystemTransformPosition(managedSourceGeometry)); return static_cast(destGeometry->GetDisposableObject().ToPointer()); } else { return 0; } } }}} And the managed !CoordinateSystemTransform can be initialized in this way: {{{ NAMESPACE_OSGEO_FDO_XML::CoordinateSystemTransform::CoordinateSystemTransform() : Disposable(IntPtr(new VirtualFdoCoordinateSystemTransform()), true) { static_cast(GetImpObj())->SetWrapper(this); } }}} By doing this the child class of !CoordinateSystemTransform can do the coordinate system transformation. Above is pseudo code as a reference. Currently there is no concrete requirement in managed side, so the managed API is not added and tested. == Implications == Existing code is not implicated. == Test Plan == Add unit test in FDO to do pseudo coordinate system transformation. Test in !MapGuide to do real coordinate system transformation. == !Funding/Resources == Autodesk