[geos-commits] r3291 - in trunk: include/geos/operation/buffer src/operation/buffer tests/xmltester tests/xmltester/tests/ticket

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Apr 20 13:13:13 EDT 2011


Author: strk
Date: 2011-04-20 10:13:13 -0700 (Wed, 20 Apr 2011)
New Revision: 3291

Added:
   trunk/tests/xmltester/tests/ticket/bug434.xml
Modified:
   trunk/include/geos/operation/buffer/OffsetCurveSetBuilder.h
   trunk/src/operation/buffer/OffsetCurveSetBuilder.cpp
   trunk/tests/xmltester/Makefile.am
Log:
Sync OffsetCurveSetBuilder::isErodedCompletely implementation to JTS, fixing bug #434

Modified: trunk/include/geos/operation/buffer/OffsetCurveSetBuilder.h
===================================================================
--- trunk/include/geos/operation/buffer/OffsetCurveSetBuilder.h	2011-04-20 15:55:53 UTC (rev 3290)
+++ trunk/include/geos/operation/buffer/OffsetCurveSetBuilder.h	2011-04-20 17:13:13 UTC (rev 3291)
@@ -38,6 +38,7 @@
 		class GeometryCollection;
 		class Point;
 		class LineString;
+		class LinearRing;
 		class Polygon;
 	}
 	namespace geomgraph {
@@ -141,12 +142,12 @@
 	 * It may be degenerate (i.e. contain only 1, 2, or 3 points).
 	 * In this case it has no area, and hence has a minimum diameter of 0.
 	 *
-	 * @param ringCoord
+	 * @param ring
 	 * @param offsetDistance
 	 * @return
 	 */
-	bool isErodedCompletely(geom::CoordinateSequence *ringCoord,
-			double bufferDistance);
+	bool isErodedCompletely(const geom::LinearRing* ringCoord,
+      double bufferDistance);
 
 	/**
 	 * Tests whether a triangular ring would be eroded completely by
@@ -162,11 +163,11 @@
 	 * In this case the triangle buffer curve "inverts" with incorrect
 	 * topology, producing an incorrect hole in the buffer.
 	 *
-	 * @param triangleCoord
+	 * @param triCoord
 	 * @param bufferDistance
 	 * @return
 	 */
-	bool isTriangleErodedCompletely(geom::CoordinateSequence *triangleCoord,
+	bool isTriangleErodedCompletely(const geom::CoordinateSequence *triCoords,
 			double bufferDistance);
 
     // Declare type as noncopyable

Modified: trunk/src/operation/buffer/OffsetCurveSetBuilder.cpp
===================================================================
--- trunk/src/operation/buffer/OffsetCurveSetBuilder.cpp	2011-04-20 15:55:53 UTC (rev 3290)
+++ trunk/src/operation/buffer/OffsetCurveSetBuilder.cpp	2011-04-20 17:13:13 UTC (rev 3291)
@@ -132,7 +132,12 @@
 void
 OffsetCurveSetBuilder::add(const Geometry& g)
 {
-	if (g.isEmpty()) return;
+  if (g.isEmpty()) {
+#if GEOS_DEBUG
+    std::cerr<<__FUNCTION__<<": skip empty geometry"<<std::endl;
+#endif
+    return;
+  }
 
 	const Polygon *poly = dynamic_cast<const Polygon *>(&g);
 	if ( poly ) {
@@ -217,22 +222,25 @@
 
 	// FIXME: avoid the C-style cast
 	const LinearRing *shell=(const LinearRing *)p->getExteriorRing();
-	CoordinateSequence *shellCoord = CoordinateSequence::removeRepeatedPoints(shell->getCoordinatesRO());
 
 	// optimization - don't bother computing buffer
 	// if the polygon would be completely eroded
-	if (distance < 0.0 && isErodedCompletely(shellCoord, distance))
+	if (distance < 0.0 && isErodedCompletely(shell, distance))
 	{
-		delete shellCoord;
+#if GEOS_DEBUG
+		std::cerr<<__FUNCTION__<<": polygon is eroded completely "<<std::endl;
+#endif
 		return;
 	}
 
-	// don't attemtp to buffer a polygon
+	// don't attempt to buffer a polygon
 	// with too few distinct vertices
+	CoordinateSequence *shellCoord =
+		CoordinateSequence::removeRepeatedPoints(shell->getCoordinatesRO());
 	if (distance <= 0.0 && shellCoord->size() < 3)
 	{
 		delete shellCoord;
-        	return;
+		return;
 	}
 
 	addPolygonRing(
@@ -249,16 +257,17 @@
 		const LineString *hls=p->getInteriorRingN(i);
 		assert(dynamic_cast<const LinearRing *>(hls));
 		const LinearRing *hole=static_cast<const LinearRing *>(hls);
-		CoordinateSequence *holeCoord=CoordinateSequence::removeRepeatedPoints(hole->getCoordinatesRO());
 
 		// optimization - don't bother computing buffer for this hole
 		// if the hole would be completely covered
-		if (distance > 0.0 && isErodedCompletely(holeCoord, -distance))
+		if (distance > 0.0 && isErodedCompletely(hole, -distance))
 		{
-			delete holeCoord;
 			continue;
 		}
 
+		CoordinateSequence *holeCoord =
+			CoordinateSequence::removeRepeatedPoints(hole->getCoordinatesRO());
+
 		// Holes are topologically labelled opposite to the shell,
 		// since the interior of the polygon lies on their opposite
 		// side (on the left, if the hole is oriented CCW)
@@ -306,18 +315,25 @@
 
 /*private*/
 bool
-OffsetCurveSetBuilder::isErodedCompletely(CoordinateSequence *ringCoord,
+OffsetCurveSetBuilder::isErodedCompletely(const LinearRing *ring,
 	double bufferDistance)
 {
-	double minDiam=0.0;
+	const CoordinateSequence *ringCoord = ring->getCoordinatesRO();
+
 	// degenerate ring has no area
 	if (ringCoord->getSize() < 4)
 		return bufferDistance < 0;
+
 	// important test to eliminate inverted triangle bug
 	// also optimizes erosion test for triangles
 	if (ringCoord->getSize() == 4)
 		return isTriangleErodedCompletely(ringCoord, bufferDistance);
 
+  const Envelope* env = ring->getEnvelopeInternal();
+  double envMinDimension = std::min(env->getHeight(), env->getWidth());
+  if (bufferDistance < 0.0 && 2 * std::abs(bufferDistance) > envMinDimension)
+      return true;
+
 	/**
 	 * The following is a heuristic test to determine whether an
 	 * inside buffer will be eroded completely->
@@ -330,20 +346,22 @@
 	 * a full topological computation->
 	 *
 	 */
-	LinearRing *ring=inputGeom.getFactory()->createLinearRing(*ringCoord);
+
+/* MD  7 Feb 2005 - there's an unknown bug in the MD code,
+ so disable this for now */
+#if 0
 	MinimumDiameter md(ring); //=new MinimumDiameter(ring);
-	minDiam=md.getLength();
-	delete ring;
+	double minDiam = md.getLength();
+	return minDiam < (2 * std::fabs(bufferDistance));
+#endif
 
-	//delete md;
-	//System->out->println(md->getDiameter());
-	return minDiam < (2 * std::fabs(bufferDistance));
+  return false;
 }
 
 /*private*/
 bool
 OffsetCurveSetBuilder::isTriangleErodedCompletely(
-	CoordinateSequence *triangleCoord, double bufferDistance)
+	const CoordinateSequence *triangleCoord, double bufferDistance)
 {
 	Triangle tri(triangleCoord->getAt(0), triangleCoord->getAt(1), triangleCoord->getAt(2));
 

Modified: trunk/tests/xmltester/Makefile.am
===================================================================
--- trunk/tests/xmltester/Makefile.am	2011-04-20 15:55:53 UTC (rev 3290)
+++ trunk/tests/xmltester/Makefile.am	2011-04-20 17:13:13 UTC (rev 3291)
@@ -30,6 +30,7 @@
 	$(srcdir)/tests/ticket/bug360.xml \
 	$(srcdir)/tests/ticket/bug366.xml \
 	$(srcdir)/tests/ticket/bug398.xml \
+	$(srcdir)/tests/ticket/bug434.xml \
 	$(srcdir)/tests/general/TestBoundary.xml \
 	$(srcdir)/tests/general/TestBuffer.xml \
 	$(srcdir)/tests/general/TestBufferMitredJoin.xml \

Added: trunk/tests/xmltester/tests/ticket/bug434.xml
===================================================================
--- trunk/tests/xmltester/tests/ticket/bug434.xml	                        (rev 0)
+++ trunk/tests/xmltester/tests/ticket/bug434.xml	2011-04-20 17:13:13 UTC (rev 3291)
@@ -0,0 +1,77 @@
+<run>
+  <desc>
+    http://trac.osgeo.org/geos/ticket/434
+  </desc>
+  <precisionModel type="FLOATING" />
+  <resultMatcher>com.vividsolutions.jtstest.testrunner.BufferResultMatcher</resultMatcher>
+
+<case>
+  <desc>
+    http://trac.osgeo.org/geos/ticket/434
+  </desc>
+  <a>
+010300000001000000260000000000000012E136C100000000584704C17CCA693DFB9437C15F3458D7B8CA0AC17CCA693DFB9437C15E3458D7B8CA0AC1A15FFC2B329E37C1BBC9994706040BC1A15FFC2B329E37C1BCC9994706040BC10000000005AD37C10000000070BE04C100000000371438C1000000003074FEC0000000004DAF38C100000000A0DFE7C000000000DA3D39C10000000000289DC000000000121639C1000000000005E54000000000900A39C100000000404AF74000000000C33B39C100000000D84A034100000000878538C10000000098A10141C50E55840D0238C1504578023004FF4028952472DBE037C1EFD75A166897FD40B301719AFEDB37C115B828D1D1A5FD40240E3BD05F0537C1FAC38571278CF740322F8AA7A60437C146F1AC8AA08BF7406F06AC4CCD0237C1A29F2ECC947EF74091E37943ACB336C1E9D63E5D7FEBF74000000000B6C435C10000000020F1F840000000000E1E35C100000000209EFA4000000000BCBB33C1000000008815014100000000CAEF33C1000000002032F74000000000EE5134C10000000000F1DB40000000008ADD34C1000000008099CBC0E42825B8ED4F35C13972434F3048EEC079DE4959ABE935C1B7656ADAE51FE0C051400DD809C635C1001FCAB19AC1AA4023302240A30436C144723E9FFB13E0C0A98
 D3A4CC8A436C1F7F77487DBB2DFC06E7AF552B50036C1D559460AE05EE2C07870019EB07335C1681A197BE5D2F0C0DCC23BB59DA135C1BFEB4186272FFDC014961A1FF69D35C1CDEE1C7F6F09FEC0D4BA81C7E60236C186226939A60305C10FAF8B543D0536C15716FC2B2C0D05C10000000012E136C100000000584704C1
+  </a>
+<test>
+  <op name='buffer' arg1='A' arg2='-9502'>
+POLYGON ((-1565260.6206011446 111732.66899895086, -1512637.4197541769
+87800.91348955338, -1511887.9553205783 87542.9550616941,
+-1511879.1656611576 87539.07911020475, -1510380.224568009
+87022.64683612906, -1508816.2815230151 86762.62982427831,
+-1507230.8751184365 86766.26668522462, -1487056.6518885682
+88501.80293939149, -1425965.3129563173 92682.16829688638,
+-1425104.6790447247 92780.63793183706, -1382440.6790447247
+99644.63793183706, -1380883.552616635 100032.3964705434,
+-1307581.025805522 125025.53084629907, -1315580.6801167233
+98046.05735775629, -1340013.0573368135 33475.88610080863,
+-1374723.4937759638 -8035.814646773755, -1375540.3966797974
+-9173.749061246888, -1399420.6762844694 -48224.22717737771,
+-1425311.2385910228 -29150.93862345213, -1417736.1160114263
+1117.9654269575603, -1417462.389107992 2977.2656135774496,
+-1417559.9528732277 4854.072719633237, -1418024.990767285
+6674.969026049172, -1418839.3112448766 8368.723955607617,
+-1419971.0593796924 9869.080500222728, -1421375.9629786243
+11117.347090073301, -1422999.064439784 12064.693514782575,
+-1424776.8706067775 12674.06108384778, -1426639.8365203394
+12921.612303871138, -1428515.0859069047 12797.663363516955,
+-1430329.261982915 12307.062948861332, -1432011.397055914
+11469.00257047849, -1433495.6886681858 10316.265821967412,
+-1434724.073684598 8893.945937735312, -1435648.499630413
+7257.681817144551, -1449143.4561333996 -23354.810616285424,
+-1483867.7348210595 -22958.05034354897, -1485776.6295743138
+-23129.542180347664, -1487612.279399581 -23680.612364703436,
+-1489300.0024860846 -24588.84108720258, -1490771.1352932872
+-25817.277855075656, -1491965.8260670996 -27315.944790741232,
+-1492835.4698562517 -29023.869938128897, -1493344.6859623056
+-30871.56785348871, -1493472.7573724887 -32783.86656001538,
+-1493214.473613273 -34682.965854105925, -1492580.3427339422
+-36491.60253873035, -1491596.1637957809 -38136.19380915876,
+-1490301.9772597842 -39549.830905140276, -1488750.4359754561
+-40675.00123540831, -1487004.6630455877 -41465.928227252676,
+-1485135.683717921 -41890.43370642135, -1446007.6029769813
+-46700.584262917684, -1416423.8835601667 -72339.85858975082,
+-1426885.4130973895 -117389.06894304338, -1427130.3703204703
+-119697.9017421352, -1426824.687619137 -121878.75478429934,
+-1448107.0131300709 -162332.10613743018, -1498347.8261209533
+-156680.5537782484, -1500189.4513298413 -156653.02325111572,
+-1502001.7906441302 -156981.3029334265, -1503716.7500390832
+-157653.05855387077, -1505269.8942919231 -158643.0506092964,
+-1506602.8679708943 -159914.08267462972, -1539977.4973322283
+-198577.71596101607, -1542144.8124445549 -169234.09042439144,
+-1542547.1855037627 -167113.735032329, -1543417.6618736198
+-165138.87251636875, -1569723.593278455 -120135.5955899725,
+-1609322.6038058014 -44486.34486061129, -1610234.1160785698
+-43067.65041476705, -1643974.2956479487 411.9052427339163,
+-1634783.2308133794 40946.81156439988, -1634563.0113663338
+42514.09863767898, -1631617.0113663338 94862.09863767898,
+-1631788.403045867 97268.87409831762, -1641289.145133498
+144525.1654491555, -1610591.364441635 135570.87839490557,
+-1578279.3072280572 118874.10762665431, -1570270.8915449486
+113373.9089381907, -1568640.3591467661 112475.31692187724,
+-1566865.9081669166 111911.91011199991, -1565260.6206011446
+111732.66899895086))
+  </op>
+</test>
+</case>
+
+</run>



More information about the geos-commits mailing list