[mapguide-commits] r9614 - in sandbox/jng/mvt_alt: Common/Stylization Server/src/UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Sat Sep 21 17:20:02 PDT 2019


Author: jng
Date: 2019-09-21 17:20:02 -0700 (Sat, 21 Sep 2019)
New Revision: 9614

Modified:
   sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.cpp
   sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.h
   sandbox/jng/mvt_alt/Server/src/UnitTesting/TestMisc.cpp
Log:
When rendering a MVT tile, we need to know when a new polygon of a multi-polygon begins. LineBuffers delineate everything in terms of points and contours (a series of points)

Cursory analysis of the LineBuffer class suggests that it does not have a means to determine which contour is the start of a geometry in a multi-geometry type (eg. MultiLineString/MultiPolygon).

I've added new APIs to LineBuffer to indicate:
 - Geometry count:
    - int num_geometries() const
 - The contour indices that mark the beginning of a new geometry for a multi-geometry LineBuffer:
    - int geom_start_cntr(int iGeom) const

These value are set when LoadFromAgf() is called.

I've extended the LineBuffer conversion test to verify these values are being set for multi-geometry LineBuffer instances.

Modified: sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.cpp
===================================================================
--- sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.cpp	2019-09-21 23:28:21 UTC (rev 9613)
+++ sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.cpp	2019-09-22 00:20:02 UTC (rev 9614)
@@ -59,7 +59,9 @@
     m_closeseg(NULL),
     m_cur_closeseg(-1),
     m_geom_type(0),
-    m_drawingScale(0.0)
+    m_drawingScale(0.0),
+    m_geom_count(0),
+    m_cntr_geom_start(NULL)
 {
     ResizePoints(rs_max(size, 2));
     ResizeContours(4);
@@ -113,6 +115,7 @@
     delete[] m_num_geomcntrs;
     delete[] m_arcs_sp;
     delete[] m_closeseg;
+    delete[] m_cntr_geom_start;
 }
 
 
@@ -144,6 +147,16 @@
         m_bounds.minz = 0.0;
         m_bounds.maxz = 0.0;
     }
+
+    if (m_geom_count > 0)
+    {
+        _ASSERT(m_cntr_geom_start != NULL);
+        for (int i = 0; i < m_geom_count; i++)
+        {
+            m_cntr_geom_start[0] = -1;
+        }
+    }
+    m_geom_count = 0;
 }
 
 
@@ -899,8 +912,23 @@
             if (is_multi)
                 num_geoms = *ireader++;
 
+            m_geom_count = num_geoms;
+
+            // Release old one
+            if (m_cntr_geom_start)
+                delete[] m_cntr_geom_start;
+            m_cntr_geom_start = new int[m_geom_count];
+            // Fill default values
+            for (int q = 0; q < num_geoms; ++q)
+            {
+                m_cntr_geom_start[q] = -1;
+            }
+
+            int current_contour = 0;
             for (int q=0; q<num_geoms; ++q)
             {
+                m_cntr_geom_start[q] = current_contour;
+
                 // skip past geometry type of subgeometry
                 // we know it is LineString or Polygon or Point respectively
                 if (is_multi)
@@ -1013,6 +1041,8 @@
 
                     ireader = (int*)dreader;
                     //*** ireader valid again
+
+                    current_contour++;
                 }
             }
             break;

Modified: sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.h
===================================================================
--- sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.h	2019-09-21 23:28:21 UTC (rev 9613)
+++ sandbox/jng/mvt_alt/Common/Stylization/LineBuffer.h	2019-09-22 00:20:02 UTC (rev 9614)
@@ -209,6 +209,8 @@
     inline double& y_coord(int n) const;
     inline double& z_coord(int n) const;
     inline bool contour_closed(int cntr) const;
+    inline int num_geometries() const;
+    inline int geom_start_cntr(int iGeom) const;
 
     // Adds point without checking for available space, updating the bounds, or applying
     // the 3D transform. Thus, Ensure{Points, Contours}, and possibly ComputeBounds must
@@ -253,6 +255,9 @@
     int m_closeseg_len;         // length of m_closeseg array
     int m_cur_closeseg;         // current index into m_closeseg;
     int* m_closeseg;            // closed segment indices array
+    
+    int m_geom_count;           // Geometry count (for multi-geometry types)
+    int* m_cntr_geom_start;     // Array of starting contours (denoting the start of a new geometry of a multi-geometry type)
 
     void Resize();
     void ResizeContours();
@@ -590,4 +595,14 @@
     _ASSERT(m_cur_closeseg <= m_closeseg_len);
 }
 
+int LineBuffer::num_geometries() const
+{
+    return m_geom_count;
+}
+
+int LineBuffer::geom_start_cntr(int iGeom) const
+{
+    return m_cntr_geom_start[iGeom];
+}
+
 #endif

Modified: sandbox/jng/mvt_alt/Server/src/UnitTesting/TestMisc.cpp
===================================================================
--- sandbox/jng/mvt_alt/Server/src/UnitTesting/TestMisc.cpp	2019-09-21 23:28:21 UTC (rev 9613)
+++ sandbox/jng/mvt_alt/Server/src/UnitTesting/TestMisc.cpp	2019-09-22 00:20:02 UTC (rev 9614)
@@ -932,15 +932,15 @@
         Ptr<MgGeometry> gMultiPolygon1 = wktRw.Read(L"MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))");
         Ptr<MgGeometry> gMultiPolygon2 = wktRw.Read(L"MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))");
 
+        LineBuffer lb(8);
         //Point
         {
-            LineBuffer lb(8);
             Ptr<MgByteReader> agf = agfRw.Write(gPoint);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count());
+            CPPUNIT_ASSERT(1 == lb.num_geometries());
             CPPUNIT_ASSERT(1 == lb.point_count());
             CPPUNIT_ASSERT(30 == lb.x_coord(0));
             CPPUNIT_ASSERT(10 == lb.y_coord(0));
@@ -948,13 +948,14 @@
 
         //MultiPoint
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gMultiPoint);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count()); //LineBuffer flattens this
+            CPPUNIT_ASSERT(4 == lb.num_geometries());
             CPPUNIT_ASSERT(4 == lb.point_count());
             CPPUNIT_ASSERT(10 == lb.x_coord(0));
             CPPUNIT_ASSERT(40 == lb.y_coord(0));
@@ -968,7 +969,8 @@
 
         //LineString
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gLineStr);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
@@ -975,7 +977,7 @@
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
             int lineIdx = 0;
-            CPPUNIT_ASSERT(1 == lb.geom_count());
+            CPPUNIT_ASSERT(1 == lb.num_geometries());
             CPPUNIT_ASSERT(1 == lb.cntr_count());
             CPPUNIT_ASSERT(3 == lb.cntr_size(lineIdx));
 
@@ -1004,13 +1006,17 @@
         
         //MultiLineString
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gMultiLineString);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count()); //LineBuffer flattens this
+            CPPUNIT_ASSERT(2 == lb.num_geometries());
+            CPPUNIT_ASSERT(0 == lb.geom_start_cntr(0));
+            CPPUNIT_ASSERT(1 == lb.geom_start_cntr(1));
+
             CPPUNIT_ASSERT(2 == lb.cntr_count());
             CPPUNIT_ASSERT(3 == lb.cntr_size(0));
             CPPUNIT_ASSERT(4 == lb.cntr_size(1));
@@ -1072,13 +1078,15 @@
     
         //Polygon 1 (1 outer, 0 inner)
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gPolygon1);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count());
+            CPPUNIT_ASSERT(1 == lb.num_geometries());
+            CPPUNIT_ASSERT(0 == lb.geom_start_cntr(0));
             auto cc = lb.cntr_count();
             CPPUNIT_ASSERT(1 == cc);
 
@@ -1118,13 +1126,15 @@
 
         //Polygon 2 (1 outer, 1 inner)
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gPolygon2);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count());
+            CPPUNIT_ASSERT(1 == lb.num_geometries());
+            CPPUNIT_ASSERT(0 == lb.geom_start_cntr(0));
             auto cc = lb.cntr_count();
             CPPUNIT_ASSERT(2 == cc);
 
@@ -1195,13 +1205,16 @@
 
         //MultiPolygon 1
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gMultiPolygon1);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count()); //LineBuffer flattens this
+            CPPUNIT_ASSERT(2 == lb.num_geometries());
+            CPPUNIT_ASSERT(0 == lb.geom_start_cntr(0));
+            CPPUNIT_ASSERT(1 == lb.geom_start_cntr(1));
             auto cc = lb.cntr_count();
             CPPUNIT_ASSERT(2 == cc);
             auto closed1 = lb.contour_closed(0);
@@ -1274,13 +1287,16 @@
 
         //MultiPolygon 2
         {
-            LineBuffer lb(8);
+            lb.Reset();
+
             Ptr<MgByteReader> agf = agfRw.Write(gMultiPolygon2);
             Ptr<MgByteSink> agfSink = new MgByteSink(agf);
             Ptr<MgByte> bytes = agfSink->ToBuffer();
             lb.LoadFromAgf(bytes->Bytes(), bytes->GetLength(), nullptr);
 
-            CPPUNIT_ASSERT(1 == lb.geom_count()); //LineBuffer flattens this
+            CPPUNIT_ASSERT(2 == lb.num_geometries());
+            CPPUNIT_ASSERT(0 == lb.geom_start_cntr(0));
+            CPPUNIT_ASSERT(1 == lb.geom_start_cntr(1));
             auto cc = lb.cntr_count();
             CPPUNIT_ASSERT(3 == cc);
             auto closed1 = lb.contour_closed(0);



More information about the mapguide-commits mailing list