[geos-commits] r3087 - in trunk: src/operation/buffer
src/operation/valid tests/xmltester/tests/general
svn_geos at osgeo.org
svn_geos at osgeo.org
Mon Jul 26 18:21:07 EDT 2010
Author: swongu
Date: 2010-07-26 22:21:07 +0000 (Mon, 26 Jul 2010)
New Revision: 3087
Modified:
trunk/src/operation/buffer/BufferBuilder.cpp
trunk/src/operation/valid/ConnectedInteriorTester.cpp
trunk/src/operation/valid/IsValidOp.cpp
trunk/tests/xmltester/tests/general/TestValid2.xml
Log:
Fixed a bufferLineSingleSided crash and fixed OGC validation on rare cases. (#364)
Modified: trunk/src/operation/buffer/BufferBuilder.cpp
===================================================================
--- trunk/src/operation/buffer/BufferBuilder.cpp 2010-07-15 15:54:52 UTC (rev 3086)
+++ trunk/src/operation/buffer/BufferBuilder.cpp 2010-07-26 22:21:07 UTC (rev 3087)
@@ -7,6 +7,7 @@
* Copyright (C) 2009 Sandro Santilli <strk at keybit.net>
* Copyright (C) 2005-2007 Refractions Research Inc.
* Copyright (C) 2001-2002 Vivid Solutions Inc.
+ * Copyright (C) 2008-2010 Safe Software Inc.
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
@@ -314,14 +315,22 @@
geomFact->destroyGeometry( singleSided );
geomFact->destroyGeometry( intersectedLines );
- if ( mergedLinesGeom->size() > 1 ) return geomFact->createMultiLineString( mergedLinesGeom );
- else
+ if ( mergedLinesGeom->size() > 1 )
+ {
+ return geomFact->createMultiLineString( mergedLinesGeom );
+ }
+ else if ( mergedLinesGeom->size() == 1 )
{
- // Must be a single line
+
Geometry* single = (*mergedLinesGeom)[0];
delete mergedLinesGeom;
return single;
}
+ else
+ {
+ delete mergedLinesGeom;
+ return NULL;
+ }
}
/*public*/
Modified: trunk/src/operation/valid/ConnectedInteriorTester.cpp
===================================================================
--- trunk/src/operation/valid/ConnectedInteriorTester.cpp 2010-07-15 15:54:52 UTC (rev 3086)
+++ trunk/src/operation/valid/ConnectedInteriorTester.cpp 2010-07-26 22:21:07 UTC (rev 3087)
@@ -4,6 +4,7 @@
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
+ * Copyright (C) 2007-2010 Safe Software Inc.
* Copyright (C) 2005-2006 Refractions Research Inc.
* Copyright (C) 2001-2002 Vivid Solutions Inc.
*
@@ -259,6 +260,9 @@
void
ConnectedInteriorTester::visitInteriorRing(const LineString *ring, PlanarGraph &graph)
{
+ // can't visit an empty ring
+ if(ring->isEmpty()) return;
+
const CoordinateSequence *pts=ring->getCoordinatesRO();
const Coordinate& pt0=pts->getAt(0);
Modified: trunk/src/operation/valid/IsValidOp.cpp
===================================================================
--- trunk/src/operation/valid/IsValidOp.cpp 2010-07-15 15:54:52 UTC (rev 3086)
+++ trunk/src/operation/valid/IsValidOp.cpp 2010-07-26 22:21:07 UTC (rev 3087)
@@ -4,6 +4,7 @@
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
+ * Copyright (C) 2010 Safe Software Inc.
* Copyright (C) 2010 Sandro Santilli <strk at keybit.net>
* Copyright (C) 2001-2002 Vivid Solutions Inc.
* Copyright (C) 2005 Refractions Research Inc.
@@ -370,12 +371,34 @@
const LinearRing *shell=static_cast<const LinearRing*>(
p->getExteriorRing());
+
+ int nholes = p->getNumInteriorRing();
+ if(shell->isEmpty())
+ {
+ for(int i=0; i<nholes; ++i)
+ {
+ assert(dynamic_cast<const LinearRing*>(
+ p->getInteriorRingN(i)));
+
+ const LinearRing *hole=static_cast<const LinearRing*>(
+ p->getInteriorRingN(i));
+
+ if(!hole->isEmpty())
+ {
+ validErr=new TopologyValidationError(
+ TopologyValidationError::eHoleOutsideShell);
+ return;
+ }
+ }
+ // all interiors also empty or none exist
+ return;
+ }
+
//SimplePointInRing pir(shell);
//SIRtreePointInRing pir(shell);
MCPointInRing pir(shell);
- int nholes = p->getNumInteriorRing();
for(int i=0; i<nholes; ++i)
{
assert(dynamic_cast<const LinearRing*>(
@@ -421,6 +444,9 @@
const LinearRing *innerHole=static_cast<const LinearRing*>(
p->getInteriorRingN(i));
+
+ //empty holes always pass
+ if(innerHole->isEmpty()) continue;
nestedTester.add(innerHole);
}
@@ -457,6 +483,8 @@
const Polygon *p2=static_cast<const Polygon *>(
mp->getGeometryN(j));
+ if (shell->isEmpty() || p2->isEmpty()) continue;
+
checkShellNotNested(shell, p2, graph);
if (validErr!=NULL) return;
@@ -619,7 +647,7 @@
void
IsValidOp::checkClosedRing(const LinearRing *ring)
{
- if ( ! ring->isClosed() )
+ if ( ! ring->isClosed() && ! ring->isEmpty() )
{
validErr = new TopologyValidationError(
TopologyValidationError::eRingNotClosed,
Modified: trunk/tests/xmltester/tests/general/TestValid2.xml
===================================================================
--- trunk/tests/xmltester/tests/general/TestValid2.xml 2010-07-15 15:54:52 UTC (rev 3086)
+++ trunk/tests/xmltester/tests/general/TestValid2.xml 2010-07-26 22:21:07 UTC (rev 3087)
@@ -5243,4 +5243,25 @@
</a>
<test> <op name="isValid" arg1="A"> true </op> </test>
</case>
+<case>
+ <desc>Test 752</desc>
+ <a>
+ POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260), EMPTY)
+ </a>
+ <test> <op name="isValid" arg1="A"> true </op> </test>
+</case>
+<case>
+ <desc>Test 753</desc>
+ <a>
+ POLYGON ((180 260, 80 300, 40 180, 160 120, 180 260), EMPTY, EMPTY)
+ </a>
+ <test> <op name="isValid" arg1="A"> true </op> </test>
+</case>
+<case>
+ <desc>Test 754</desc>
+ <a>
+ MultiPolygon(((10 10, 10 20, 20 20, 20 15, 10 10)),((60 60, 70 70, 80 60, 60 60 )), (EMPTY))
+ </a>
+ <test> <op name="isValid" arg1="A"> true </op> </test>
+</case>
</run>
More information about the geos-commits
mailing list