[mapguide-commits] r9547 - in sandbox/jng/mvt: Common/Renderers Common/Stylization Server/src/Services/Mapping Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Jun 12 09:25:24 PDT 2019


Author: jng
Date: 2019-06-12 09:25:24 -0700 (Wed, 12 Jun 2019)
New Revision: 9547

Modified:
   sandbox/jng/mvt/Common/Renderers/MVTRenderer.cpp
   sandbox/jng/mvt/Common/Renderers/MVTRenderer.h
   sandbox/jng/mvt/Common/Stylization/DefaultStylizer.cpp
   sandbox/jng/mvt/Common/Stylization/RS_FeatureReader.h
   sandbox/jng/mvt/Common/Stylization/Renderer.h
   sandbox/jng/mvt/Common/Stylization/RendererStyles.h
   sandbox/jng/mvt/Common/Stylization/SE_Renderer.cpp
   sandbox/jng/mvt/Common/Stylization/SE_Renderer.h
   sandbox/jng/mvt/Common/Stylization/StylizationEngine.cpp
   sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.cpp
   sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.h
   sandbox/jng/mvt/Server/src/Services/Mapping/ServerMappingService.vcxproj
   sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp
Log:
As I had suspected and feared, ring orientation is important when rendering mapbox vector tiles, so we have to entertain the real possibility that incorrectly oriented polygons could be fed to our MVTRenderer.

Fortunately, FDO has some code in FdoSpatialUtility to help us correct polygons to the right orientation, but this requires some interface changes in the rendering/stylization engine first:

 - Add a new RS_DesiredPolygonOrientation enum that a renderer implementation returns to specify the desired orientation of polygons passed to it. By default it returns RS_DesiredPolygonOrientation::NotApplicable, but for the MVTRenderer, it returns RS_DesiredPolygonOrientation::Clockwise
 - Modify RS_FeatureReader::GetGeometry to also take in this new enum
 - Ensure the DefaultStylizer and StylizationEngine read the enum value from the renderer and pass it down to the GetGeometry() calls
 - In the RSMgFeatureReader implementation, use this passed enum to determine if geometries are polygon and require re-orientation. If so, load the AGF of the re-oriented polygon into the LineBuffer to be returned.

There will be perf overhead having to re-orient polygons when rendering, but it is overhead that only the MVT renderer has to wear.

Modified: sandbox/jng/mvt/Common/Renderers/MVTRenderer.cpp
===================================================================
--- sandbox/jng/mvt/Common/Renderers/MVTRenderer.cpp	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Renderers/MVTRenderer.cpp	2019-06-12 16:25:24 UTC (rev 9547)
@@ -689,4 +689,9 @@
 void MVTRenderer::GetMVTContent(std::string& buffer)
 {
     m_impl->GetMVTContent(buffer);
+}
+
+RS_DesiredPolygonOrientation MVTRenderer::GetDesiredPolygonOrientation()
+{
+    return RS_DesiredPolygonOrientation::Clockwise;
 }
\ No newline at end of file

Modified: sandbox/jng/mvt/Common/Renderers/MVTRenderer.h
===================================================================
--- sandbox/jng/mvt/Common/Renderers/MVTRenderer.h	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Renderers/MVTRenderer.h	2019-06-12 16:25:24 UTC (rev 9547)
@@ -68,6 +68,7 @@
     RENDERERS_API virtual RS_FontEngine * GetRSFontEngine();
     RENDERERS_API virtual void ProcessSELabelGroup(SE_LabelInfo * labels, int nlabels, RS_OverpostType type, bool exclude, LineBuffer * path = NULL);
     RENDERERS_API virtual void AddExclusionRegion(RS_F_Point * fpts, int npts);
+    RENDERERS_API virtual RS_DesiredPolygonOrientation GetDesiredPolygonOrientation();
 
     //MVT-specific
     RENDERERS_API void GetMVTContent(std::string& buffer);

Modified: sandbox/jng/mvt/Common/Stylization/DefaultStylizer.cpp
===================================================================
--- sandbox/jng/mvt/Common/Stylization/DefaultStylizer.cpp	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/DefaultStylizer.cpp	2019-06-12 16:25:24 UTC (rev 9547)
@@ -338,7 +338,9 @@
         try
         {
             if (!features->IsNull(gpName))
-                features->GetGeometry(gpName, lb, xformer);
+            {
+                features->GetGeometry(gpName, lb, xformer, renderer->GetDesiredPolygonOrientation());
+            }
             else
             {
                 // just move on to the next feature

Modified: sandbox/jng/mvt/Common/Stylization/RS_FeatureReader.h
===================================================================
--- sandbox/jng/mvt/Common/Stylization/RS_FeatureReader.h	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/RS_FeatureReader.h	2019-06-12 16:25:24 UTC (rev 9547)
@@ -41,7 +41,7 @@
     virtual FdoInt32        GetInt32       (const wchar_t* propertyName) = 0;
     virtual FdoInt64        GetInt64       (const wchar_t* propertyName) = 0;
     virtual const wchar_t*  GetString      (const wchar_t* propertyName) = 0;
-    virtual LineBuffer*     GetGeometry    (const wchar_t* propertyName, LineBuffer* lb, CSysTransformer* xformer) = 0;
+    virtual LineBuffer*     GetGeometry    (const wchar_t* propertyName, LineBuffer* lb, CSysTransformer* xformer, RS_DesiredPolygonOrientation polygonOrientation) = 0;
     virtual RS_Raster*      GetRaster      (const wchar_t* propertyName) = 0;
     virtual const wchar_t*  GetAsString    (const wchar_t* propertyName) = 0;
     virtual RS_InputStream* GetBLOB        (const wchar_t* propertyName) = 0;

Modified: sandbox/jng/mvt/Common/Stylization/Renderer.h
===================================================================
--- sandbox/jng/mvt/Common/Stylization/Renderer.h	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/Renderer.h	2019-06-12 16:25:24 UTC (rev 9547)
@@ -240,6 +240,9 @@
     // line buffer pool access
     virtual SE_BufferPool* GetBufferPool() = 0;
     virtual void SetBufferPool(SE_BufferPool* pool) = 0;
+
+    // States the desired polygon orientation
+    virtual RS_DesiredPolygonOrientation GetDesiredPolygonOrientation() = 0;
 };
 
 #endif

Modified: sandbox/jng/mvt/Common/Stylization/RendererStyles.h
===================================================================
--- sandbox/jng/mvt/Common/Stylization/RendererStyles.h	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/RendererStyles.h	2019-06-12 16:25:24 UTC (rev 9547)
@@ -23,7 +23,14 @@
 
 typedef std::wstring RS_String;
 
+enum RS_DesiredPolygonOrientation
+{
+    Clockwise,
+    CounterClockwise,
+    NotApplicable
+};
 
+
 //////////////////////////////////////////////////////////////////////////////
 enum RS_HAlignment
 {

Modified: sandbox/jng/mvt/Common/Stylization/SE_Renderer.cpp
===================================================================
--- sandbox/jng/mvt/Common/Stylization/SE_Renderer.cpp	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/SE_Renderer.cpp	2019-06-12 16:25:24 UTC (rev 9547)
@@ -722,3 +722,8 @@
 {
     return true;
 }
+
+RS_DesiredPolygonOrientation SE_Renderer::GetDesiredPolygonOrientation()
+{
+    return RS_DesiredPolygonOrientation::NotApplicable;
+}
\ No newline at end of file

Modified: sandbox/jng/mvt/Common/Stylization/SE_Renderer.h
===================================================================
--- sandbox/jng/mvt/Common/Stylization/SE_Renderer.h	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/SE_Renderer.h	2019-06-12 16:25:24 UTC (rev 9547)
@@ -136,6 +136,11 @@
     // overridden.
     STYLIZATION_API virtual bool OptimizeGeometry();
 
+    // Indicate the desired polygon orientation for this renderer. Some renderers may demand
+    // that polygon data passed to it be of a particular orientation. It will be the responsibility
+    // of the Stylizer to make sure this requirement is met.
+    STYLIZATION_API virtual RS_DesiredPolygonOrientation GetDesiredPolygonOrientation();
+
 private:
     void ProcessLineOverlapWrap(LineBuffer* geometry, SE_RenderLineStyle* style);
     void ProcessLineOverlapNone(LineBuffer* geometry, SE_RenderLineStyle* style);

Modified: sandbox/jng/mvt/Common/Stylization/StylizationEngine.cpp
===================================================================
--- sandbox/jng/mvt/Common/Stylization/StylizationEngine.cpp	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Common/Stylization/StylizationEngine.cpp	2019-06-12 16:25:24 UTC (rev 9547)
@@ -148,7 +148,9 @@
             try
             {
                 if (!reader->IsNull(gpName))
-                    reader->GetGeometry(gpName, lb, xformer);
+                {
+                    reader->GetGeometry(gpName, lb, xformer, se_renderer->GetDesiredPolygonOrientation());
+                }
                 else
                 {
                     // just move on to the next feature

Modified: sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.cpp
===================================================================
--- sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.cpp	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.cpp	2019-06-12 16:25:24 UTC (rev 9547)
@@ -22,6 +22,8 @@
 #include "LineBuffer.h"
 #include "ServerFeatureReader.h"
 #include "ServerGwsFeatureReader.h"
+#include "FdoGeometry.h"
+#include "FdoSpatial.h"
 
 //we want to catch the MgException and rethrow a FdoException which
 //the Stylizer knows how to catch and release. It does not know about
@@ -297,7 +299,8 @@
 
 LineBuffer* RSMgFeatureReader::GetGeometry(const wchar_t*   propertyName,
                                            LineBuffer*      lb,
-                                           CSysTransformer* xformer)
+                                           CSysTransformer* xformer,
+                                           RS_DesiredPolygonOrientation polygonOrientation)
 {
     RSFR_TRY()
 
@@ -311,8 +314,66 @@
         throw FdoException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_60_NULL_POINTER)));
 
     _ASSERT(lb);
-    lb->LoadFromAgf(agf, sz, xformer);
 
+    //Peek at the raw AGF bytes to see if it's a polygon ahead of time.
+    int* ireader = (int*)agf;
+    // the geometry type
+    auto geomType = (FdoGeometryType)*ireader++;
+    bool isPolygon = geomType == FdoGeometryType_Polygon
+        || geomType == FdoGeometryType_MultiPolygon
+        || geomType == FdoGeometryType_CurvePolygon
+        || geomType == FdoGeometryType_MultiCurvePolygon;
+
+    if (isPolygon && polygonOrientation != RS_DesiredPolygonOrientation::NotApplicable)
+    {
+        FdoPtr<FdoFgfGeometryFactory> geomFactory = FdoFgfGeometryFactory::GetInstance();
+        FdoPtr<FdoIGeometry> geom = geomFactory->CreateGeometryFromFgf(agf, sz);
+        FdoPtr<FdoIGeometry> reoriented;
+        
+        switch (polygonOrientation)
+        {
+            case RS_DesiredPolygonOrientation::Clockwise:
+            {
+                reoriented = FdoSpatialUtility::FixPolygonVertexOrder(geom, FdoPolygonVertexOrderRule_CW);
+                FdoPtr<FdoByteArray> reFgf;
+                if (NULL != reoriented.p)
+                {
+                    reFgf = geomFactory->GetFgf(reoriented);
+                    lb->LoadFromAgf(reFgf->GetData(), reFgf->GetCount(), xformer);
+                }
+                else //Load original
+                {
+                    lb->LoadFromAgf(agf, sz, xformer);
+                }
+                break;
+            }
+            case RS_DesiredPolygonOrientation::CounterClockwise:
+            {
+                reoriented = FdoSpatialUtility::FixPolygonVertexOrder(geom, FdoPolygonVertexOrderRule_CCW);
+                FdoPtr<FdoByteArray> reFgf;
+                if (NULL != reoriented.p)
+                {
+                    reFgf = geomFactory->GetFgf(reoriented);
+                    lb->LoadFromAgf(reFgf->GetData(), reFgf->GetCount(), xformer);
+                }
+                else //Load original
+                {
+                    lb->LoadFromAgf(agf, sz, xformer);
+                }
+                break;
+            }
+            default:
+            {
+                _ASSERT(false);
+                break;
+            }
+        }
+    }
+    else
+    {
+        lb->LoadFromAgf(agf, sz, xformer);
+    }
+
     return lb;
 
     RSFR_CATCH()

Modified: sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.h
===================================================================
--- sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.h	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Server/src/Services/Mapping/RSMgFeatureReader.h	2019-06-12 16:25:24 UTC (rev 9547)
@@ -58,7 +58,7 @@
     virtual FdoInt32        GetInt32       (const wchar_t* propertyName);
     virtual FdoInt64        GetInt64       (const wchar_t* propertyName);
     virtual const wchar_t*  GetString      (const wchar_t* propertyName);
-    virtual LineBuffer*     GetGeometry    (const wchar_t* propertyName, LineBuffer* lb, CSysTransformer* xformer);
+    virtual LineBuffer*     GetGeometry    (const wchar_t* propertyName, LineBuffer* lb, CSysTransformer* xformer, RS_DesiredPolygonOrientation polygonOrientation);
     virtual RS_Raster*      GetRaster      (const wchar_t* propertyName);
     virtual const wchar_t*  GetAsString    (const wchar_t* propertyName);
     virtual RS_InputStream* GetBLOB        (const wchar_t* propertyName);

Modified: sandbox/jng/mvt/Server/src/Services/Mapping/ServerMappingService.vcxproj
===================================================================
--- sandbox/jng/mvt/Server/src/Services/Mapping/ServerMappingService.vcxproj	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Server/src/Services/Mapping/ServerMappingService.vcxproj	2019-06-12 16:25:24 UTC (rev 9547)
@@ -104,10 +104,10 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACEd.lib;xerces-c_3mgD.lib;FDO.lib;FDOCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACEd.lib;xerces-c_3mgD.lib;FDO.lib;FDOCommon.lib;FDOGeometry.lib;FDOSpatial.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerMappingServiced.dll</OutputFile>
       <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib\$(Configuration);..\..\..\..\Oem\dbxml\lib\$(Configuration);..\..\..\..\Oem\FDO\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;FDOGeometry.dll;FDOSpatial.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerMappingServiced.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -131,10 +131,10 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACEd.lib;xerces-c_3mgD.lib;FDO.lib;FDOCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACEd.lib;xerces-c_3mgD.lib;FDO.lib;FDOCommon.lib;FDOGeometry.lib;FDOSpatial.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerMappingServiced.dll</OutputFile>
       <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib64\$(Configuration);..\..\..\..\Oem\dbxml\lib64\$(Configuration);..\..\..\..\Oem\FDO\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;FDOGeometry.dll;FDOSpatial.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerMappingServiced.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -157,10 +157,10 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACE.lib;xerces-c_3mg.lib;FDO.lib;FDOCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACE.lib;xerces-c_3mg.lib;FDO.lib;FDOCommon.lib;FDOGeometry.lib;FDOSpatial.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerMappingService.dll</OutputFile>
       <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib\$(Configuration);..\..\..\..\Oem\dbxml\lib\$(Configuration);..\..\..\..\Oem\FDO\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;FDOGeometry.dll;FDOSpatial.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerMappingService.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
@@ -185,10 +185,10 @@
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>ACE.lib;xerces-c_3mg.lib;FDO.lib;FDOCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACE.lib;xerces-c_3mg.lib;FDO.lib;FDOCommon.lib;FDOGeometry.lib;FDOSpatial.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgServerMappingService.dll</OutputFile>
       <AdditionalLibraryDirectories>..\..\..\..\Oem\ACE\ACE_wrappers\lib64\$(Configuration);..\..\..\..\Oem\dbxml\lib64\$(Configuration);..\..\..\..\Oem\FDO\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>FDO.dll;FDOCommon.dll;FDOGeometry.dll;FDOSpatial.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgServerMappingService.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>

Modified: sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp
===================================================================
--- sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp	2019-06-12 16:00:27 UTC (rev 9546)
+++ sandbox/jng/mvt/Server/src/UnitTesting/TestRenderingService.cpp	2019-06-12 16:25:24 UTC (rev 9547)
@@ -1924,7 +1924,7 @@
     virtual FdoInt32        GetInt32(const wchar_t* propertyName) { return 0; }
     virtual FdoInt64        GetInt64(const wchar_t* propertyName) { return 0; }
     virtual const wchar_t*  GetString(const wchar_t* propertyName) { return nullptr; }
-    virtual LineBuffer*     GetGeometry(const wchar_t* propertyName, LineBuffer* lb, CSysTransformer* xformer) { return nullptr; }
+    virtual LineBuffer*     GetGeometry(const wchar_t* propertyName, LineBuffer* lb, CSysTransformer* xformer, RS_DesiredPolygonOrientation polygonOrientation) { return nullptr; }
     virtual RS_Raster*      GetRaster(const wchar_t* propertyName) { return nullptr; }
     virtual const wchar_t*  GetAsString(const wchar_t* propertyName) { return nullptr; }
     virtual RS_InputStream* GetBLOB(const wchar_t* propertyName) { return nullptr; }



More information about the mapguide-commits mailing list