The (somewhat simplistic) snapping heuristic currently in JTS tends to have
issues with geometries which (a) contain many nearly coincident segments or
(b) contain topology which is "close to invalid" - e.g. narrow slivers,
gores or holes.

Unfortunately, your A.union(AB) situation exhibits both of these
syndromes...  A has a lot of similar segments to AB (not surprisingly), and
AB contains narrow gores and a very narrow hole.  So that's why snapping
isn't able to deal with this effectively.

The more effective way of reducing topology failures is to reduce the
precision of the inputs.  It looks to me like the geometries contain a lot
of unnecessary precision.  Perhaps they could be precision-reduced to say 8
decimal places?  Use GeometryPrecisionReducer to do this.  When I tried
this on the geometries below, the A.union(AB) example worked:


POLYGON ((151.33165600113327 -33.49995421900626, 151.33175839
-33.50049687999996, 151.33175839 -33.50049688, 151.33085839 -33.50059688,
151.32785839 -33.50059688, 151.3259956451168 -33.50037335061402,
151.32535839000002 -33.50029688000001, 151.32411293468047
-33.506079351126324, 151.32395839 -33.50679688, 151.32605839 -33.50709688,
151.32765839 -33.50719688, 151.32695839 -33.51129688, 151.32625839
-33.51429688, 151.32615839 -33.51479688, 151.32575839 -33.51729688,
151.32555839 -33.51839688, 151.32485839 -33.52219688, 151.32865839
-33.52259688, 151.32845839 -33.52459688, 151.32265839 -33.52509688,
151.32015839 -33.52579688, 151.31715839 -33.52719688, 151.31815839
-33.52139688, 151.31985839 -33.52159688, 151.32015839 -33.51999688,
151.31695839 -33.51959688, 151.31675839 -33.52139688, 151.31545839
-33.52819688, 151.31265839 -33.52979688, 151.31155839 -33.53319688,
151.31265839 -33.53459688, 151.30925839 -33.53559688, 151.29595839
-33.53609688, 151.29645839 -33.53379688, 151.29765839 -33.52799688,
151.29885839 -33.52239688, 151.30015839 -33.51589688, 151.30135839
-33.50989688, 151.30165839 -33.50869688, 151.30175839 -33.50789688,
151.29855839 -33.50749688, 151.29925839 -33.50429688, 151.29705839
-33.50389688, 151.29725839 -33.50279688, 151.29735398471678
-33.50222331169926, 151.29735839 -33.50219688, 151.29505839000012
-33.50179688000002, 151.29400124729491 -33.50695045068732, 151.29345839
-33.50959688, 151.29345838999996 -33.50959687999999, 151.29345838999996
-33.509596880000004, 151.2931250566379 -33.509563546663784, 151.29245839
-33.50949688, 151.29135839 -33.51469688, 151.28815839 -33.51419688,
151.28815839 -33.51419687999994, 151.28815838999992 -33.51419687999993,
151.29035198512716 -33.50367887259539, 151.29205839 -33.49549688,
151.28885839 -33.49399688, 151.2888583900001 -33.49399687999999,
151.28885838999997 -33.49399687999994, 151.29239380119407
-33.49381557686184, 151.29275839 -33.49379688, 151.29275839
-33.493796880000005, 151.29275839000024 -33.49379687999999,
151.29395839000006 -33.49479687999997, 151.29525838999996
-33.49599687999995, 151.29955839000013 -33.49549687999996,
151.30025838999995 -33.49549687999996, 151.30367497628635
-33.49600096650126, 151.30635839 -33.49639688, 151.30839882146446
-33.494664438190554, 151.31165838999993 -33.49189688000001, 151.31165839
-33.491896880000006, 151.31165839 -33.49189688, 151.31565838999998
-33.49139688000001, 151.31818735735206 -33.489176323300626, 151.32385839
-33.48419688, 151.32385839130671 -33.48419677677434, 151.32394830607632
-33.47709350997866, 151.32394830994195 -33.477093514584524, 151.32394831
-33.47709351, 151.32399231380268 -33.47714594471653, 151.32403683439372
-33.4771989905272, 151.3245583900001 -33.483196879999866,
151.32645839000008 -33.48389687999986, 151.33574164113446
-33.484356446887844, 151.33655839 -33.48439688, 151.33655839
-33.48439688000001, 151.33655839000016 -33.48439688000002,
151.33432182989543 -33.48847860219086, 151.33255839 -33.49169688,
151.33075839 -33.49519688, 151.33165600113327 -33.49995421900626))


On Mon, Jul 13, 2015 at 12:59 PM, Joe Amenta <[email protected]> wrote:

> Hey all,
>
> I've got an interesting problem.  I've only tested it with NTS, but I'm
> sure it's an issue in JTS as well, and it shouldn't be terribly hard for
> someone with a JTS environment already set up to confirm.
>
> Consider the following two geometries, named "A" and "B", respectively:
>
> A: POLYGON ((151.33075838999991 -33.495196879999924, 151.33175839
> -33.500496879999957, 151.33085839000012 -33.500596879999989,
> 151.32785838999996 -33.500596879999989, 151.32535839000002
> -33.500296880000008, 151.32395839000003 -33.506796879999854,
> 151.31945839000002 -33.506296879999979, 151.31925838999996
> -33.506996879999974, 151.31615838999994 -33.506596880000018, 151.31545839
> -33.506496879999986, 151.31125839000026 -33.505896880000023, 151.30685839
> -33.505196879999914, 151.30175838999992 -33.504496879999976,
> 151.29725839000025 -33.502796880000005, 151.29735839 -33.502196879999929,
> 151.29505839000012 -33.501796879999972, 151.29345838999996
> -33.509596880000004, 151.29245838999998 -33.509496879999972,
> 151.29135839000003 -33.5146968799998, 151.28815838999992
> -33.514196879999929, 151.29205839000008 -33.495496879999962,
> 151.28885838999997 -33.493996879999941, 151.29275839000025
> -33.493796879999991, 151.29395839000006 -33.494796879999967,
> 151.29525838999996 -33.49599687999995, 151.29955839000013
> -33.495496879999962, 151.30025838999995 -33.495496879999962, 151.30635839
> -33.49639688000002, 151.31165838999993 -33.491896880000013,
> 151.31565838999995 -33.491396880000025, 151.32385839000006
> -33.484196880000013, 151.32394830607632 -33.477093509978658,
> 151.32403683439372 -33.4771989905272, 151.32455839000011
> -33.483196879999866, 151.32645839000008 -33.483896879999861,
> 151.33655839000016 -33.48439688000002, 151.33255838999992
> -33.491696879999893, 151.33075838999991 -33.495196879999924))
>
> B: POLYGON ((151.31615838999994 -33.506596880000004, 151.31925838999993
> -33.506996879999974, 151.31945839000005 -33.506296879999965,
> 151.32395839000006 -33.506796879999939, 151.32605839000007
> -33.507096879999985, 151.32765839000012 -33.50719687999991,
> 151.32695839000004 -33.511296879999946, 151.32625839000002
> -33.514296880000018, 151.32615838999993 -33.514796879999992,
> 151.32575839000003 -33.517296879999989, 151.32555839000011
> -33.518396880000054, 151.32485839 -33.522196879999967, 151.32865839000002
> -33.522596879999931, 151.32845839000007 -33.524596880000033,
> 151.32265839000013 -33.525096879999921, 151.32015838999996
> -33.525796880000023, 151.31715838999992 -33.527196879999948,
> 151.31815839000012 -33.521396879999941, 151.31985839000004
> -33.521596879999969, 151.32015838999996 -33.519996880000008,
> 151.31695839000005 -33.519596879999952, 151.31675839000002
> -33.521396879999941, 151.31545839000003 -33.528196879999911,
> 151.31265839000017 -33.529796879999964, 151.3115583900001
> -33.533196879999991, 151.31265839000017 -33.534596879999924,
> 151.30925838999997 -33.535596879999972, 151.29595839000007
> -33.536096879999953, 151.29645839000003 -33.533796879999983,
> 151.29765839000012 -33.527996879999975, 151.29885838999994
> -33.5223968799999, 151.30015839000009 -33.515896879999971,
> 151.30135839000002 -33.509896879999928, 151.30165838999997
> -33.508696879999945, 151.30175838999989
> -33.507896879999919,151.29855839000007 -33.507496879999948,
> 151.29925838999998 -33.504296879999949, 151.29705839000013
> -33.503896879999985, 151.29725839000014 -33.502796880000005,
> 151.30175838999989 -33.504496879999976,151.30685838999997
> -33.5051968799999, 151.31125839000015 -33.505896879999995,
> 151.31545839000003 -33.506496879999986, 151.31615838999994
> -33.506596880000004))
>
> AB = A.Union(B) -- works like a charm
> BAB = B.Union(AB) -- also works just fine
> AAB = A.Union(AB) -- throws even after snapping... the post-snap exception
> is in DirectedEdgeStar.LinkResultDirectedEdges(): no outgoing dirEdge found
> [ (0.0077441045222599314, -0.50638418161354082, NaN) ]
>
> This is the underlying cause of a failure of a much larger operation.  In
> the real-world scenario it came from, there are other things unioned
> together with "A" and other things unioned together with "B", so in the
> real-world it winds up being something more like "UNION(UNION(A, Z, Y,
> ...), UNION(A, B, X, W, ...), ...)" where we need to keep all intermediate
> polygons as well as their union.
>
> Any tips on how to work around this?  I'm hoping for something better than
> using the user data to tag each aggregated polygon with its list of
> leaf-level children (so the first would be conceptually tagged as "A, Z, Y,
> ...") and then replacing our code that does the final union to fetch the
> leaf-level children back again to ensure we never have to union two
> overlapping geometries... this would obviously make already slow operation
> even slower, not to mention how expensive that solution would be in terms
> of development effort...
>
>
>
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
Jts-topo-suite-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jts-topo-suite-user

Reply via email to