[mapguide-commits] r9238 - in sandbox/jng/coordsys_mapagent: Common/Foundation/System Common/Schema Server/src/UnitTesting Web/src/HttpHandler

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Sep 19 07:27:03 PDT 2017


Author: jng
Date: 2017-09-19 07:27:03 -0700 (Tue, 19 Sep 2017)
New Revision: 9238

Added:
   sandbox/jng/coordsys_mapagent/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd
Removed:
   sandbox/jng/coordsys_mapagent/Common/Schema/CoordinateCollection-3.3.0.xsd
Modified:
   sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.cpp
   sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.h
   sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.cpp
   sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.h
   sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp
   sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/XmlJsonConvert.cpp
Log:
- Add MgUtil::TryParseDouble to attempt parsing a string to a double.
  - Add unit tests to exercise this method
- Update the CS.TRANSFORMCOORDINATES operation to:
  - Output tokens that fail to parse into coordinate pairs (via the new MgUtil::TryParseDouble() method) into <Error> elements
- Rename CoordinateCollection-3.3.0.xsd to TransformedCoordinateCollection-3.3.0.xsd
  - Include coordinate system information in the schema

Modified: sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.cpp
===================================================================
--- sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.cpp	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.cpp	2017-09-19 14:27:03 UTC (rev 9238)
@@ -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: sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.h
===================================================================
--- sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.h	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Common/Foundation/System/Util.h	2017-09-19 14:27:03 UTC (rev 9238)
@@ -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:
 
     ///////////////////////////////////////////////////////////////////////////

Deleted: sandbox/jng/coordsys_mapagent/Common/Schema/CoordinateCollection-3.3.0.xsd
===================================================================
--- sandbox/jng/coordsys_mapagent/Common/Schema/CoordinateCollection-3.3.0.xsd	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Common/Schema/CoordinateCollection-3.3.0.xsd	2017-09-19 14:27:03 UTC (rev 9238)
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
-  <xs:element name="CoordinateCollection">
-    <xs:annotation>
-      <xs:documentation>A collection of transformed coordinates</xs:documentation>
-    </xs:annotation>
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element name="Coordinate" type="Coordinate" minOccurs="0" maxOccurs="unbounded" />
-      </xs:sequence>
-    </xs:complexType>
-  </xs:element>
-  <xs:complexType name="Coordinate">
-    <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>

Copied: sandbox/jng/coordsys_mapagent/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd (from rev 9237, sandbox/jng/coordsys_mapagent/Common/Schema/CoordinateCollection-3.3.0.xsd)
===================================================================
--- sandbox/jng/coordsys_mapagent/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd	                        (rev 0)
+++ sandbox/jng/coordsys_mapagent/Common/Schema/TransformedCoordinateCollection-3.3.0.xsd	2017-09-19 14:27:03 UTC (rev 9238)
@@ -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: sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.cpp
===================================================================
--- sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.cpp	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.cpp	2017-09-19 14:27:03 UTC (rev 9238)
@@ -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: sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.h
===================================================================
--- sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.h	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Server/src/UnitTesting/TestMisc.h	2017-09-19 14:27:03 UTC (rev 9238)
@@ -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: sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp
===================================================================
--- sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/HttpCsTransformCoordinates.cpp	2017-09-19 14:27:03 UTC (rev 9238)
@@ -63,39 +63,61 @@
     Ptr<MgTransform> xform = factory->GetTransform(source, target);
     
     std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
-    xml += "<CoordinateCollection xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"CoordinateCollection-3.3.0.xsd\">";
+    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 += "<Coordinate>";
+        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 = MgUtil::StringToDouble(sX);
-            double y = MgUtil::StringToDouble(sY);
+            double x = 0.0;
+            double y = 0.0;
 
-            Ptr<MgCoordinate> coord = new MgCoordinateXY(x, y);
-            Ptr<MgCoordinate> tx = xform->Transform(coord);
+            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>";
+                std::string mbX;
+                std::string mbY;
+                MgUtil::DoubleToString(tx->GetX(), mbX);
+                MgUtil::DoubleToString(tx->GetY(), mbY);
 
-            xml += "<Y>";
-            xml += mbY;
-            xml += "</Y>";
+                xml += "<X>";
+                xml += mbX;
+                xml += "</X>";
+
+                xml += "<Y>";
+                xml += mbY;
+                xml += "</Y>";
+                bValid = true;
+            }
         }
-        else 
+        
+        if (!bValid)
         {
             xml += "<Error>";
             std::string mbPart;
@@ -103,10 +125,10 @@
             xml += mbPart;
             xml += "</Error>";
         }
-        xml += "</Coordinate>";
+        xml += "</TransformedCoordinate>";
     }
 
-    xml += "</CoordinateCollection>";
+    xml += "</TransformedCoordinateCollection>";
 
     Ptr<MgByteSource> byteSource = new MgByteSource((BYTE_ARRAY_IN)xml.c_str(), (INT32)xml.length());
     byteSource->SetMimeType(MgMimeType::Xml);

Modified: sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/XmlJsonConvert.cpp
===================================================================
--- sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/XmlJsonConvert.cpp	2017-09-19 12:33:52 UTC (rev 9237)
+++ sandbox/jng/coordsys_mapagent/Web/src/HttpHandler/XmlJsonConvert.cpp	2017-09-19 14:27:03 UTC (rev 9238)
@@ -960,11 +960,13 @@
     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;
-    s_elementPathTypeMap["/CoordinateCollection/Coordinate/X"] = XML_DATA_TYPE_NUM_DOUBLE;
-    s_elementPathTypeMap["/CoordinateCollection/Coordinate/Y"] = XML_DATA_TYPE_NUM_DOUBLE;
 
     // ====================================================================================================================
     // Element paths below basically correspond to XML Schema elements that have minOccurs="1|0" and maxOccurs="unbounded"
@@ -1148,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");
@@ -1155,7 +1159,6 @@
     s_multiElementPaths.insert("/FeatureInformation/SelectedFeatures/SelectedLayer/LayerMetadata/Property");
     s_multiElementPaths.insert("/FeatureInformation/SelectedFeatures/SelectedLayer/Feature");
     s_multiElementPaths.insert("/FeatureInformation/SelectedFeatures/SelectedLayer/Feature/Property");
-    s_multiElementPaths.insert("/CoordinateCollection/Coordinate");
 
     return true;
 }
\ No newline at end of file



More information about the mapguide-commits mailing list