Esri / geometry-api-java

The Esri Geometry API for Java enables developers to write custom applications for analysis of spatial data. This API is used in the Esri GIS Tools for Hadoop and other 3rd-party data processing solutions.
Apache License 2.0
694 stars 260 forks source link

Weird clipping behaviour #296

Closed nsiatras closed 2 years ago

nsiatras commented 2 years ago

Hello,

I am trying to clip a polyline. The input and result are as the following image. As you can see the result is not complete, it is exactly half.

image

Also see:

Before clipping: image

After Clipping: image

The code I am using is the following

public static ArrayList<Position> ClipPolygon(final ArrayList<double[]> clipper, final ArrayList<double[]> subject)
    {
        ArrayList<Position> result = new ArrayList<>();

        // Create a Polygon for clipper
        com.esri.core.geometry.Polygon clipperPoly = new com.esri.core.geometry.Polygon();
        clipperPoly.startPath(clipper.get(0)[0], clipper.get(0)[1]);
        for (int i = 1; i < clipper.size(); i++)
        {
            clipperPoly.lineTo(clipper.get(i)[0], clipper.get(i)[1]);
        }

        // Create a Polyline for subject
        Polyline line = new Polyline();
        line.startPath(subject.get(0)[0], subject.get(0)[1]);
        for (int i = 1; i < subject.size(); i++)
        {
            line.lineTo(subject.get(i)[0], subject.get(i)[1]);
        }

        // Create a spatial reference object for GCS_WGS_1984.
        SpatialReference sr = SpatialReference.create(4326);

        SimpleGeometryCursor inputGeometries = new SimpleGeometryCursor(line);
        SimpleGeometryCursor intersector = new SimpleGeometryCursor(clipperPoly);

        GeometryCursor outGeoms = OperatorIntersection.local().execute(inputGeometries, intersector, sr, null, -1);

        Geometry geom;
        while ((geom = outGeoms.next()) != null)
        {
            if (geom instanceof Polyline)
            {
                Polyline pLine = (Polyline) geom;

                for (int i = 0; i < pLine.getPathCount(); i++)
                {
                    result.add(new Position(pLine.getPoint(i).getX(), pLine.getPoint(i).getY(), 0));
                }
            }
        }

        return result;
    }

All ideas are welcome

stolstov commented 2 years ago

@nsiatras Result of polyline after intersection is probably a set of disconnected paths. Here is how to visit all paths and vertices in each path:

                for (int ipath = 0; ipath < pLine.getPathCount(); ipath ++)
                {
                    for (int i = pLine.getPathStart(ipath); i < pLine.getPathEnd(ipath); i++)
                    {
                        pLine.getPoint(i).getX();
                        pLine.getPoint(i).getY();
                    }
                }
nsiatras commented 2 years ago

@stolstov Thank you very much for your reply

Edited: It works excellent and I can tell it is very fast! Thanks again!

stolstov commented 2 years ago

@nsiatras If your intent to clip with axis-aligned rectangle (as clipping geometry for display on rectangular screen), then OperatorClip is more optimized for this.