<br><font size=2 face="sans-serif">Unfortunately, coincident geometries
are the norm in our case. The two in the example I gave are the results
of previous differences with a third overlapping polygon(s).</font>
<br>
<br><font size=2 face="sans-serif">I tried Ben's suggestion first and got
a compile error about a missing include file (this is all on a x86_64 Linux
install using a very recent svn version). Thought you might want to know.</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; geos/include/geos/geom/BinaryOp.h:54:44:
error: geos/precision/GeometrySnapper.h: No such file or directory</font>
<br>
<br><font size=2 face="sans-serif">GeometrySnapper.h is listed in</font>
<br><font size=2 face="sans-serif">&nbsp; noinst_HEADERS</font>
<br><font size=2 face="sans-serif">of</font>
<br><font size=2 face="sans-serif">&nbsp; source/headers/geos/precision/Makefile</font>
<br>
<br><font size=2 face="sans-serif">Just to see what would happen I copied
the file to</font>
<br><font size=2 face="sans-serif">&nbsp; include/geos/precision</font>
<br><font size=2 face="sans-serif">and it compiled, linked, and ran successfully.</font>
<br><font size=2 face="sans-serif"><br>
Stuart</font>
<br><font size=2 face="sans-serif"><br>
</font>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>Ben Jubb &lt;benjubb@refractions.net&gt;</b>
</font>
<br><font size=1 face="sans-serif">Sent by: geos-devel-bounces@geos.refractions.net</font>
<p><font size=1 face="sans-serif">09/19/2007 01:54 PM</font>
<table border>
<tr valign=top>
<td bgcolor=white>
<div align=center><font size=1 face="sans-serif">Please respond to<br>
GEOS Development List &lt;geos-devel@geos.refractions.net&gt;</font></div></table>
<br>
<td width=59%>
<table width=100%>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td><font size=1 face="sans-serif">GEOS Development List &lt;geos-devel@geos.refractions.net&gt;</font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td><font size=1 face="sans-serif">Re: [geos-devel] no outgoing dirEdge
found error</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><font size=2><tt>There is a way to make this particular operation succeed
in GEOS, which <br>
is to use the BinaryOp method instead of difference(). &nbsp;For example,
the <br>
following code works (in MSVC8):<br>
<br>
<br>
#include &lt;string&gt;<br>
#include &lt;iostream&gt;<br>
<br>
#include &lt;geos/geom/PrecisionModel.h&gt;<br>
#include &lt;geos/geom/GeometryFactory.h&gt;<br>
#include &lt;geos/geom/Geometry.h&gt;<br>
#include &lt;geos/geom/MultiPolygon.h&gt;<br>
#include &lt;geos/io/WKTReader.h&gt;<br>
<br>
#include &lt;geos/geom/BinaryOp.h&gt;<br>
#include &lt;geos/operation/overlay/OverlayOp.h&gt;<br>
<br>
using namespace geos;<br>
<br>
int main (int argc, char *argv[])<br>
{<br>
 &nbsp; &nbsp;using namespace operation::overlay;<br>
 &nbsp;typedef std::auto_ptr&lt; geom::Geometry &gt; GeomAutoPtr;<br>
<br>
 &nbsp;std::string mp1s = &quot;MULTIPOLYGON (((88.0541300495810049 <br>
-40.3914336120775417,&quot;<br>
 &nbsp; &nbsp;&quot; 88.0013586636740683 -40.3952580652168507,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9856522556763849 -40.3125682141688557,&quot;<br>
 &nbsp; &nbsp;&quot; 88.0410955427405639 -40.3084853410231361,&quot;<br>
 &nbsp; &nbsp;&quot; 88.0447770149226727 -40.3320733430391556,&quot;<br>
 &nbsp; &nbsp;&quot; 88.0541300495810049 -40.3914336120775417)),&quot;<br>
 &nbsp; &nbsp;&quot; ((87.9569549228361041 -40.1614847724049824,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9856522556763849 -40.3125682141688557,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9594803530699494 -40.3144955269957563,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9484023890450430 -40.2597855714132962,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9236385364479673 -40.1638760511710515,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9569549228361041 -40.1614847724049824)))&quot;;<br>
<br>
 &nbsp;std::string mp2s = &quot;MULTIPOLYGON (((87.7184147523609425 <br>
-40.3314878875577705,&quot;<br>
 &nbsp; &nbsp;&quot; 87.7106409229361930 -40.2916861830969211,&quot;<br>
 &nbsp; &nbsp;&quot; 87.6363928113999862 -39.9074815079801084,&quot;<br>
 &nbsp; &nbsp;&quot; 87.8588765594887349 -39.8933226300382628,&quot;<br>
 &nbsp; &nbsp;&quot; 88.3245648150878964 -39.8616404104367064,&quot;<br>
 &nbsp; &nbsp;&quot; 88.3252910982550503 -39.8653834273614933,&quot;<br>
 &nbsp; &nbsp;&quot; 88.4058355104796334 -40.2774282017416283,&quot;<br>
 &nbsp; &nbsp;&quot; 88.4066631207306273 -40.2815647501607259,&quot;<br>
 &nbsp; &nbsp;&quot; 87.9574816223991007 -40.3146427145853394,&quot;<br>
 &nbsp; &nbsp;&quot; 87.7184147523609425 -40.3314878875577705)))&quot;;<br>
<br>
 &nbsp;try {<br>
 &nbsp; &nbsp;geos::geom::PrecisionModel *model =<br>
 &nbsp; &nbsp; &nbsp; &nbsp;new <br>
geos::geom::PrecisionModel(geos::geom::PrecisionModel::FLOATING);<br>
 &nbsp; &nbsp;geos::geom::GeometryFactory *factory = new <br>
geos::geom::GeometryFactory(model);<br>
<br>
 &nbsp; &nbsp;geos::io::WKTReader *wkt = new geos::io::WKTReader();<br>
 &nbsp; &nbsp;geos::geom::MultiPolygon *mp1 = (geos::geom::MultiPolygon
<br>
*)wkt-&gt;read(mp1s);<br>
 &nbsp; &nbsp;geos::geom::MultiPolygon *mp2 = (geos::geom::MultiPolygon
<br>
*)wkt-&gt;read(mp2s);<br>
<br>
 &nbsp; &nbsp;std::cout &lt;&lt; &quot;Is valid of one = &quot; &lt;&lt;
mp1-&gt;isValid() &lt;&lt; std::endl;<br>
 &nbsp; &nbsp;std::cout &lt;&lt; &quot;Is valid of two = &quot; &lt;&lt;
mp2-&gt;isValid() &lt;&lt; std::endl;<br>
<br>
 &nbsp; &nbsp;//geos::geom::Geometry *diff = mp1-&gt;difference(mp2);<br>
<br>
 &nbsp; &nbsp;GeomAutoPtr gRealRes = BinaryOp(mp1, mp2, <br>
overlayOp(OverlayOp::opDIFFERENCE));<br>
<br>
 &nbsp; &nbsp;std::cout &lt;&lt; mp1-&gt;toString() &lt;&lt; std::endl;<br>
 &nbsp; &nbsp;std::cout &lt;&lt; mp2-&gt;toString() &lt;&lt; std::endl;<br>
 &nbsp; &nbsp;//std::cout &lt;&lt; diff-&gt;toString() &lt;&lt; std::endl;<br>
 &nbsp; &nbsp;std::cout &lt;&lt; gRealRes.get()-&gt;toString() &lt;&lt;
std::endl;<br>
<br>
 &nbsp;}<br>
 &nbsp;catch (std::exception const &amp;se) {<br>
 &nbsp; &nbsp;std::cout &lt;&lt; &quot;ERROR - &quot; &lt;&lt; se.what()
&lt;&lt; std::endl;<br>
 &nbsp;}<br>
 &nbsp;catch (...) {<br>
 &nbsp; &nbsp;std::cout &lt;&lt; &quot;General error&quot; &lt;&lt; std::endl;<br>
 &nbsp;}<br>
<br>
}<br>
<br>
<br>
BInaryOp does the same difference op, but when that fails it tries again
<br>
after shifting the geometry close to the origin. &nbsp;Presumably this
gains <br>
a few bits of precision in the intermediate results, that allows the <br>
operation to succeed. &nbsp;This method is perhaps not as robust tho.<br>
<br>
b<br>
<br>
<br>
Martin Davis wrote:<br>
&gt; This computation works fine in the current version of JTS. &nbsp;This
may <br>
&gt; indicate a porting bug in GEOS, or a slightly different choice of
<br>
&gt; tolerances.<br>
&gt;<br>
&gt; This is a classic case which causes robustness problems - overlaying
<br>
&gt; two geometries with linework which is almost coincident.<br>
&gt;<br>
&gt; The only suggestion I can make is to reduce the precision of your
data <br>
&gt; slightly in cases which fail. &nbsp;Presumably your source data isn't
<br>
&gt; actually accurate to 16 decimal places? &nbsp; It could be a while
before <br>
&gt; we can look at the GEOS code for this.<br>
&gt;<br>
&gt; Stuart C Sides wrote:<br>
&gt;&gt;<br>
&gt;&gt; Hi GEOS devels,<br>
&gt;&gt;<br>
&gt;&gt; We are writing a C++ application which is looking for areas of
<br>
&gt;&gt; overlap between 1000's &nbsp;of polygons. The app is being<br>
&gt;&gt; developed on Linux with g++ 4.1.0.<br>
&gt;&gt;<br>
&gt;&gt; We first tried the stable release of GEOS 2.2.3 and received this
<br>
&gt;&gt; error after processing several polygons:<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; TopologyException: found non-noded intersection
between 87.9595 <br>
&gt;&gt; -40.3145, 87.9484 -40.2598 and 87.9857 -40.3126, 87.9575 -40.3146
<br>
&gt;&gt; 87.9595 -40.3145<br>
&gt;&gt;<br>
&gt;&gt; While reviewing the list archives we found references to major
code <br>
&gt;&gt; changes that might fix some of these errors, so we<br>
&gt;&gt; upgraded to RC3 and eventually to an SVN version from 2007-09-18.
We <br>
&gt;&gt; got through a lot more polygons without errors,<br>
&gt;&gt; but finally received this error:<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; TopologyException: no outgoing dirEdge found 87.957
-40.1615<br>
&gt;&gt;<br>
&gt;&gt; Note: this coordinate is from the first segment of the second
polygon <br>
&gt;&gt; of the first multi-polygon below.<br>
&gt;&gt;<br>
&gt;&gt; In the original code, before I converted the multipolygons to
strings <br>
&gt;&gt; to create the example, we received this error:<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; TopologyException: no outgoing dirEdge found 87.7184
-40.3315<br>
&gt;&gt;<br>
&gt;&gt; Note: this coordinate is from the first segment of the second
<br>
&gt;&gt; multi-polygon below:<br>
&gt;&gt;<br>
&gt;&gt; I've boiled the error down to just a few lines of code, and would
<br>
&gt;&gt; appreciate any suggestions. &nbsp;The error is thrown at the<br>
&gt;&gt; difference.<br>
&gt;&gt;<br>
&gt;&gt; Thanks<br>
&gt;&gt; Stuart<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; #include &lt;string&gt;<br>
&gt;&gt; #include &lt;iostream&gt;<br>
&gt;&gt;<br>
&gt;&gt; #include &lt;geos/geom/PrecisionModel.h&gt;<br>
&gt;&gt; #include &lt;geos/geom/GeometryFactory.h&gt;<br>
&gt;&gt; #include &lt;geos/geom/Geometry.h&gt;<br>
&gt;&gt; #include &lt;geos/geom/MultiPolygon.h&gt;<br>
&gt;&gt; #include &lt;geos/io/WKTReader.h&gt;<br>
&gt;&gt;<br>
&gt;&gt; int main (int argc, char *argv[])<br>
&gt;&gt; {<br>
&gt;&gt; &nbsp; std::string mp1s = &quot;MULTIPOLYGON (((88.0541300495810049
<br>
&gt;&gt; -40.3914336120775417,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.0013586636740683 -40.3952580652168507,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9856522556763849 -40.3125682141688557,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.0410955427405639 -40.3084853410231361,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.0447770149226727 -40.3320733430391556,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.0541300495810049 -40.3914336120775417)),&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; ((87.9569549228361041 -40.1614847724049824,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9856522556763849 -40.3125682141688557,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9594803530699494 -40.3144955269957563,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9484023890450430 -40.2597855714132962,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9236385364479673 -40.1638760511710515,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9569549228361041 -40.1614847724049824)))&quot;;<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; std::string mp2s = &quot;MULTIPOLYGON (((87.7184147523609425
<br>
&gt;&gt; -40.3314878875577705,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.7106409229361930 -40.2916861830969211,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.6363928113999862 -39.9074815079801084,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.8588765594887349 -39.8933226300382628,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.3245648150878964 -39.8616404104367064,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.3252910982550503 -39.8653834273614933,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.4058355104796334 -40.2774282017416283,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 88.4066631207306273 -40.2815647501607259,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.9574816223991007 -40.3146427145853394,&quot;<br>
&gt;&gt; &nbsp; &nbsp; &quot; 87.7184147523609425 -40.3314878875577705)))&quot;;<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; try {<br>
&gt;&gt; &nbsp; &nbsp; geos::geom::PrecisionModel *model =<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; new <br>
&gt;&gt; geos::geom::PrecisionModel(geos::geom::PrecisionModel::FLOATING);<br>
&gt;&gt; &nbsp; &nbsp; geos::geom::GeometryFactory *factory = new <br>
&gt;&gt; geos::geom::GeometryFactory(model);<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; geos::io::WKTReader *wkt = new geos::io::WKTReader();<br>
&gt;&gt; &nbsp; &nbsp; geos::geom::MultiPolygon *mp1 = (geos::geom::MultiPolygon
<br>
&gt;&gt; *)wkt-&gt;read(mp1s);<br>
&gt;&gt; &nbsp; &nbsp; geos::geom::MultiPolygon *mp2 = (geos::geom::MultiPolygon
<br>
&gt;&gt; *)wkt-&gt;read(mp2s);<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; &quot;Is valid of one = &quot;
&lt;&lt; mp1-&gt;isValid() &lt;&lt; std::endl;<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; &quot;Is valid of two = &quot;
&lt;&lt; mp2-&gt;isValid() &lt;&lt; std::endl;<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; geos::geom::Geometry *diff = mp1-&gt;difference(mp2);<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; mp1-&gt;toString() &lt;&lt; std::endl;<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; mp2-&gt;toString() &lt;&lt; std::endl;<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; diff-&gt;toString() &lt;&lt;
std::endl;<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; }<br>
&gt;&gt; &nbsp; catch (std::exception const &amp;se) {<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; &quot;ERROR - &quot; &lt;&lt;
se.what() &lt;&lt; std::endl;<br>
&gt;&gt; &nbsp; }<br>
&gt;&gt; &nbsp; catch (...) {<br>
&gt;&gt; &nbsp; &nbsp; std::cout &lt;&lt; &quot;General error&quot; &lt;&lt;
std::endl;<br>
&gt;&gt; &nbsp; }<br>
&gt;&gt;<br>
&gt;&gt; }<br>
&gt;&gt; ------------------------------------------------------------------------<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; geos-devel mailing list<br>
&gt;&gt; geos-devel@geos.refractions.net<br>
&gt;&gt; http://geos.refractions.net/mailman/listinfo/geos-devel<br>
&gt;&gt; &nbsp; <br>
&gt;<br>
_______________________________________________<br>
geos-devel mailing list<br>
geos-devel@geos.refractions.net<br>
http://geos.refractions.net/mailman/listinfo/geos-devel<br>
</tt></font>
<br>