jts icon indicating copy to clipboard operation
jts copied to clipboard

GeometryCollection difference

Open halset opened this issue 3 years ago • 2 comments

Should we add support for Geometry.difference from/to a non-empty GeometryCollection? I just made a method for this in one of my projects to get around some Exceptions, but having support for more such operations for GeometryCollection would make it easier to use JTS.

halset avatar Jan 31 '22 06:01 halset

I made an RFC for this: #761. It needs a bit more detail about the exact semantics, however. What is the behaviour that you are proposing?

dr-jts avatar Jan 31 '22 15:01 dr-jts

For difference, I am currently doing this:

  • If left side is GeometryCollection, then do difference on each of the collections geometries with the right side and then union the result.
  • If the right side is GeometryCollection, then subtract all of the collections geometries from the left side.

This is the utility method I now use to do this. Perhaps GeometryCollection.difference could do something similar.

    public static Geometry difference(Geometry g0, Geometry g1) {

        if (g0.getClass().equals(GeometryCollection.class)) {
            // left side is geometry collection
            GeometryCollection gc = (GeometryCollection) g0;

            List<Geometry> geoms = new ArrayList<>(g0.getNumGeometries());
            for (int i = 0; i < gc.getNumGeometries(); i++) {
                Geometry g = gc.getGeometryN(i);
                g = difference(g, g1);
                if (!g.isEmpty()) {
                    geoms.add(g);
                }
            }

            if (geoms.isEmpty()) {
                return // empty;
            }

            Geometry result = UnaryUnionOp.union(geoms);

            if (result == null) {
                return // empty;
            }

            return result;
        } else if (g1.getClass().equals(GeometryCollection.class)) {
            // right side is geometry collection
            GeometryCollection gc = (GeometryCollection) g1;

            Geometry result = g0;
            for (int i = 0; i < gc.getNumGeometries(); i++) {
                Geometry g = gc.getGeometryN(i);
                result = difference(result, g);
            }
            return result;
        }

        return g0.difference(g1);
    }

Today, I also got trapped with the same issue for the union operation and worked around it in a similar way.

halset avatar Feb 03 '22 10:02 halset