[mapguide-commits] r4226 - in trunk/MgDev: Common/Renderers Common/Stylization Server/src/Services/Rendering

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Sep 16 16:57:54 EDT 2009


Author: waltweltonlair
Date: 2009-09-16 16:57:54 -0400 (Wed, 16 Sep 2009)
New Revision: 4226

Modified:
   trunk/MgDev/Common/Renderers/AGGRenderer.cpp
   trunk/MgDev/Common/Renderers/AGGRenderer.h
   trunk/MgDev/Common/Renderers/DWFRenderer.cpp
   trunk/MgDev/Common/Renderers/DWFRenderer.h
   trunk/MgDev/Common/Renderers/GDRenderer.cpp
   trunk/MgDev/Common/Renderers/GDRenderer.h
   trunk/MgDev/Common/Renderers/KmlRenderer.cpp
   trunk/MgDev/Common/Renderers/KmlRenderer.h
   trunk/MgDev/Common/Stylization/DefaultStylizer.cpp
   trunk/MgDev/Common/Stylization/LineBuffer.cpp
   trunk/MgDev/Common/Stylization/Renderer.h
   trunk/MgDev/Common/Stylization/StylizationEngine.cpp
   trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.cpp
   trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.h
Log:
Fix #1095: Plot to DWF (eplot) - plot contains additional and wrong elements

Part of the rendering pipeline involves clipping feature geometry to the view extent.  The clipping code, however, does not yet support geometry with Z values - if the supplied geometry has Z values it simply won?\226?\128?\153t be clipped.  Normally that doesn?\226?\128?\153t cause any problems; the image renderers used in the AJAX / Fusion viewers can handle geometry which lies outside the view extent.  But DWFRenderer does not support this.  Why?  Data in the DWF file is represented as W2D streams, and the coordinates for points must be in the range of [-2,147,483,648, +2,147,483,647], the range for signed 32-bit integers.  DWFRenderer is configured so that this range is mapped to the view extent, e.g. a W2D point with y=2,000,000,000 will be near the top of the view extent.  This works fine as long as the geometry is clipped to the view extent.  But any geometry that isn?\226?\128?\153t clipped will end up outside the valid range for W2D coordinates, and when we cast the double precision coordinates to signed integers the values wrap around.  This causes spurious geometry to appear in the EPlot.

The fix is to ignore Z values when processing the feature geometry for DWFs.  LineBuffer already supports this functionality - we just have to take advantage of it.  I implemented the fix by adding a new SupportsZ virtual method to the Renderer class.  If this returns true then Z values in the geometry will be processed, otherwise they are ignored.  DWFRenderer returns false for this method, as do all the other MapGuide renderers (AGG, GD, Kml).

Note that this submission can provide performance improvements for AGG / GD when processing features with 3D geometry.  Before this change the geometry would not be clipped, and if you're zoomed far in (so that features extend far beyond the visible extent) then this reduces rendering performance.  After this submission those features will now be clipped.


Modified: trunk/MgDev/Common/Renderers/AGGRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Renderers/AGGRenderer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/AGGRenderer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -1115,6 +1115,13 @@
 }
 
 
+bool AGGRenderer::SupportsZ()
+{
+    // Z values in feature geometry are ignored
+    return false;
+}
+
+
 bool AGGRenderer::SupportsTooltips()
 {
     // set to false to disable processing of tooltips

Modified: trunk/MgDev/Common/Renderers/AGGRenderer.h
===================================================================
--- trunk/MgDev/Common/Renderers/AGGRenderer.h	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/AGGRenderer.h	2009-09-16 20:57:54 UTC (rev 4226)
@@ -140,6 +140,8 @@
 
     RENDERERS_API virtual bool RequiresLabelClipping();
 
+    RENDERERS_API virtual bool SupportsZ();
+
     RENDERERS_API virtual bool SupportsTooltips();
 
     RENDERERS_API virtual bool SupportsHyperlinks();

Modified: trunk/MgDev/Common/Renderers/DWFRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Renderers/DWFRenderer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/DWFRenderer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -2283,6 +2283,13 @@
 }
 
 
+bool DWFRenderer::SupportsZ()
+{
+    // Z values in feature geometry are ignored
+    return false;
+}
+
+
 double DWFRenderer::GetMapToW2DScale()
 {
     return m_scale;

Modified: trunk/MgDev/Common/Renderers/DWFRenderer.h
===================================================================
--- trunk/MgDev/Common/Renderers/DWFRenderer.h	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/DWFRenderer.h	2009-09-16 20:57:54 UTC (rev 4226)
@@ -159,6 +159,8 @@
 
     virtual bool RequiresLabelClipping();
 
+    virtual bool SupportsZ();
+
     /////////////////////////////////////////////
     // DWFRenderer specific
     //

Modified: trunk/MgDev/Common/Renderers/GDRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Renderers/GDRenderer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/GDRenderer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -1199,6 +1199,13 @@
 }
 
 
+bool GDRenderer::SupportsZ()
+{
+    // Z values in feature geometry are ignored
+    return false;
+}
+
+
 bool GDRenderer::SupportsTooltips()
 {
     // set to false to disable processing of tooltips

Modified: trunk/MgDev/Common/Renderers/GDRenderer.h
===================================================================
--- trunk/MgDev/Common/Renderers/GDRenderer.h	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/GDRenderer.h	2009-09-16 20:57:54 UTC (rev 4226)
@@ -134,6 +134,8 @@
 
     virtual bool RequiresLabelClipping();
 
+    virtual bool SupportsZ();
+
     virtual bool SupportsTooltips();
 
     virtual bool SupportsHyperlinks();

Modified: trunk/MgDev/Common/Renderers/KmlRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Renderers/KmlRenderer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/KmlRenderer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -476,6 +476,14 @@
 }
 
 
+bool KmlRenderer::SupportsZ()
+{
+    // although KmlRenderer supports elevation, it ignores Z values
+    // in feature geometry
+    return false;
+}
+
+
 //Inserts the contents of a given DWF input stream
 //into the current output W2D. The given coord sys
 //transformation is applied and geometry will be clipped

Modified: trunk/MgDev/Common/Renderers/KmlRenderer.h
===================================================================
--- trunk/MgDev/Common/Renderers/KmlRenderer.h	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Renderers/KmlRenderer.h	2009-09-16 20:57:54 UTC (rev 4226)
@@ -119,6 +119,8 @@
 
     virtual bool RequiresLabelClipping();
 
+    virtual bool SupportsZ();
+
     ////////////////////////////////////////////////
     // SE_Renderer
     //

Modified: trunk/MgDev/Common/Stylization/DefaultStylizer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/DefaultStylizer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Stylization/DefaultStylizer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -277,6 +277,9 @@
     }
     RS_ElevationSettings* elevSettings = spElevSettings.get();
 
+    // ignore Z values if the renderer doesn't need them
+    bool ignoreZ = !renderer->SupportsZ();
+
     // create an expression engine with our custom functions
     // NOTE: We must create a new engine for each call to StylizeVLHelper.  The
     //       engine stores a weak reference to the RS_FeatureReader's internal
@@ -292,7 +295,7 @@
         ++nFeatures;
         #endif
 
-        LineBuffer* lb = LineBufferPool::NewLineBuffer(&m_lbPool, 8, FdoDimensionality_Z, false);
+        LineBuffer* lb = LineBufferPool::NewLineBuffer(&m_lbPool, 8, FdoDimensionality_Z, ignoreZ);
         if (!lb)
             continue;
 

Modified: trunk/MgDev/Common/Stylization/LineBuffer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/LineBuffer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Stylization/LineBuffer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -1540,7 +1540,7 @@
 
     bool move = false;
 
-    // loop over all segments, MoveTos denote start of polygon
+    // loop over all segments, MoveTo's denote start of polygon
     // in a multipolygon
     for (int i=0; i<m_cur_types; ++i)
     {
@@ -1588,14 +1588,14 @@
             // find the t values for x and y exit points
             if (deltaX != 0.0)
                 tOutX = (xOut - aline[0]) / deltaX;
-            else if (clipRect.minx<=aline[0] && aline[0]<=clipRect.maxx)
+            else if (clipRect.minx <= aline[0] && aline[0] <= clipRect.maxx)
                 tOutX = std::numeric_limits<double>::infinity();
             else
                 tOutX = -std::numeric_limits<double>::infinity();
 
             if (deltaY != 0.0)
                 tOutY = (yOut - aline[1]) / deltaY;
-            else if (clipRect.miny<=aline[1]&& aline[1]<=clipRect.maxy)
+            else if (clipRect.miny <= aline[1]&& aline[1] <= clipRect.maxy)
                 tOutY = std::numeric_limits<double>::infinity();
             else
                 tOutY = -std::numeric_limits<double>::infinity();
@@ -1634,7 +1634,7 @@
                 // a possible turning vertex
                 if (tOut1 < tIn2)
                 {
-                    // if tOut1 > 0.0 and tOut1 < 1.0 then line crosses over
+                    // if tOut1 > 0.0 and tOut1 <= 1.0 then line crosses over
                     // intermediate corner region - generate turning vertex
                     if (tOut1 > 0.0 && tOut1 <= 1.0)
                     {
@@ -1780,7 +1780,7 @@
 //                     structure pointed to contains the coordinates of the
 //                     corners of the clip rectangle.
 //         x         - passes the x coordinate of the clipped vertex.
-//         y         - passes the y coordiante of the clipped vertex.
+//         y         - passes the y coordinate of the clipped vertex.
 //
 // RETURNS: None.
 //
@@ -1798,8 +1798,8 @@
     // TODO: NOT Z AWARE
     bool degenerate = false;
 
-    // only line segments can be degenerate -- a move indicates the start of a new
-    // polygon, so it is not degenerate
+    // only line segments can be degenerate - a move indicates the start of a
+    // new polygon, so it is not degenerate
     int npts = move? 0 : lb->m_cntrs[lb->m_cur_cntr];
 
     if (npts > 1)
@@ -1816,8 +1816,8 @@
                       ((x <= x1 && x2 <= x1) || (x >= x1 && x2 >= x1)));
     }
 
-    // else if there is only one vertex, and the new vertex is identical, then
-    // flag as degenerate
+    // else if there is only one vertex, and the new vertex is identical,
+    // then flag as degenerate
     else if (npts == 1)
     {
         degenerate =   x == lb->x_coord(lb->point_count()-1)
@@ -1931,32 +1931,18 @@
 //
 // FUNCTION: ClipLine().
 //
-// PURPOSE: Clip a line (given in application coordinates) against the
+// PURPOSE: Clips a line (given in application coordinates) against the
 //          specified clip rectangle using the Cohen-Sutherland clipping
-//          algorithm. Note - the clipped segment is guaranteed to have
+//          algorithm.  Note - the clipped segment is guaranteed to have
 //          the same directon as the original.
 //
 // PARAMETERS:
+//     clipRect - the rectangle to clip against
+//     line     - an array of 4 doubles containing the x/y coordinates
+//                of the line segment's start and end points
+//     ret      - an array of 4 doubles which will contain the x/y
+//                coordinates of the line's clipped start and end points
 //
-//     Input:
-//
-//         clipRect - passes a reference to an OpsFloatExtent structure; the
-//                    structure contains the coordinates of the corners of
-//                    the clip rectangle.
-//         endPt1   - passes a reference to an OpsFloatPoint structure; the
-//                    structure contains the coordinates of the first endpoint
-//                    of the line segment.
-//         endPt2   - passes a reference to an OpsFloatPoint structure; the
-//                    structure contains the coordinates of the second endpoint
-//                    of the line segment.
-//
-//     Output:
-//
-//         endPt1   - the coordinates of the (possibly clipped) first endpoint
-//                    are returned in the referenced structure.
-//         endPt2   - the coordinates of the (possibly clipped) second endpoint
-//                    are returned in the referenced structure.
-//
 // RETURNS: The method returns 0 if the line segment is not visible with respect
 //          the clip rectangle; 1 if the line segment is visible and the second
 //          endpoint was not clipped off; 2 if the segment is visible and the

Modified: trunk/MgDev/Common/Stylization/Renderer.h
===================================================================
--- trunk/MgDev/Common/Stylization/Renderer.h	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Stylization/Renderer.h	2009-09-16 20:57:54 UTC (rev 4226)
@@ -184,22 +184,22 @@
     virtual RS_Bounds& GetBounds() = 0;
 
     //------------------------------------------------------
-    // Geometry clipping renderer options
+    // Geometry renderer settings
     //------------------------------------------------------
 
-    ///<summary>
-    /// Flags whether the geometry used to render the feature is clipped.
-    ///</summary>
+    // Flags whether the geometry used to render the feature is clipped.
     virtual bool RequiresClipping() = 0;
 
-    ///<summary>
-    /// Flags whether the geometry used to label the feature is clipped.
-    /// This only applies if geometry clipping is set to false.  By setting
-    /// label clipping to true, you can be assured of generating on-screen
-    /// labels even though the feature geometry is not clipped to the screen.
-    ///</summary>
+    // Flags whether the geometry used to label the feature is clipped.
+    // This only applies if geometry clipping is set to false.  By setting
+    // label clipping to true, you can be assured of generating on-screen
+    // labels even though the feature geometry is not clipped to the screen.
     virtual bool RequiresLabelClipping() = 0;
 
+    // Flags whether the renderer has rendering support for geometry
+    // containing Z values.
+    virtual bool SupportsZ() = 0;
+
     //------------------------------------------------------
     // Miscellaneous
     //------------------------------------------------------

Modified: trunk/MgDev/Common/Stylization/StylizationEngine.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/StylizationEngine.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Common/Stylization/StylizationEngine.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -95,6 +95,9 @@
     if (numTypeStyles == 0)
         return;
 
+    // ignore Z values if the renderer doesn't need them
+    bool ignoreZ = !se_renderer->SupportsZ();
+
     // we always start with rendering pass 0
     int instanceRenderingPass = 0;
     int symbolRenderingPass = 0;
@@ -129,7 +132,7 @@
                 nFeatures++;
             #endif
 
-            LineBuffer* lb = LineBufferPool::NewLineBuffer(m_pool, 8, FdoDimensionality_Z, false);
+            LineBuffer* lb = LineBufferPool::NewLineBuffer(m_pool, 8, FdoDimensionality_Z, ignoreZ);
             if (!lb)
                 continue;
 

Modified: trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.cpp	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.cpp	2009-09-16 20:57:54 UTC (rev 4226)
@@ -467,6 +467,13 @@
 }
 
 
+bool FeatureInfoRenderer::SupportsZ()
+{
+    // Z values in feature geometry are ignored
+    return false;
+}
+
+
 bool FeatureInfoRenderer::RequiresCompositeLineStyleSeparation()
 {
     return false;

Modified: trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.h
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.h	2009-09-16 00:46:08 UTC (rev 4225)
+++ trunk/MgDev/Server/src/Services/Rendering/FeatureInfoRenderer.h	2009-09-16 20:57:54 UTC (rev 4226)
@@ -123,6 +123,8 @@
 
     virtual RS_Bounds& GetBounds();
 
+    virtual bool SupportsZ();
+
     virtual bool RequiresClipping();
 
     virtual bool RequiresLabelClipping();



More information about the mapguide-commits mailing list