[mapguide-commits] r6166 - in trunk/MgDev/Common: CoordinateSystem Geometry/CoordinateSystem

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Oct 5 04:30:22 EDT 2011


Author: baertelchen
Date: 2011-10-05 01:30:21 -0700 (Wed, 05 Oct 2011)
New Revision: 6166

Modified:
   trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.cpp
   trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.h
   trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemTransform.h
Log:
This submission is mainly to address ticket 1824 (http://trac.osgeo.org/mapguide/ticket/1824).

In RFC116, API has been added to the MgCoordinateSystemTransform class allowing to retrieve the actual geodetic transformation steps that are performed when converting from the source coordinate system.

I'm applying some corrections to that last change:
--> Documentation:
The description of the [NumberOfGeodeticTransformations] left the reader unclear in what exactly this method returns in which cases and what exactly is considered a NULL-transformation
at MapGuide API level. For example, setting up an explicit NULL-transformation from one datum to another results in [NumberOfGeodeticTransformations] returning a non-zero count.

Also fixed the [GetGeodeticTransformation]'s comment so it reflects what the method is doing. In particular, I corrected the statement, that a zero-index value would always return a NULL pointer what's not the case.

--> Implementation: 
The [GetGeodeticTransformation] accessed an empty std::wstring via the index operator - this resulted in an assertion in debug builds. The behavior in release would be undefined in the best case.
Changed the implementation so it checks the index parameter before it tries to do anything with it.

--> API naming:
All new API added for RFC116 is named 
[...GeodeticTransformation...()]. Just the [NumberOfGeodeticTransformations] was named differently. Changed that to [GetGeodeticTransformationCount] so that we now a consistent naming scheme.

[GetGeodeticTransformationCount()]
[GetGeodeticTransformation(INT32)]
[GetGeodeticTransformationDirection(INT32)]

Note though, that I'm not changing the GeometryConsoleTest project here as this has the code that would have exercised parts of the [...GeodeticTransformation...] API excluded from building.

Changes reviewed by Hugues.

Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.cpp	2011-10-05 05:33:17 UTC (rev 6165)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.cpp	2011-10-05 08:30:21 UTC (rev 6166)
@@ -894,52 +894,66 @@
 }
 
 // Geodetic Transformation Information
-INT32 CCoordinateSystemTransform::NumberOfGeodeticTransformations ()
+INT32 CCoordinateSystemTransform::GetGeodeticTransformationCount ()
 {
-    INT32 rtnValue;
-    
-    rtnValue = m_pDtcprm->xfrmCount;
-    return rtnValue;
+    //see the ctor - when passing in NULL for either the source or the target, this guy here
+    //won't get initialized
+    if (NULL == this->m_pDtcprm) 
+        return 0;
+
+    return m_pDtcprm->xfrmCount;
 }
 MgCoordinateSystemGeodeticTransformDef* CCoordinateSystemTransform::GetGeodeticTransformation (INT32 index)
 {
-    STRING xfrmDefName;
-    cs_GxXform_ *xfrmPtr;
-   	cs_GeodeticTransform_* xfrmDefPtr;
-   	Ptr<MgCoordinateSystemCatalog> pCatalog;
-    Ptr<MgCoordinateSystemGeodeticTransformDef> rtnValue;
-    Ptr<MgCoordinateSystemGeodeticTransformDefDictionary> pGxDefDict;
-    
-    MgCoordinateSystemFactory csFactory;
+    if (index < 0 || index >= this->GetGeodeticTransformationCount())
+        throw new MgArgumentOutOfRangeException(L"GetGeodeticTransformation.GetGeodeticTransformation",__LINE__,__WFILE__, NULL, L"", NULL);
 
-    xfrmDefName [0] = '\0';
-    if (index >= 0 && index < m_pDtcprm->xfrmCount)
-    {
-        // indexparameter is valid, get a pointer to the appropriate
-        // CS-MAP transformation object.
-        xfrmPtr = m_pDtcprm->xforms [index];
-        if (xfrmPtr != NULL)
+    // indexparameter is valid, get a pointer to the appropriate
+    // CS-MAP transformation object.
+    cs_GxXform_ *xfrmPtr = m_pDtcprm->xforms [index];
+    if (NULL == xfrmPtr)
+        throw new MgCoordinateSystemInitializationFailedException(L"GetGeodeticTransformation.GetGeodeticTransformation",__LINE__,__WFILE__, NULL, L"", NULL);
+
+    cs_GeodeticTransform_* xfrmDefPtr = &xfrmPtr->gxDef;
+    if (NULL == xfrmDefPtr)
+        throw new MgCoordinateSystemInitializationFailedException(L"GetGeodeticTransformation.GetGeodeticTransformation",__LINE__,__WFILE__, NULL, L"", NULL);
+
+    // Extract the name of the transformation.
+    Ptr<MgCoordinateSystemGeodeticTransformDef> catalogTransformationDef;
+    wchar_t* pDefinitionName = NULL;
+
+    MG_TRY()
+
+        //actually, CSMAP automatically sets a name up for the transformation
+        //presumably, [xfrmName] is never empty
+        pDefinitionName = Convert_Ascii_To_Wide (xfrmDefPtr->xfrmName);
+        bool hasCatalogDef = (NULL != pDefinitionName && L'\0' != pDefinitionName[0]);
+        if (hasCatalogDef)
         {
-            xfrmDefPtr = &xfrmPtr->gxDef;
-            if (xfrmDefPtr != NULL)
-            {
-                // Extract the name of the transformation.
-                wchar_t* pwszDtName = Convert_Ascii_To_Wide (xfrmDefPtr->xfrmName);
-                xfrmDefName = pwszDtName;
-                delete[] pwszDtName;
-            }
-         }
-     }
-     if (!xfrmDefName.empty ())
-     {
-        // We have a treansformation name.  Get a copy of the named
-        // transformation from the dictionary.
-        pCatalog = csFactory.GetCatalog();
-        pGxDefDict = pCatalog->GetGeodeticTransformDefDictionary ();
-        MgDisposable* tmpPtr = pGxDefDict.p->Get(xfrmDefName);
-        rtnValue = dynamic_cast<MgCoordinateSystemGeodeticTransformDef*>(tmpPtr);
-    }
-    return rtnValue.Detach ();
+            // We have a transformation name.  Get a copy of the named
+            // transformation from the dictionary.
+            MgCoordinateSystemFactory csFactory;
+            Ptr<MgCoordinateSystemCatalog> pCatalog = csFactory.GetCatalog();
+            Ptr<MgCoordinateSystemGeodeticTransformDefDictionary> transformationDictionary = pCatalog->GetGeodeticTransformDefDictionary();
+            catalogTransformationDef = transformationDictionary->GetGeodeticTransformationDef((STRING)pDefinitionName);
+        }
+
+        //this can happen (at least) in the following case:
+        //the datum dictionary contains a datum which carries geocentric transformation information with it, e.g. molodensky
+        //but the transformation dictionary does not contain that guy
+        //in this case, CSMAP returns a [xfrmDefPtr] but the actual (explicit) transformation definition
+        //doesn't exist in the dictionaries
+        if (NULL == catalogTransformationDef)
+            throw new MgCoordinateSystemLoadFailedException(L"GetGeodeticTransformation.GetGeodeticTransformation",__LINE__,__WFILE__, NULL, L"", NULL);
+
+    MG_CATCH(L"GetGeodeticTransformation.GetGeodeticTransformation")
+
+    delete[] pDefinitionName;
+    pDefinitionName = NULL;
+
+    MG_THROW()
+
+    return catalogTransformationDef.Detach ();
 }
 INT32 CCoordinateSystemTransform::GetGeodeticTransformationDirection (INT32 index)
 {

Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.h	2011-10-05 05:33:17 UTC (rev 6165)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysTransform.h	2011-10-05 08:30:21 UTC (rev 6166)
@@ -46,7 +46,7 @@
     virtual void SetSourceAndTarget(MgCoordinateSystem* pSource, MgCoordinateSystem* pTarget);
 
     // Geodetic Transformation Information
-    virtual INT32 NumberOfGeodeticTransformations();
+    virtual INT32 GetGeodeticTransformationCount();
     virtual MgCoordinateSystemGeodeticTransformDef* GetGeodeticTransformation (INT32 index);
     virtual INT32 GetGeodeticTransformationDirection (INT32 index);
     virtual MgCoordinateSystemGeodeticPath* GetExplicitGeodeticPath();

Modified: trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemTransform.h
===================================================================
--- trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemTransform.h	2011-10-05 05:33:17 UTC (rev 6165)
+++ trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemTransform.h	2011-10-05 08:30:21 UTC (rev 6166)
@@ -405,29 +405,48 @@
     ///////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns the number of geodetic transformations used in the implicit or
-    /// explicit path used to convert the source datum to the target datum.
+    /// explicit path used to convert the source to the target coordinate system.
+    /// For a geodetic transformation to take place, both the source and the target
+    /// coordinate systems have to be referenced to a datum.
     /// \return
-    /// Returns the number of geodetic transformations in the path.  Zero is
-    /// an indication of the null transformation.  A non-zero return value
-    /// should not be taken as meaning the transformation is not null.  One
-    /// or transformation definitions of the null type may also exist thus
-    /// yielding a null transformation with a non-zero transformation count.
+    /// Returns the number of geodetic transformations in the path as described above.
+    /// Returns 0, if no geodetic transformation will have to be done when converting from
+    /// the source coordinate system to the target coordinate system. In 
+    /// particular, this method returns 0 in the following cases:
+    /// \li The source and the target coordinate system is referenced to the same datum
+    /// \li Either the source or the target coordinate system is not referenced
+    ///     to a datum
+    /// \li This transformation object transforms between arbitrary coordinate systems.
     ///
-    virtual INT32 NumberOfGeodeticTransformations()=0;
+    /// \remarks
+    /// This method returns a non-zero geodetic transformation count even if a geodetic transformation
+    /// doesn't perform any calculations but simply assumes the datum the source coordinate system is referenced to,
+    /// to be equivalent to that datum the target coordinate system is referenced to.
+    virtual INT32 GetGeodeticTransformationCount()=0;
 
     ///////////////////////////////////////////////////////////////////////////
     /// \brief
-    /// Returns a pointer to the geodetic transformation definition indicated
+    /// Returns a pointer to the catalog-resident(!) geodetic transformation definition indicated
     /// by the index parameter.
     /// \param index
     /// A zero based index indicating the specific transformation definition
     /// which is to be returned.
     /// \return
     /// Returns a disposable pointer to the geodetic transformation definition
-    /// indicated by the index parameter.  A null pointer is returned if the
-    /// index parameter is zero.
-    /// \remarks
-    /// No exceptions are thrown.
+    /// indicated by the index parameter. The \link MgCoordinateSystemGeodeticTransformDef
+    /// instance is guaranteed to exist in the geodetic transformation definition
+    /// dictionary.
+    /// \exception  MgIndexOutOfRangeException if index is out of range. See \link
+    ///             GetGeodeticTransformationCount.
+    /// \exception  MgCoordinateSystemLoadFailedException if the geodetic transformation
+    ///             denoted by the index is not contained in the dictionries
+    ///             but has been created in-memory only. Note though, that this will only
+    ///             in very rare circumstances.
+    /// \exception  MgCoordinateSystemInitializationFailedException if the 
+    ///             the transformation definition object could not be setup.
+    /// \exception  MgException if the dictionaries could not be accessed or
+    ///             any other error condition has been encountered.
+    /// \see GetGeodeticTransformationCount
     ///
     virtual MgCoordinateSystemGeodeticTransformDef* GetGeodeticTransformation (INT32 index)=0;
 



More information about the mapguide-commits mailing list