Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Union Operations returns collections containing empty elements #1224

Open
nbvfgh opened this issue Jan 9, 2025 · 6 comments
Open

Union Operations returns collections containing empty elements #1224

nbvfgh opened this issue Jan 9, 2025 · 6 comments
Labels

Comments

@nbvfgh
Copy link

nbvfgh commented Jan 9, 2025

Relates to: https://trac.osgeo.org/postgis/ticket/5835

Reproduce in GEOS:

geosop -a 'GEOMETRYCOLLECTION(POLYGON EMPTY, POINT EMPTY, LINESTRING(10 10, 10 10))' -b 'POINT(1 1)' union
-- reuslt:{GEOMETRYCOLLECTION (POLYGON EMPTY, POINT EMPTY, LINESTRING (10 10, 10 10), POINT (1 1))}

geosop -a 'GEOMETRYCOLLECTION(POLYGON EMPTY, POINT EMPTY, LINESTRING(10 10, 10 10), POINT(1 1))' unaryUnion
-- result:{GEOMETRYCOLLECTION (POINT (1 1), LINESTRING EMPTY)}
@dr-jts
Copy link
Contributor

dr-jts commented Jan 9, 2025

Interesting - in JTS the unary union gives the expected result:

POINT (1 1)

@dr-jts dr-jts added the Bug label Jan 9, 2025
@dr-jts
Copy link
Contributor

dr-jts commented Jan 9, 2025

A simpler case for unary union:

bin/geosop -a 'GEOMETRYCOLLECTION(LINESTRING(10 10, 10 10), POINT(1 1))' unaryUnion 
--> GEOMETRYCOLLECTION (POINT (1 1), LINESTRING EMPTY)

The ideal result is probably

 GEOMETRYCOLLECTION (LINESTRING(10 10, 10 10), POINT (1 1))

@nbvfgh
Copy link
Author

nbvfgh commented Jan 9, 2025

A simpler case for unary union:

bin/geosop -a 'GEOMETRYCOLLECTION(LINESTRING(10 10, 10 10), POINT(1 1))' unaryUnion 
--> GEOMETRYCOLLECTION (POINT (1 1), LINESTRING EMPTY)

The ideal result is probably

 GEOMETRYCOLLECTION (LINESTRING(10 10, 10 10), POINT (1 1))

Yes, dicussion in #1136 indicate that a Linestring of 0 length or a Area of 0 size should return a point or at least be retained.

@dr-jts
Copy link
Contributor

dr-jts commented Jan 10, 2025

The cause of the union anomaly is the heuristic code in Geometry::Union, which combines the two inputs if their envelopes are disjoint. It does not check for empty geometries (and in general does not reduce geometries to a more canonical form, which performing an explicit union would do).

This code should be enhanced to remove empty elements.

Actually I'm in favour of removing it altogether, since it creates other behaviour differences with OverlayNG (for example, it does not node disjoint sets of LineStrings). Or at least refining it significantly, and perhaps moving it into OverlayNG, since it is then available everywhere. At very least it can be moved into HeuristicOverlay.

In general I think it's better to avoid putting heuristic logic into Geometry methods, because:

  • complex heuristic logic complicates the Geometry class
  • it splits up the logic for operations and makes it less widely available

@pramsey
Copy link
Member

pramsey commented Jan 10, 2025

I guess it depends on just how fast the fast path through OverlayNG is, for the "union of disjoint things"?

@dr-jts
Copy link
Contributor

dr-jts commented Jan 10, 2025

I guess it depends on just how fast the fast path through OverlayNG is, for the "union of disjoint things"?

It should provide similar performance, apart from a bit of overhead from a few more calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants