[mapguide-commits] r9255 - in trunk/MgDev: . Common/Foundation/System Common/MapGuideCommon/Services Common/PlatformBase/Services Common/Schema Server/src/Services/Feature Server/src/UnitTesting UnitTest/WebTier/MapAgent/MapAgentForms Web/src/HttpHandler

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sun Nov 26 14:17:19 PST 2017


Author: jng
Date: 2017-11-26 14:17:19 -0800 (Sun, 26 Nov 2017)
New Revision: 9255

Added:
   trunk/MgDev/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cstransformcoordinatesform.html
   trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.h
Modified:
   trunk/MgDev/
   trunk/MgDev/Common/Foundation/System/Util.cpp
   trunk/MgDev/Common/Foundation/System/Util.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.h
   trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.cpp
   trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.h
   trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.cpp
   trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.h
   trunk/MgDev/Common/PlatformBase/Services/Reader.h
   trunk/MgDev/Server/src/Services/Feature/ServerDataReader.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerDataReader.h
   trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.h
   trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h
   trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.h
   trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.cpp
   trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.h
   trunk/MgDev/Server/src/UnitTesting/TestMisc.cpp
   trunk/MgDev/Server/src/UnitTesting/TestMisc.h
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/coordinatesystemapi.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectaggregatesform.html
   trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectfeaturesform.html
   trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj
   trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters
   trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h
   trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.h
   trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.h
   trunk/MgDev/Web/src/HttpHandler/HttpUtil.cpp
   trunk/MgDev/Web/src/HttpHandler/HttpUtil.h
   trunk/MgDev/Web/src/HttpHandler/Makefile.am
   trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp
   trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h
   trunk/MgDev/Web/src/HttpHandler/XmlJsonConvert.cpp
Log:
Merge in RFC 162 sandbox


Property changes on: trunk/MgDev
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/2.4/MgDev:6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev:8276-8286,8288-8292,8297,8299,8301,8303,8314-8315,8318,8335,8340,8354-8355,8365,8373
/branches/3.0/MgDev:8658,8705,8710
/branches/3.1/MgDev:9026,9058-9059,9067-9068
/sandbox/VC140:8684-8759
/sandbox/adsk/2.6l:8727
/sandbox/adsk/3.0m:8563,8584,8607,8625,8694-8695
/sandbox/adsk/3.1n:8871,8895,8901,8912-8913,8921-8922,8942,9019-9020
/sandbox/jng/clean_json:8818-9180
/sandbox/jng/cmdline:9199-9217
/sandbox/jng/convenience_apis:8262-8268,8271-8363
/sandbox/jng/createruntimemap:7486-7555
/sandbox/jng/dwftk:8321-8324,8328-8329,8331,8352
/sandbox/jng/geoprocessing:9205-9229
/sandbox/jng/geos34x:8256-8259
/sandbox/jng/php56x:8975-8985
/sandbox/jng/rfc155:8872-8884
/sandbox/jng/simplify:8814-9141
/sandbox/jng/tiling:8174-8208
/sandbox/jng/utfgrid:9179-9212
/sandbox/jng/v30:8212-8227
/sandbox/rfc94:5099-5163
   + /branches/2.4/MgDev:6749-6756,6777-6783,6785-6787,6789,6791-6794,6796-6801,6954-6962,6986-7006
/branches/2.6/MgDev:8276-8286,8288-8292,8297,8299,8301,8303,8314-8315,8318,8335,8340,8354-8355,8365,8373
/branches/3.0/MgDev:8658,8705,8710
/branches/3.1/MgDev:9026,9058-9059,9067-9068
/sandbox/VC140:8684-8759
/sandbox/adsk/2.6l:8727
/sandbox/adsk/3.0m:8563,8584,8607,8625,8694-8695
/sandbox/adsk/3.1n:8871,8895,8901,8912-8913,8921-8922,8942,9019-9020
/sandbox/jng/clean_json:8818-9180
/sandbox/jng/cmdline:9199-9217
/sandbox/jng/convenience_apis:8262-8268,8271-8363
/sandbox/jng/coordsys_mapagent:9231-9254
/sandbox/jng/createruntimemap:7486-7555
/sandbox/jng/dwftk:8321-8324,8328-8329,8331,8352
/sandbox/jng/geoprocessing:9205-9229
/sandbox/jng/geos34x:8256-8259
/sandbox/jng/php56x:8975-8985
/sandbox/jng/rfc155:8872-8884
/sandbox/jng/simplify:8814-9141
/sandbox/jng/tiling:8174-8208
/sandbox/jng/utfgrid:9179-9212
/sandbox/jng/v30:8212-8227
/sandbox/rfc94:5099-5163

Modified: trunk/MgDev/Common/Foundation/System/Util.cpp
===================================================================
--- trunk/MgDev/Common/Foundation/System/Util.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/Foundation/System/Util.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -682,6 +682,19 @@
     return ::wcstod(tmp.c_str(), NULL);
 }
 
+bool MgUtil::TryParseDouble(CREFSTRING source, double& result)
+{
+    STRING tmp = Trim(source, L" \t\r\n");
+
+    wchar_t* endptr = 0;
+    const wchar_t* str = tmp.c_str();
+    result = ::wcstod(str, &endptr);
+
+    if (*endptr != '\0' || endptr == str)
+        return false;
+    return true;
+}
+
 bool MgUtil::StringToBoolean(const string& str)
 {
     string tmp = Trim(str, " \t\r\n");

Modified: trunk/MgDev/Common/Foundation/System/Util.h
===================================================================
--- trunk/MgDev/Common/Foundation/System/Util.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/Foundation/System/Util.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -507,6 +507,23 @@
     ///
     static STRING ToUpper(CREFSTRING source);
 
+    //////////////////////////////////////////////
+    /// \brief
+    /// Attempt to parse the given string as a double.
+    ///
+    /// \param source
+    /// source string to convert
+    ///
+    /// \param result
+    /// The parsed value if successful
+    ///
+    /// \return
+    /// true if parsing is successful. false otherwise
+    ///
+    /// Be cautious using this function with localized strings.
+    ///
+    static bool TryParseDouble(CREFSTRING source, double& result);
+
 INTERNAL_API:
 
     ///////////////////////////////////////////////////////////////////////////

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -687,7 +687,7 @@
     BodyStartUtf8(str);
     while ( this->ReadNext() )
     {
-        CurrentToStringUtf8(str);
+        CurrentToStringUtf8(str, NULL);
     }
     BodyEndUtf8(str);
     ResponseEndUtf8(str);
@@ -740,7 +740,7 @@
     }
 }
 
-void MgProxyDataReader::CurrentToStringUtf8(string& str)
+void MgProxyDataReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     if (NULL != (MgBatchPropertyCollection*)m_set)
     {
@@ -748,6 +748,19 @@
         INT32 cnt = propCol->GetCount();
         if (propCol != NULL && cnt > 0)
         {
+            //If xform given, attach it to any geometry properties
+            if (NULL != xform)
+            {
+                for (INT32 i = 0; i < cnt; i++) 
+                {
+                    Ptr<MgProperty> prop = propCol->GetItem(i);
+                    if (prop->GetPropertyType() == MgPropertyType::Geometry) 
+                    {
+                        MgGeometryProperty* geomProp = static_cast<MgGeometryProperty*>(prop.p);
+                        geomProp->AttachTransform(xform);
+                    }
+                }
+            }
             str += "<PropertyCollection>";
             propCol->ToXml(str, false);
             str += "</PropertyCollection>";

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyDataReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -593,7 +593,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// \brief

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -838,7 +838,7 @@
         BodyStartUtf8(str);
         while ( this->ReadNext() )
         {
-            CurrentToStringUtf8(str);
+            CurrentToStringUtf8(str, NULL);
         }
         BodyEndUtf8(str);
         ResponseEndUtf8(str);
@@ -893,7 +893,7 @@
     }
 }
 
-void MgProxyFeatureReader::CurrentToStringUtf8(string& str)
+void MgProxyFeatureReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     if (NULL != (MgFeatureSet*)m_set)
     {
@@ -901,6 +901,19 @@
         INT32 cnt = propCol->GetCount();
         if (propCol != NULL && cnt > 0)
         {
+            //If xform given, attach it to any geometry properties
+            if (NULL != xform)
+            {
+                for (INT32 i = 0; i < cnt; i++)
+                {
+                    Ptr<MgProperty> prop = propCol->GetItem(i);
+                    if (prop->GetPropertyType() == MgPropertyType::Geometry)
+                    {
+                        MgGeometryProperty* geomProp = static_cast<MgGeometryProperty*>(prop.p);
+                        geomProp->AttachTransform(xform);
+                    }
+                }
+            }
             propCol->ToFeature(str);
         }
     }

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyFeatureReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -566,7 +566,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// \brief

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -773,7 +773,7 @@
         BodyStartUtf8(str);
         while ( this->ReadNext() )
         {
-            CurrentToStringUtf8(str);
+            CurrentToStringUtf8(str, NULL);
         }
         BodyEndUtf8(str);
         ResponseEndUtf8(str);
@@ -828,7 +828,7 @@
     }
 }
 
-void MgProxyGwsFeatureReader::CurrentToStringUtf8(string& str)
+void MgProxyGwsFeatureReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     if (NULL != (MgFeatureSet*)m_set)
     {
@@ -836,6 +836,19 @@
         INT32 cnt = propCol->GetCount();
         if (propCol != NULL && cnt > 0)
         {
+            //If xform given, attach it to any geometry properties
+            if (NULL != xform)
+            {
+                for (INT32 i = 0; i < cnt; i++)
+                {
+                    Ptr<MgProperty> prop = propCol->GetItem(i);
+                    if (prop->GetPropertyType() == MgPropertyType::Geometry)
+                    {
+                        MgGeometryProperty* geomProp = static_cast<MgGeometryProperty*>(prop.p);
+                        geomProp->AttachTransform(xform);
+                    }
+                }
+            }
             propCol->ToFeature(str);
         }
     }

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxyGwsFeatureReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -540,7 +540,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// \brief

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -685,7 +685,7 @@
     BodyStartUtf8(str);
     while ( this->ReadNext() )
     {
-        CurrentToStringUtf8(str);
+        CurrentToStringUtf8(str, NULL);
     }
     BodyEndUtf8(str);
     ResponseEndUtf8(str);
@@ -738,7 +738,7 @@
     }
 }
 
-void MgProxySqlDataReader::CurrentToStringUtf8(string& str)
+void MgProxySqlDataReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     if (NULL != (MgBatchPropertyCollection*)m_set)
     {
@@ -746,6 +746,19 @@
         INT32 cnt = propCol->GetCount();
         if (propCol != NULL && cnt > 0)
         {
+            //If xform given, attach it to any geometry properties
+            if (NULL != xform)
+            {
+                for (INT32 i = 0; i < cnt; i++)
+                {
+                    Ptr<MgProperty> prop = propCol->GetItem(i);
+                    if (prop->GetPropertyType() == MgPropertyType::Geometry)
+                    {
+                        MgGeometryProperty* geomProp = static_cast<MgGeometryProperty*>(prop.p);
+                        geomProp->AttachTransform(xform);
+                    }
+                }
+            }
             propCol->ToRow(str);
         }
     }

Modified: trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/MapGuideCommon/Services/ProxySqlDataReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -563,7 +563,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// \brief

Modified: trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.cpp
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -47,6 +47,7 @@
 MgGeometryProperty::MgGeometryProperty()
 {
     m_value = NULL;
+    m_xform = NULL;
 }
 
 /////////////////////////////////////////////////////////////////
@@ -133,7 +134,7 @@
             if (byteReader != NULL)
             {
                 MgAgfReaderWriter agfReader;
-                Ptr<MgGeometry> geom = agfReader.Read(byteReader);
+                Ptr<MgGeometry> geom = agfReader.Read(byteReader, m_xform);
 
                 // geom->ToXml(str); // TODO: we need this method
                 STRING awktStr = L"";
@@ -195,3 +196,8 @@
 
     m_value = stream->GetStream();
 }
+
+void MgGeometryProperty::AttachTransform(MgTransform* xform)
+{
+    m_xform = SAFE_ADDREF(xform);
+}
\ No newline at end of file

Modified: trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/PlatformBase/Services/GeometryProperty.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -170,6 +170,15 @@
     ///
     virtual void Deserialize(MgStream* stream);
 
+    //////////////////////////////////////////////////////////////////
+    /// \brief
+    /// Attaches the given transform.
+    ///
+    /// \param xform
+    /// Transform
+    ///
+    void AttachTransform(MgTransform* xform);
+
 protected:
 
     /////////////////////////////////////////////////////////////////
@@ -200,6 +209,7 @@
 private:
 
     Ptr<MgByteReader>   m_value;
+    Ptr<MgTransform>    m_xform;
 
 CLASS_ID:
     static const INT32 m_cls_id = PlatformBase_FeatureService_GeometryProperty;

Modified: trunk/MgDev/Common/PlatformBase/Services/Reader.h
===================================================================
--- trunk/MgDev/Common/PlatformBase/Services/Reader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Common/PlatformBase/Services/Reader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -1216,7 +1216,7 @@
     /// \param str
     /// Destination string.
     ///
-    virtual void CurrentToStringUtf8(string& str) = 0;
+    virtual void CurrentToStringUtf8(string& str, MgTransform* xform) = 0;
 
     //////////////////////////////////////////////////////////////////
     /// \brief

Copied: trunk/MgDev/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd (from rev 9254, sandbox/jng/coordsys_mapagent/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd)
===================================================================
--- trunk/MgDev/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd	                        (rev 0)
+++ trunk/MgDev/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd	2017-11-26 22:17:19 UTC (rev 9255)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+  <xs:element name="TransformedCoordinateCollection">
+    <xs:annotation>
+      <xs:documentation>A collection of transformed coordinates</xs:documentation>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="CoordinateSystem" type="CoordinateSystemInfo" />
+        <xs:element name="TransformedCoordinate" type="TransformedCoordinate" minOccurs="0" maxOccurs="unbounded" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:complexType name="CoordinateSystemInfo">
+    <xs:annotation>
+      <xs:documentation>Information about the coordinate system</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="MentorCode" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>Mentor (CS-Map) coordinate system code</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="EpsgCode" type="xs:integer">
+        <xs:annotation>
+          <xs:documentation>EPSG code</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Wkt" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>The well-known text of the coordinate system</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+  <xs:complexType name="TransformedCoordinate">
+    <xs:annotation>
+      <xs:documentation>Represents a transformed coordinate</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="X" type="xs:double" minOccurs="0" maxOccurs="1">
+        <xs:annotation>
+          <xs:documentation>x-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Y" type="xs:double" minOccurs="0" maxOccurs="1">
+        <xs:annotation>
+          <xs:documentation>y-coordinate</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="Error" type="xs:string" minOccurs="0" maxOccurs="1">
+        <xs:annotation>
+          <xs:documentation>The string token that failed to parse into a coordinate pair</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+  </xs:complexType>
+</xs:schema>

Modified: trunk/MgDev/Server/src/Services/Feature/ServerDataReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerDataReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerDataReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -1554,7 +1554,7 @@
         __LINE__, __WFILE__, NULL, L"", NULL);
 }
 
-void MgServerDataReader::CurrentToStringUtf8(string& str)
+void MgServerDataReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     throw new MgInvalidOperationException(L"MgServerDataReader.CurrentToStringUtf8",
         __LINE__, __WFILE__, NULL, L"", NULL);

Modified: trunk/MgDev/Server/src/Services/Feature/ServerDataReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerDataReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerDataReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -514,7 +514,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// <summary>

Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -974,7 +974,7 @@
         __LINE__, __WFILE__, NULL, L"", NULL);
 }
 
-void MgServerFeatureReader::CurrentToStringUtf8(string& str)
+void MgServerFeatureReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     throw new MgInvalidOperationException(L"MgServerFeatureReader.CurrentToStringUtf8",
         __LINE__, __WFILE__, NULL, L"", NULL);

Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -479,7 +479,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// <summary>

Modified: trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -1276,7 +1276,7 @@
         __LINE__, __WFILE__, NULL, L"", NULL);
 }
 
-void MgServerGwsFeatureReader::CurrentToStringUtf8(string& str)
+void MgServerGwsFeatureReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     throw new MgInvalidOperationException(L"MgServerGwsFeatureReader.CurrentToStringUtf8",
         __LINE__, __WFILE__, NULL, L"", NULL);

Modified: trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerGwsFeatureReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -471,7 +471,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// <summary>

Modified: trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -1394,7 +1394,7 @@
         __LINE__, __WFILE__, NULL, L"", NULL);
 }
 
-void MgServerSqlDataReader::CurrentToStringUtf8(string& str)
+void MgServerSqlDataReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
     throw new MgInvalidOperationException(L"MgServerSqlDataReader.CurrentToStringUtf8",
         __LINE__, __WFILE__, NULL, L"", NULL);

Modified: trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSqlDataReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -489,7 +489,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// <summary>

Modified: trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -378,9 +378,9 @@
     m_innerReader->BodyEndUtf8(str);
 }
 
-void MgTransformedGeometryFeatureReader::CurrentToStringUtf8(string& str)
+void MgTransformedGeometryFeatureReader::CurrentToStringUtf8(string& str, MgTransform* xform)
 {
-    m_innerReader->CurrentToStringUtf8(str);
+    m_innerReader->CurrentToStringUtf8(str, xform);
 }
 
 void MgTransformedGeometryFeatureReader::HeaderToStringUtf8(string& str)

Modified: trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/Services/Feature/TransformedGeometryFeatureReader.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -439,7 +439,7 @@
     /// \param str
     /// Destination string.
     ///
-    void CurrentToStringUtf8(string& str);
+    void CurrentToStringUtf8(string& str, MgTransform* xform);
 
     //////////////////////////////////////////////////////////////////
     /// <summary>

Modified: trunk/MgDev/Server/src/UnitTesting/TestMisc.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestMisc.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/UnitTesting/TestMisc.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -715,4 +715,41 @@
     {
         throw;
     }
+}
+
+void TestMisc::TestCase_TryParseDouble()
+{
+    try
+    {
+        double dBad = 0.0;
+        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"", dBad));
+        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"abc", dBad));
+        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"abc123", dBad));
+        CPPUNIT_ASSERT(!MgUtil::TryParseDouble(L"123.asd", dBad));
+        double d1 = 0.0;
+        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"123", d1));
+        CPPUNIT_ASSERT(123 == d1);
+        double d2 = 0.0;
+        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"123.23", d2));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(123.23, d2, 0.001);
+        double d3 = 0.0;
+        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"0.1237483", d3));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1237483, d3, 0.00000001);
+        double d4 = 0.0;
+        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L"123.", d4));
+        CPPUNIT_ASSERT(123 == d4);
+        double d5 = 0.0;
+        CPPUNIT_ASSERT(MgUtil::TryParseDouble(L".1235", d5));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1235, d5, 0.00001);
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
 }
\ No newline at end of file

Modified: trunk/MgDev/Server/src/UnitTesting/TestMisc.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestMisc.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Server/src/UnitTesting/TestMisc.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -32,6 +32,7 @@
     CPPUNIT_TEST(TestCase_MapLayerCollections);
     CPPUNIT_TEST(TestCase_ApiVersionCheck);
     CPPUNIT_TEST(TestCase_DoubleToStringWithDecimals);
+    CPPUNIT_TEST(TestCase_TryParseDouble);
 
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
     CPPUNIT_TEST_SUITE_END();
@@ -53,6 +54,7 @@
     void TestCase_CreateMapWithInitialDisplayParams();
     void TestCase_ApiVersionCheck();
     void TestCase_DoubleToStringWithDecimals();
+    void TestCase_TryParseDouble();
 
 private:
     Ptr<MgSiteConnection> m_siteConnection;

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/coordinatesystemapi.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/coordinatesystemapi.html	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/coordinatesystemapi.html	2017-11-26 22:17:19 UTC (rev 9255)
@@ -29,6 +29,7 @@
 <li><a href="csepsgcodetowktform.html" target="showform">ConvertEpsgCodeToWkt</a>
 <li><a href="csgetbaselibraryform.html" target="showform">GetBaseLibrary</a>
 <li><a href="csisvalidform.html" target="showform">IsValid</a>
+<li><a href="cstransformcoordinatesform.html" target="showform">TransformCoordinates</a>
 </ul>
 </body>
 </html>

Copied: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cstransformcoordinatesform.html (from rev 9254, sandbox/jng/coordsys_mapagent/UnitTest/WebTier/MapAgent/MapAgentForms/cstransformcoordinatesform.html)
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cstransformcoordinatesform.html	                        (rev 0)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/cstransformcoordinatesform.html	2017-11-26 22:17:19 UTC (rev 9255)
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+        <title></title>
+        <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
+        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+        <script type="text/javascript" src="setactiontarget.js">
+        </script>
+    </head>
+    <body>
+        <form name="input" action="" method="get" ID="Form1">
+        <b>Operation:</b>
+        <input type="text" name="OPERATION" value="CS.TRANSFORMCOORDINATES" size="50" ID="Text1">
+        <p> Version:
+        <input type="text" name="VERSION" value="3.3.0" size="10" ID="Text2">
+        <p> Locale:
+        <input type="text" name="LOCALE" value="en" size="10" ID="Text3">
+        <p> Client Agent:
+        <input type="text" name="CLIENTAGENT" value="MapGuide Developer" size="100">
+        <p> Source CS (CS-Map code):
+        <input type="text" name="SOURCE" value="" size="100" ID="Text4">
+        <p> Target CS (CS-Map code):
+        <input type="text" name="TARGET" value="" size="100" ID="Text5">
+        <p> Coordinates (in source CS. Comma-separated list of space-separated coordinate pairs):
+        <input type="text" name="COORDINATES" value="" size="100">
+        <p> Format:
+        <select name="FORMAT">
+        <option value="text/xml">text/xml</option>
+        <option value="application/json">application/json</option>
+        </select>
+        <p> Clean JSON: <input type="text" name="CLEAN" value="0" ID="TextClean">
+        <p>
+        <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
+        </form>
+    </body>
+</html>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectaggregatesform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectaggregatesform.html	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectaggregatesform.html	2017-11-26 22:17:19 UTC (rev 9255)
@@ -39,6 +39,8 @@
                 Clean JSON: <input type="text" name="CLEAN" value="0" ID="TextClean">
             <p> Coordinate Precision (if requesting clean JSON):
                 <input type="text" name="PRECISION" value="7" size="10">
+            <p> Transform to (CS-Map code):
+                <input type="text" name="TRANSFORMTO">
             <p>
         <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
         </form>

Modified: trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectfeaturesform.html
===================================================================
--- trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectfeaturesform.html	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/UnitTest/WebTier/MapAgent/MapAgentForms/selectfeaturesform.html	2017-11-26 22:17:19 UTC (rev 9255)
@@ -39,6 +39,8 @@
                 Clean JSON: <input type="text" name="CLEAN" value="0" ID="TextClean">
             <p> Coordinate Precision (if requesting clean JSON):
                 <input type="text" name="PRECISION" value="7" size="10">
+            <p> Transform to (CS-Map code):
+                <input type="text" name="TRANSFORMTO">
             <p>
             <input type="submit" value="Submit" onclick="SetActionTarget()"> <input type="reset">
         </form>

Copied: trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp (from rev 9254, sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp)
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp	                        (rev 0)
+++ trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -0,0 +1,156 @@
+//
+//  Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "HttpHandler.h"
+#include "HttpCsTransformCoordinates.h"
+
+HTTP_IMPLEMENT_CREATE_OBJECT(MgHttpCsTransformCoordinates)
+
+/// <summary>
+/// Initializes the common parameters and parameters specific to this request.
+/// </summary>
+/// <param name="name">Input
+/// MgHttpRequest
+/// This contains all the parameters of the request.
+/// </param>
+/// <returns>
+/// nothing
+/// </returns>
+MgHttpCsTransformCoordinates::MgHttpCsTransformCoordinates(MgHttpRequest *hRequest)
+{
+    InitializeCommonParameters(hRequest);
+
+    Ptr<MgHttpRequestParam> params = hRequest->GetRequestParam();
+    m_srcCs = params->GetParameterValue(MgHttpResourceStrings::reqCsSource);
+    m_dstCs = params->GetParameterValue(MgHttpResourceStrings::reqCsTarget);
+    m_coordinates = params->GetParameterValue(MgHttpResourceStrings::reqCsCoordinates);
+}
+
+/// <summary>
+/// Executes the specific request.
+/// </summary>
+/// <returns>
+/// MgHttpResponse
+/// This contains the response (including MgHttpResult and StatusCode) from the server.
+/// </returns>
+void MgHttpCsTransformCoordinates::Execute(MgHttpResponse& hResponse)
+{
+    Ptr<MgHttpResult> hResult = hResponse.GetResult();
+
+    MG_HTTP_HANDLER_TRY()
+
+    // Check common parameters
+    ValidateCommonParameters();
+
+    Ptr<MgCoordinateSystemFactory> factory = new MgCoordinateSystemFactory();
+    Ptr<MgCoordinateSystem> source = factory->CreateFromCode(m_srcCs);
+    Ptr<MgCoordinateSystem> target = factory->CreateFromCode(m_dstCs);
+
+    Ptr<MgTransform> xform = factory->GetTransform(source, target);
+    
+    std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
+    xml += "<TransformedCoordinateCollection xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"TransformedCoordinateCollection-3.3.0.xsd\">";
+
+    // Output information about the target coordinate system
+
+    xml += "<CoordinateSystem>";
+    xml += "<MentorCode>";
+    xml += MgUtil::WideCharToMultiByte(target->GetCsCode());
+    xml += "</MentorCode>";
+    xml += "<EpsgCode>";
+    std::string mbEpsg;
+    MgUtil::Int32ToString(target->GetEpsgCode(), mbEpsg);
+    xml += mbEpsg;
+    xml += "</EpsgCode>";
+    xml += "<Wkt>";
+    xml += MgUtil::WideCharToMultiByte(factory->ConvertCoordinateSystemCodeToWkt(m_dstCs));
+    xml += "</Wkt>";
+    xml += "</CoordinateSystem>";
+
+    std::wstringstream wss(m_coordinates);
+    STRING part;
+    while (std::getline(wss, part, L','))
+    {
+        xml += "<TransformedCoordinate>";
+        size_t found = part.find_first_of(L' ');
+        bool bValid = false;
+        if (found != STRING::npos)
+        {
+            STRING sX = part.substr(0, found);
+            STRING sY = part.substr(found);
+
+            double x = 0.0;
+            double y = 0.0;
+
+            if (MgUtil::TryParseDouble(sX, x) && MgUtil::TryParseDouble(sY, y))
+            {
+                Ptr<MgCoordinate> coord = new MgCoordinateXY(x, y);
+                Ptr<MgCoordinate> tx = xform->Transform(coord);
+
+                std::string mbX;
+                std::string mbY;
+                MgUtil::DoubleToString(tx->GetX(), mbX);
+                MgUtil::DoubleToString(tx->GetY(), mbY);
+
+                xml += "<X>";
+                xml += mbX;
+                xml += "</X>";
+
+                xml += "<Y>";
+                xml += mbY;
+                xml += "</Y>";
+                bValid = true;
+            }
+        }
+        
+        if (!bValid)
+        {
+            xml += "<Error>";
+            std::string mbPart;
+            MgUtil::WideCharToMultiByte(part, mbPart);
+            xml += mbPart;
+            xml += "</Error>";
+        }
+        xml += "</TransformedCoordinate>";
+    }
+
+    xml += "</TransformedCoordinateCollection>";
+
+    Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)xml.c_str(), (INT32)xml.length());
+    byteSource->SetMimeType(MgMimeType::Xml);
+    Ptr<MgByteReader> byteReader = byteSource->GetReader();
+
+    ProcessFormatConversion(byteReader);
+
+    hResult->SetResultObject(byteReader, byteReader->GetMimeType());
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW_EX(L"MgHttpCsTransformCoordinates.Execute")
+}
+
+void MgHttpCsTransformCoordinates::ValidateOperationVersion()
+{
+    MG_HTTP_HANDLER_TRY()
+
+    INT32 version = m_userInfo->GetApiVersion();
+    if (version != MG_API_VERSION(3, 3, 0))
+    {
+        throw new MgInvalidOperationVersionException(
+            L"MgHttpCsTransformCoordinates.ValidateOperationVersion", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpCsTransformCoordinates.ValidateOperationVersion");
+}
\ No newline at end of file

Copied: trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.h (from rev 9254, sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/HttpCsTransformCoordinates.h)
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.h	                        (rev 0)
+++ trunk/MgDev/Web/src/HttpHandler/HttpCsTransformCoordinates.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -0,0 +1,54 @@
+//
+//  Copyright (C) 2004-2017 by Autodesk, Inc.
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of version 2.1 of the GNU Lesser
+//  General Public License as published by the Free Software Foundation.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef _CS_TRANSFORM_COORDINATES_H
+#define _CS_TRANSFORM_COORDINATES_H
+
+class MgHttpCsTransformCoordinates : public MgHttpRequestResponseHandler
+{
+    HTTP_DECLARE_CREATE_OBJECT()
+
+public:
+    /// <summary>
+    /// Initializes the common parameters of the request.
+    /// </summary>
+    /// <param name="name">Input
+    /// MgHttpRequest
+    /// This contains all the parameters of the request.
+    /// </param>
+    /// <returns>
+    /// nothing
+    /// </returns>
+    MgHttpCsTransformCoordinates(MgHttpRequest *hRequest);
+
+    /// <summary>
+    /// Executes the specific request.
+    /// </summary>
+    /// <param name="hResponse">Input
+    /// This contains the response (including MgHttpResult and StatusCode) from the server.
+    /// </param>
+    void Execute(MgHttpResponse& hResponse);
+
+    virtual void ValidateOperationVersion();
+
+private:
+    STRING m_srcCs;
+    STRING m_dstCs;
+    STRING m_coordinates;
+};
+
+#endif  // _CS_TRANSFORM_COORDINATES_H

Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj	2017-11-26 22:17:19 UTC (rev 9255)
@@ -210,6 +210,12 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="HttpCsTransformCoordinates.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="HttpGeoBoundary.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -999,6 +1005,7 @@
   <ItemGroup>
     <ClInclude Include="HttpApplyResourcePackage.h" />
     <ClInclude Include="HttpChangeResourceOwner.h" />
+    <ClInclude Include="HttpCsTransformCoordinates.h" />
     <ClInclude Include="HttpGeoBoundary.h" />
     <ClInclude Include="HttpGeoConvexHull.h" />
     <ClInclude Include="HttpCopyResource.h" />

Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandler.vcxproj.filters	2017-11-26 22:17:19 UTC (rev 9255)
@@ -416,6 +416,9 @@
     <ClCompile Include="HttpGeoBoundary.cpp">
       <Filter>GeoProcessing</Filter>
     </ClCompile>
+    <ClCompile Include="HttpCsTransformCoordinates.cpp">
+      <Filter>Coordinate System</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="HttpApplyResourcePackage.h">
@@ -814,6 +817,9 @@
     <ClInclude Include="HttpGeoBoundary.h">
       <Filter>GeoProcessing</Filter>
     </ClInclude>
+    <ClInclude Include="HttpCsTransformCoordinates.h">
+      <Filter>Coordinate System</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="HttpHandler.rc" />

Modified: trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpHandlerBuild.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -36,6 +36,7 @@
 #include "HttpCsEnumerateCoordinateSystems.cpp"
 #include "HttpCsGetBaseLibrary.cpp"
 #include "HttpCsIsValid.cpp"
+#include "HttpCsTransformCoordinates.cpp"
 #include "HttpDeleteRepository.cpp"
 #include "HttpDeleteResource.cpp"
 #include "HttpDeleteResourceData.cpp"

Modified: trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpRequest.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -123,6 +123,7 @@
 #include "HttpCsEnumerateCoordinateSystems.h"
 #include "HttpCsGetBaseLibrary.h"
 #include "HttpCsIsValid.h"
+#include "HttpCsTransformCoordinates.h"
 
 // Geo-Processing
 #include "HttpGeoBoundary.h"
@@ -435,6 +436,7 @@
     httpClassCreators[MgHttpResourceStrings::opCsEnumerateCoordinateSystems] = MgHttpCsEnumerateCoordinateSystems::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opCsGetBaseLibrary] = MgHttpCsGetBaseLibrary::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opCsIsValid] = MgHttpCsIsValid::CreateObject;
+    httpClassCreators[MgHttpResourceStrings::opCsTransformCoordinates] = MgHttpCsTransformCoordinates::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opEnumerateUnmanagedData] = MgHttpEnumerateUnmanagedData::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opGetFdoCacheInfo] = MgHttpGetFdoCacheInfo::CreateObject;
     httpClassCreators[MgHttpResourceStrings::opEnumerateApplicationTemplates] = MgHttpEnumerateApplicationTemplates::CreateObject;

Modified: trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -358,6 +358,7 @@
 const STRING MgHttpResourceStrings::opCsEnumerateCoordinateSystems = L"CS.ENUMERATECOORDINATESYSTEMS";
 const STRING MgHttpResourceStrings::opCsGetBaseLibrary = L"CS.GETBASELIBRARY";
 const STRING MgHttpResourceStrings::opCsIsValid = L"CS.ISVALID";
+const STRING MgHttpResourceStrings::opCsTransformCoordinates = L"CS.TRANSFORMCOORDINATES";
 
 // Web Application Operations
 const STRING MgHttpResourceStrings::opEnumerateApplicationTemplates = L"ENUMERATEAPPLICATIONTEMPLATES";
@@ -391,6 +392,9 @@
 const STRING MgHttpResourceStrings::reqCsWkt = L"CSWKT";
 const STRING MgHttpResourceStrings::reqCsCode = L"CSCODE";
 const STRING MgHttpResourceStrings::reqCsCategory = L"CSCATEGORY";
+const STRING MgHttpResourceStrings::reqCsSource = L"SOURCE";
+const STRING MgHttpResourceStrings::reqCsTarget = L"TARGET";
+const STRING MgHttpResourceStrings::reqCsCoordinates = L"COORDINATES";
 
 // Predefined Site Service Request Parameters
 const STRING MgHttpResourceStrings::reqGroup = L"GROUP";

Modified: trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpResourceStrings.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -362,6 +362,7 @@
     static const STRING opCsEnumerateCoordinateSystems;
     static const STRING opCsGetBaseLibrary;
     static const STRING opCsIsValid;
+    static const STRING opCsTransformCoordinates;
 
     // Web Applications Operations
     static const STRING opEnumerateApplicationTemplates;
@@ -395,6 +396,9 @@
     static const STRING reqCsWkt;
     static const STRING reqCsCode;
     static const STRING reqCsCategory;
+    static const STRING reqCsSource;
+    static const STRING reqCsTarget;
+    static const STRING reqCsCoordinates;
 
     // PREDEFINED SITE REQUEST PARAMETERS
     static const STRING reqGroup;

Modified: trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -55,6 +55,11 @@
             m_bEnablePrecision = true;
         }
     }
+    // Get transform flag (TRANSFORMTO). Only recognize this flag for 3.3.0 and above
+    if (m_userInfo->GetApiVersion() >= MG_API_VERSION(3, 3, 0))
+    {
+        m_transformTo = params->GetParameterValue(MgHttpResourceStrings::reqGeoTransformTo);
+    }
 }
 
 /// <summary>
@@ -123,8 +128,17 @@
 
     Ptr<MgFeatureReader> featureReader = service->SelectFeatures(&resId, m_className, qryOptions);
     //MgByteSource owns this and will clean it up when done
-    ByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(featureReader, m_responseFormat, m_bCleanJson, m_bEnablePrecision, m_precision);
+    Ptr<MgTransform> xform;
+    if (!m_transformTo.empty())
+    {
+        STRING schemaName;
+        STRING className;
+        MgUtil::ParseQualifiedClassName(m_className, schemaName, className);
 
+        xform = MgHttpUtil::GetTransform(service, &resId, schemaName, className, m_transformTo);
+    }
+    ByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(featureReader, m_responseFormat, m_bCleanJson, m_bEnablePrecision, m_precision, xform);
+
     Ptr<MgByteSource> byteSource = new MgByteSource(bsImpl);
     byteSource->SetMimeType(m_responseFormat);
     Ptr<MgByteReader> byteReader = byteSource->GetReader();

Modified: trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpSelectFeatures.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -48,6 +48,7 @@
     STRING  m_className;
     INT32   m_precision;
     bool    m_bEnablePrecision;
+    STRING  m_transformTo;
 };
 
 #endif  // _FS_SELECT_FEATURES_H

Modified: trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -65,6 +65,12 @@
             m_bEnablePrecision = true;
         }
     }
+
+    // Get transform flag (TRANSFORMTO). Only recognize this flag for 3.3.0 and above
+    if (m_userInfo->GetApiVersion() >= MG_API_VERSION(3, 3, 0))
+    {
+        m_transformTo = params->GetParameterValue(MgHttpResourceStrings::reqGeoTransformTo);
+    }
 }
 
 /// <summary>
@@ -133,8 +139,17 @@
 
     Ptr<MgDataReader> dataReader = service->SelectAggregate(&resId, m_className, qryOptions);
     //MgByteSource owns this and will clean it up when done
-    ByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(dataReader, m_responseFormat, m_bCleanJson, m_bEnablePrecision, m_precision);
+    Ptr<MgTransform> xform;
+    if (!m_transformTo.empty())
+    {
+        STRING schemaName;
+        STRING className;
+        MgUtil::ParseQualifiedClassName(m_className, schemaName, className);
 
+        xform = MgHttpUtil::GetTransform(service, &resId, schemaName, className, m_transformTo);
+    }
+    ByteSourceImpl* bsImpl = new MgReaderByteSourceImpl(dataReader, m_responseFormat, m_bCleanJson, m_bEnablePrecision, m_precision, xform);
+
     Ptr<MgByteSource> byteSource = new MgByteSource(bsImpl);
     byteSource->SetMimeType(m_responseFormat);
     Ptr<MgByteReader> byteReader = byteSource->GetReader();

Modified: trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpSelectFeaturesSpatially.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -51,6 +51,7 @@
     INT32   m_operation;
     INT32   m_precision;
     bool    m_bEnablePrecision;
+    STRING  m_transformTo;
 };
 
 #endif  // _FS_SELECT_FEATURES_SPATIALLY_H

Modified: trunk/MgDev/Web/src/HttpHandler/HttpUtil.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpUtil.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpUtil.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -86,3 +86,48 @@
         }
     }
 }
+
+MgTransform* MgHttpUtil::GetTransform(MgFeatureService* featSvc, MgResourceIdentifier* resId, CREFSTRING schemaName, CREFSTRING className, CREFSTRING transformTo)
+{
+    Ptr<MgTransform> transform;
+
+    MG_HTTP_HANDLER_TRY()
+
+    Ptr<MgCoordinateSystemFactory> factory = new MgCoordinateSystemFactory();
+    STRING targetWkt = factory->ConvertCoordinateSystemCodeToWkt(transformTo);
+    Ptr<MgClassDefinition> clsDef = featSvc->GetClassDefinition(resId, schemaName, className);
+    //Has a designated geometry property, use it's spatial context
+    if (!clsDef->GetDefaultGeometryPropertyName().empty())
+    {
+        Ptr<MgPropertyDefinitionCollection> props = clsDef->GetProperties();
+        INT32 idx = props->IndexOf(clsDef->GetDefaultGeometryPropertyName());
+        if (idx >= 0) 
+        {
+            Ptr<MgPropertyDefinition> pd = props->GetItem(idx);
+            if (pd->GetPropertyType() == MgFeaturePropertyType::GeometricProperty)
+            {
+                MgGeometricPropertyDefinition* geomProp = static_cast<MgGeometricPropertyDefinition*>(pd.p);
+                STRING scName = geomProp->GetSpatialContextAssociation();
+                Ptr<MgSpatialContextReader> scReader = featSvc->GetSpatialContexts(resId, false);
+                while (scReader->ReadNext()) 
+                {
+                    if (scReader->GetName() == scName) 
+                    {
+                        if (scReader->GetCoordinateSystemWkt() != targetWkt) 
+                        {
+                            Ptr<MgCoordinateSystem> targetCs = factory->CreateFromCode(transformTo);
+                            Ptr<MgCoordinateSystem> sourceCs = factory->Create(scReader->GetCoordinateSystemWkt());
+                            transform = factory->GetTransform(sourceCs, targetCs);
+                            break;
+                        }
+                    }
+                }
+                scReader->Close();
+            }
+        }
+    }
+
+    MG_HTTP_HANDLER_CATCH_AND_THROW(L"MgHttpUtil::GetTransform")
+
+    return transform.Detach();
+}
\ No newline at end of file

Modified: trunk/MgDev/Web/src/HttpHandler/HttpUtil.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/HttpUtil.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/HttpUtil.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -73,6 +73,8 @@
     ~MgHttpUtil();
 
     static void LogException(MgException* exception);
+
+    static MgTransform* GetTransform(MgFeatureService* featSvc, MgResourceIdentifier* resId, CREFSTRING schemaName, CREFSTRING className, CREFSTRING transformTo);
 };
 
 #endif

Modified: trunk/MgDev/Web/src/HttpHandler/Makefile.am
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/Makefile.am	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/Makefile.am	2017-11-26 22:17:19 UTC (rev 9255)
@@ -34,6 +34,7 @@
   HttpCsEnumerateCoordinateSystems.cpp \
   HttpCsGetBaseLibrary.cpp \
   HttpCsIsValid.cpp \
+  HttpCsTransformCoordinates.cpp \
   HttpDeleteRepository.cpp \
   HttpDeleteResource.cpp \
   HttpDeleteResourceData.cpp \
@@ -168,6 +169,7 @@
   HttpCsEnumerateCoordinateSystems.h \
   HttpCsGetBaseLibrary.h \
   HttpCsIsValid.h \
+  HttpCsTransformCoordinates.h \
   HttpDeleteRepository.h \
   HttpDeleteResource.h \
   HttpDeleteResourceData.h \

Modified: trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -17,7 +17,7 @@
 #include "ReaderByteSourceImpl.h"
 #include "PlatformBase.h"
 
-MgReaderByteSourceImpl::MgReaderByteSourceImpl(MgReader* reader, CREFSTRING format, bool bCleanJson, bool bEnablePrecision, INT32 precision)
+MgReaderByteSourceImpl::MgReaderByteSourceImpl(MgReader* reader, CREFSTRING format, bool bCleanJson, bool bEnablePrecision, INT32 precision, MgTransform* xform)
 {
     m_reader = SAFE_ADDREF(reader);
     m_format = format;
@@ -29,6 +29,7 @@
     m_bCleanJson = bCleanJson;
     m_bEnablePrecision = bEnablePrecision;
     m_precision = precision;
+    m_xform = SAFE_ADDREF(xform);
 }
 
 MgReaderByteSourceImpl::~MgReaderByteSourceImpl()
@@ -38,6 +39,7 @@
     m_reader->Close();
     MG_CATCH_AND_RELEASE()
     m_reader = NULL;
+    m_xform = NULL;
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -175,11 +177,11 @@
                     if (m_reader->GetReaderType() == MgReaderType::FeatureReader)
                     {
                         MgFeatureReader* fr = static_cast<MgFeatureReader*>(m_reader.p);
-                        sGeoJson = geoJsonWriter.FeatureToGeoJson(fr, NULL);
+                        sGeoJson = geoJsonWriter.FeatureToGeoJson(fr, m_xform);
                     }
                     else 
                     {
-                        sGeoJson = geoJsonWriter.FeatureToGeoJson(m_reader, NULL, L"", L"");
+                        sGeoJson = geoJsonWriter.FeatureToGeoJson(m_reader, m_xform, L"", L"");
                     }
 
                     if (!m_bFirstRecord)
@@ -194,7 +196,7 @@
                 }
                 else
                 {
-                    m_reader->CurrentToStringUtf8(buf);
+                    m_reader->CurrentToStringUtf8(buf, m_xform);
                     //The body is a valid full XML element, so no need for gymnastics like its
                     //surrounding elements
                     MgXmlJsonConvert convert;
@@ -230,7 +232,7 @@
 #ifdef _DEBUG
                 m_buf += "<!-- BEGIN RECORD -->\n";
 #endif
-                m_reader->CurrentToStringUtf8(m_buf);
+                m_reader->CurrentToStringUtf8(m_buf, m_xform);
 #ifdef _DEBUG
                 m_buf += "<!-- END RECORD -->\n";
 #endif

Modified: trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/ReaderByteSourceImpl.h	2017-11-26 22:17:19 UTC (rev 9255)
@@ -29,7 +29,7 @@
     DECLARE_CLASSNAME(MgReaderByteSourceImpl)
 
 public:
-    MgReaderByteSourceImpl(MgReader* reader, CREFSTRING format, bool bCleanJson, bool bEnablePrecision, INT32 precision);
+    MgReaderByteSourceImpl(MgReader* reader, CREFSTRING format, bool bCleanJson, bool bEnablePrecision, INT32 precision, MgTransform* xform);
     virtual ~MgReaderByteSourceImpl();
 
     ///////////////////////////////////////////////////////////////////////////
@@ -84,6 +84,7 @@
     INT32 ReadInternalBuffer(BYTE_ARRAY_OUT buffer, INT32 fromIndex, INT32 length);
 
     Ptr<MgReader> m_reader;
+	Ptr<MgTransform> m_xform;
     STRING m_format;
     bool m_bCleanJson;
     bool m_bReadHeader;

Modified: trunk/MgDev/Web/src/HttpHandler/XmlJsonConvert.cpp
===================================================================
--- trunk/MgDev/Web/src/HttpHandler/XmlJsonConvert.cpp	2017-11-17 06:00:39 UTC (rev 9254)
+++ trunk/MgDev/Web/src/HttpHandler/XmlJsonConvert.cpp	2017-11-26 22:17:19 UTC (rev 9255)
@@ -960,6 +960,10 @@
     s_elementPathTypeMap["/GeometryInfo/Envelope/UpperRight/Y"] = XML_DATA_TYPE_NUM_DOUBLE;
     s_elementPathTypeMap["/GeometryInfo/Centroid/X"] = XML_DATA_TYPE_NUM_DOUBLE;
     s_elementPathTypeMap["/GeometryInfo/Centroid/Y"] = XML_DATA_TYPE_NUM_DOUBLE;
+    //TransformedCoordinateCollection-3.3.0.xsd
+    s_elementPathTypeMap["/TransformedCoordinateCollection/CoordinateSystem/EpsgCode"] = XML_DATA_TYPE_NUM_INT;
+    s_elementPathTypeMap["/TransformedCoordinateCollection/TransformedCoordinate/X"] = XML_DATA_TYPE_NUM_DOUBLE;
+    s_elementPathTypeMap["/TransformedCoordinateCollection/TransformedCoordinate/Y"] = XML_DATA_TYPE_NUM_DOUBLE;
     //Miscellaneous MapGuide response types that don't have a formal schema
     s_elementPathTypeMap["/SessionTimeout/Value"] = XML_DATA_TYPE_NUM_INT;
     s_elementPathTypeMap["/FeatureInformation/SelectedFeatures/SelectedLayer/LayerMetadata/Property/Type"] = XML_DATA_TYPE_NUM_INT;
@@ -1146,6 +1150,8 @@
     //UserList-1.0.0.xsd
     s_multiElementPaths.insert("/UserList/User");
     s_multiElementPaths.insert("/UserList/Group");
+    //TransformedCoordinateCollection-3.3.0.xsd
+    s_multiElementPaths.insert("/TransformedCoordinateCollection/TransformedCoordinate");
     //Miscellaneous MapGuide response types that don't have a formal schema
     s_multiElementPaths.insert("/FeatureInformation/FeatureSet/Layer");
     s_multiElementPaths.insert("/FeatureInformation/FeatureSet/Layer/Class/ID");



More information about the mapguide-commits mailing list