[mapguide-commits] r4361 - in sandbox/adsk/2.1/Common: MapGuideCommon/Services Renderers

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Nov 30 17:36:34 EST 2009


Author: waltweltonlair
Date: 2009-11-30 17:36:33 -0500 (Mon, 30 Nov 2009)
New Revision: 4361

Modified:
   sandbox/adsk/2.1/Common/MapGuideCommon/Services/PrintLayout.cpp
   sandbox/adsk/2.1/Common/Renderers/DWFRenderer.cpp
   sandbox/adsk/2.1/Common/Renderers/DWFRenderer.h
Log:
Fix #1089: Plot to DWF (eplot) - plot wrong -> islands/holes filled 

Merge the trunk fix into the sandbox stream.


Modified: sandbox/adsk/2.1/Common/MapGuideCommon/Services/PrintLayout.cpp
===================================================================
--- sandbox/adsk/2.1/Common/MapGuideCommon/Services/PrintLayout.cpp	2009-11-30 22:24:19 UTC (rev 4360)
+++ sandbox/adsk/2.1/Common/MapGuideCommon/Services/PrintLayout.cpp	2009-11-30 22:36:33 UTC (rev 4361)
@@ -692,11 +692,6 @@
 //
 MgEnvelope* MgPrintLayout::DetermineLayoutMapExtents(MgMap* map, double metersPerUnit, double mapWidth, double mapHeight)
 {
-    // Initialize the layout map extents with the full map extent
-    Ptr<MgEnvelope> env = map->GetDataExtent();
-    Ptr<MgCoordinate> ll = env->GetLowerLeftCoordinate();
-    Ptr<MgCoordinate> ur = env->GetUpperRightCoordinate();
-
     // Compute the aspect ratio of the available map area
     double pageAR = mapWidth / mapHeight;
 

Modified: sandbox/adsk/2.1/Common/Renderers/DWFRenderer.cpp
===================================================================
--- sandbox/adsk/2.1/Common/Renderers/DWFRenderer.cpp	2009-11-30 22:24:19 UTC (rev 4360)
+++ sandbox/adsk/2.1/Common/Renderers/DWFRenderer.cpp	2009-11-30 22:36:33 UTC (rev 4361)
@@ -584,7 +584,7 @@
 
         if (geom->cntr_count() == 1)
         {
-            // just a polygon, no need for a contourset
+            // just a polygon, no need for a contour set
             WT_Polygon polygon(geom->point_count(), m_wtPointBuffer, false);
             polygon.serialize(*m_w2dFile);
             IncrementDrawableCount();
@@ -592,6 +592,11 @@
         else
         {
             // otherwise make a contour set
+
+            // ensure the contours are oriented per the DWF spec
+            OrientContours(geom->cntr_count(), geom->cntrs(), m_wtPointBuffer);
+
+            // now create the contour set
             WT_Contour_Set cset(*m_w2dFile, geom->cntr_count(), (WT_Integer32*)geom->cntrs(), geom->point_count(), m_wtPointBuffer, true);
             cset.serialize(*m_w2dFile);
             IncrementDrawableCount();
@@ -674,8 +679,6 @@
 
     WriteStroke(lsym);
 
-    LineBuffer* workbuffer = srclb->Optimize(m_drawingScale, m_pPool);
-
     bool oldLinePatternActive = m_linePatternActive;
 
     //determine pattern to apply
@@ -719,6 +722,8 @@
         m_w2dFile->desired_rendition().dash_pattern() = dpat;
     }
 
+    LineBuffer* workbuffer = srclb->Optimize(m_drawingScale, m_pPool);
+
     WritePolylines(workbuffer);
 
     if (m_obsMesh)
@@ -2137,6 +2142,79 @@
 }
 
 
+//----------------------------------------------------------------------------
+//
+// Used by ProcessPolygon and DrawScreenPolygon to ensure that contours in
+// contour sets are oriented according to the DWF spec.  The spec requires
+// that filled areas be specified by clockwise wound points, and holes be
+// specified by counter-clockwise wound points.  So in our context the first
+// contour needs to be CW, and the remaining ones CCW.  The implementation
+// assumes simple contours (no self-intersection).
+//
+//----------------------------------------------------------------------------
+void DWFRenderer::OrientContours(int numContours, int* contourCounts, WT_Logical_Point* wtPointBuffer)
+{
+    if (numContours == 1)
+        return;
+
+    int start_pt = 0;
+    int end_pt = 0;
+
+    // iterate over the contours
+    for (int j=0; j<numContours; ++j)
+    {
+        // get point range for current contour
+        start_pt = end_pt;
+        end_pt += contourCounts[j];
+
+        if (contourCounts[j] < 2)
+            continue;
+
+        // compute area of current contour
+        double x0;
+        double y0;
+        double x1 = wtPointBuffer[end_pt-1].m_x;
+        double y1 = wtPointBuffer[end_pt-1].m_y;
+        double area2 = 0.0;
+        for (int i=start_pt; i<end_pt; ++i)
+        {
+            x0 = x1;
+            y0 = y1;
+            x1 = wtPointBuffer[i].m_x;
+            y1 = wtPointBuffer[i].m_y;
+            area2 += x0*y1 - y0*x1;
+        }
+
+        // the first contour (outer ring) needs to be CW (area < 0), and the
+        // remaining ones CCW (area > 0)
+        bool flipContour = false;
+        if (j == 0)
+        {
+            if (area2 > 0.0)
+                flipContour = true;
+        }
+        else if (area2 < 0.0)
+            flipContour = true;
+
+        if (flipContour)
+        {
+            int halfCount = contourCounts[j] / 2;
+            for (int i=0; i<halfCount; ++i)
+            {
+                int pt0 = start_pt + i;
+                int pt1 = end_pt - i - 1;
+                WT_Integer32 xTmp = wtPointBuffer[pt0].m_x;
+                WT_Integer32 yTmp = wtPointBuffer[pt0].m_y;
+                wtPointBuffer[pt0].m_x = wtPointBuffer[pt1].m_x;
+                wtPointBuffer[pt0].m_y = wtPointBuffer[pt1].m_y;
+                wtPointBuffer[pt1].m_x = xTmp;
+                wtPointBuffer[pt1].m_y = yTmp;
+            }
+        }
+    }
+}
+
+
 void DWFRenderer::SetSymbolManager(RS_SymbolManager* manager)
 {
     m_symbolManager = manager;
@@ -2438,7 +2516,7 @@
 
     if (geom->cntr_count() == 1)
     {
-        // just a polygon, no need for a contourset
+        // just a polygon, no need for a contour set
         WT_Polygon polygon(geom->point_count(), m_wtPointBuffer, false);
         polygon.serialize(*file);
         IncrementDrawableCount();
@@ -2446,6 +2524,11 @@
     else
     {
         // otherwise make a contour set
+
+        // ensure the contours are oriented per the DWF spec
+        OrientContours(geom->cntr_count(), geom->cntrs(), m_wtPointBuffer);
+
+        // now create the contour set
         WT_Contour_Set cset(*file, geom->cntr_count(), (WT_Integer32*)geom->cntrs(), geom->point_count(), m_wtPointBuffer, true);
         cset.serialize(*file);
         IncrementDrawableCount();

Modified: sandbox/adsk/2.1/Common/Renderers/DWFRenderer.h
===================================================================
--- sandbox/adsk/2.1/Common/Renderers/DWFRenderer.h	2009-11-30 22:24:19 UTC (rev 4360)
+++ sandbox/adsk/2.1/Common/Renderers/DWFRenderer.h	2009-11-30 22:36:33 UTC (rev 4361)
@@ -314,6 +314,10 @@
                              WT_Dash_Pattern& dash,
                              WT_Line_Pattern& lpat);
 
+    // used by ProcessPolygon and DrawScreenPolygon to ensure that contours in
+    // contour sets are oriented according to the DWF spec
+    void OrientContours(int numContours, int* contourCounts, WT_Logical_Point* wtPointBuffer);
+
     unsigned int m_nObjectId;
     void* m_hObjNodes;
 



More information about the mapguide-commits mailing list