[mapguide-commits] r9538 - sandbox/jng/mvt/Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Jun 5 03:48:18 PDT 2019


Author: jng
Date: 2019-06-05 03:48:18 -0700 (Wed, 05 Jun 2019)
New Revision: 9538

Modified:
   sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp
   sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.h
   sandbox/jng/mvt/Server/src/UnitTesting/UnitTesting.vcxproj
Log:
Copy the vtzero-check exammple code to validate the MVT tiles rendered by RenderTileMVT(). The test is currently failing, which is an obvious indication that we're not rendering valid MVT tiles at the moment (vtzero not throwing when we're encoding doesn't help).

Modified: sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp
===================================================================
--- sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp	2019-06-05 10:45:26 UTC (rev 9537)
+++ sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp	2019-06-05 10:48:18 UTC (rev 9538)
@@ -27,6 +27,7 @@
 #include "SE_Renderer.h"
 #include "MVTRenderer.h"
 #include "RS_FeatureReader.h"
+#include <vtzero/vector_tile.hpp>
 
 const STRING TEST_LOCALE = L"en";
 
@@ -1950,6 +1951,157 @@
     int m_limit;
 };
 
+class MVTValidationResult {
+
+    int m_return_code = 0;
+
+public:
+
+    void has_warning() noexcept {
+        if (m_return_code < 1) {
+            m_return_code = 1;
+        }
+    }
+
+    void has_error() noexcept {
+        if (m_return_code < 2) {
+            m_return_code = 2;
+        }
+    }
+
+    void has_fatal_error() noexcept {
+        if (m_return_code < 3) {
+            m_return_code = 3;
+        }
+    }
+
+    int return_code() const noexcept {
+        return m_return_code;
+    }
+};
+
+class CheckGeomHandler 
+{
+    MVTValidationResult result;
+    vtzero::point m_prev_point{};
+    int m_layer_num;
+    int m_feature_num;
+    int64_t m_extent;
+    bool m_is_first_point = false;
+    int m_count = 0;
+
+    void print_context() const {
+        std::cerr << " in layer " << m_layer_num
+            << " in feature " << m_feature_num
+            << " in geometry " << m_count
+            << ": ";
+    }
+
+    void print_error(const char* message) {
+        result.has_error();
+        std::cerr << "Error";
+        print_context();
+        std::cerr << message << '\n';
+    }
+
+    void print_warning(const char* message) {
+        result.has_warning();
+        std::cerr << "Warning";
+        print_context();
+        std::cerr << message << '\n';
+    }
+
+    void check_point_location(const vtzero::point point) {
+        if (point.x < -m_extent ||
+            point.y < -m_extent ||
+            point.x > 2 * m_extent ||
+            point.y > 2 * m_extent) {
+            print_warning("point waaaay beyond the extent");
+        }
+    }
+
+public:
+
+    CheckGeomHandler(uint32_t extent, int layer_num, int feature_num) :
+        m_layer_num(layer_num),
+        m_feature_num(feature_num),
+        m_extent(static_cast<int64_t>(extent)) {
+    }
+
+    // ----------------------------------------------------------------------
+
+    void points_begin(const uint32_t /*count*/) {
+    }
+
+    void points_point(const vtzero::point point) {
+        check_point_location(point);
+    }
+
+    void points_end() const {
+    }
+
+    // ----------------------------------------------------------------------
+
+    void linestring_begin(const uint32_t count) {
+        if (count < 2) {
+            print_error("Not enough points in linestring");
+        }
+        m_is_first_point = true;
+    }
+
+    void linestring_point(const vtzero::point point) {
+        if (m_is_first_point) {
+            m_is_first_point = false;
+        }
+        else {
+            if (point == m_prev_point) {
+                print_error("Duplicate point in linestring");
+            }
+        }
+        m_prev_point = point;
+
+        check_point_location(point);
+    }
+
+    void linestring_end() {
+        ++m_count;
+    }
+
+    // ----------------------------------------------------------------------
+
+    void ring_begin(const uint32_t count) {
+        if (count < 4) {
+            print_error("Not enough points in ring");
+        }
+        m_is_first_point = true;
+    }
+
+    void ring_point(const vtzero::point point) {
+        if (m_is_first_point) {
+            m_is_first_point = false;
+        }
+        else {
+            if (point == m_prev_point) {
+                print_error("Duplicate point in ring");
+            }
+        }
+        m_prev_point = point;
+
+        check_point_location(point);
+    }
+
+    void ring_end(const vtzero::ring_type rt) {
+        if (rt == vtzero::ring_type::invalid) {
+            print_error("Invalid ring with area 0");
+        }
+        if (m_count == 0 && rt != vtzero::ring_type::outer) {
+            print_error("First ring isn't an outer ring");
+        }
+        ++m_count;
+    }
+
+};
+
 void TestRenderingService::TestCase_MVTRenderer()
 {
     MVTRenderer ren;
@@ -2016,6 +2168,36 @@
         mvtTR->ToFile(L"../UnitTestFiles/RenderTileMVT_TR.mvt");
         mvtBL->ToFile(L"../UnitTestFiles/RenderTileMVT_BL.mvt");
         mvtBR->ToFile(L"../UnitTestFiles/RenderTileMVT_UR.mvt");
+
+        mvtTL->Rewind();
+        mvtTR->Rewind();
+        mvtBL->Rewind();
+        mvtBR->Rewind();
+
+        Ptr<MgByteSink> sinkTL = new MgByteSink(mvtTL);
+        Ptr<MgByteSink> sinkTR = new MgByteSink(mvtTR);
+        Ptr<MgByteSink> sinkBL = new MgByteSink(mvtBL);
+        Ptr<MgByteSink> sinkBR = new MgByteSink(mvtBR);
+
+        std::string dataTL;
+        std::string dataTR;
+        std::string dataBL;
+        std::string dataBR;
+
+        sinkTL->ToStringUtf8(dataTL);
+        sinkTR->ToStringUtf8(dataTR);
+        sinkBL->ToStringUtf8(dataBL);
+        sinkBR->ToStringUtf8(dataBR);
+
+        vtzero::vector_tile vtTL(dataTL);
+        vtzero::vector_tile vtTR(dataTR);
+        vtzero::vector_tile vtBL(dataBL);
+        vtzero::vector_tile vtBR(dataBR);
+
+        ValidateVectorTile(&vtTL);
+        ValidateVectorTile(&vtTR);
+        ValidateVectorTile(&vtBL);
+        ValidateVectorTile(&vtBR);
     }
     catch (MgException* e)
     {
@@ -2025,6 +2207,58 @@
     }
 }
 
+void TestRenderingService::ValidateVectorTile(vtzero::vector_tile* tile)
+{
+    std::set<std::string> layer_names;
+    MVTValidationResult result;
+
+    int layer_num = 0;
+    int feature_num = -1;
+    try {
+        while (auto layer = tile->next_layer()) {
+            if (layer.name().empty()) {
+                std::cerr << "Error in layer " << layer_num << ": name is empty (spec 4.1)\n";
+                result.has_error();
+            }
+
+            std::string name(layer.name());
+            if (layer_names.count(name) > 0) {
+                std::cerr << "Error in layer " << layer_num << ": name is duplicate of previous layer ('" << name << "') (spec 4.1)\n";
+                result.has_error();
+            }
+
+            layer_names.insert(name);
+
+            feature_num = 0;
+            while (auto feature = layer.next_feature()) {
+                CheckGeomHandler handler{ layer.extent(), layer_num, feature_num };
+                vtzero::decode_geometry(feature.geometry(), handler);
+                ++feature_num;
+            }
+            if (feature_num == 0) {
+                std::cerr << "Warning: No features in layer " << layer_num << " (spec 4.1)\n";
+                result.has_warning();
+            }
+            feature_num = -1;
+            ++layer_num;
+        }
+        if (layer_num == 0) {
+            std::cerr << "Warning: No layers in vector tile (spec 4.1)\n";
+            result.has_warning();
+        }
+    }
+    catch (const std::exception& e) {
+        std::cerr << "Fatal error in layer " << layer_num;
+        if (feature_num >= 0) {
+            std::cerr << " in feature " << feature_num;
+        }
+        std::cerr << ": " << e.what() << '\n';
+        result.has_fatal_error();
+    }
+
+    CPPUNIT_ASSERT(result.return_code() == 0);
+}
+
 STRING TestRenderingService::GetPath(CREFSTRING basePath, CREFSTRING imageFormat, CREFSTRING extension)
 {
     STRING ret;

Modified: sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.h
===================================================================
--- sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.h	2019-06-05 10:45:26 UTC (rev 9537)
+++ sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.h	2019-06-05 10:48:18 UTC (rev 9538)
@@ -20,6 +20,11 @@
 
 #include <cppunit/extensions/HelperMacros.h>
 
+namespace vtzero
+{
+    class vector_tile;
+}
+
 class TestRenderingService : public CppUnit::TestFixture
 {
     CPPUNIT_TEST_SUITE(TestRenderingService);
@@ -328,6 +333,7 @@
     void TestCase_RenderXYZMetatileGIF() { TestCase_RenderXYZMetatile(L"GIF", L"gif"); }
 
 private:
+    void ValidateVectorTile(vtzero::vector_tile* tile);
     MgMap* CreateTestMap();
     MgMap* CreateTestTiledMap();
     MgMap* CreateTestXYZMap();

Modified: sandbox/jng/mvt/Server/src/UnitTesting/UnitTesting.vcxproj
===================================================================
--- sandbox/jng/mvt/Server/src/UnitTesting/UnitTesting.vcxproj	2019-06-05 10:45:26 UTC (rev 9537)
+++ sandbox/jng/mvt/Server/src/UnitTesting/UnitTesting.vcxproj	2019-06-05 10:48:18 UTC (rev 9538)
@@ -94,7 +94,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;..\..\..\Oem\protozero-1.6.7\Include;..\..\..\Oem\vtzero-1.0.3\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -120,7 +120,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;..\..\..\Oem\protozero-1.6.7\Include;..\..\..\Oem\vtzero-1.0.3\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -146,7 +146,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;..\..\..\Oem\protozero-1.6.7\Include;..\..\..\Oem\vtzero-1.0.3\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -173,7 +173,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\Common;..\Common\Cache;..\Common\Manager;..\Services\Feature;..\Services\Kml;..\Services\Mapping;..\Services\Rendering;..\Services\Resource;..\Services\ServerAdmin;..\Services\Site;..\Services\Tile;..\..\..\Common\Foundation;..\..\..\Common\Geometry;..\..\..\Common\PlatformBase;..\..\..\Common\MapGuideCommon;..\..\..\Common\MdfModel;..\..\..\Common\MdfParser;..\..\..\Common\Renderers;..\..\..\Common\Stylization;..\..\..\Oem\ACE\ACE_wrappers;..\..\..\Oem\CppUnit-1.9.14\include;..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\Oem\FDO\inc;..\..\..\Oem\protozero-1.6.7\Include;..\..\..\Oem\vtzero-1.0.3\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>



More information about the mapguide-commits mailing list