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

Primitive.prototype.convexHull does not support GeometryCollection #39

Open
jgravois opened this issue May 17, 2020 · 0 comments
Open
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@jgravois
Copy link
Member

from Esri/terraformer#313

I have geojson geometries that include GeometryCollections. The current implementation of convexHull in terraformer does not support "GeometryCollection" in convexHull.

I have made my own code that fixes convexHull. I'm attaching my code but it is in typescript.
You can use it as reference or easily addapt it to javascript.

Hopefully you can get this fixed in a future release.

public convexHull(): Polygon | null {
    function getCoordinates(shape: any) {
        let coordinates = [] as any;
        let i;
        let j;
        if (shape.type === 'Point') {
            if (shape.coordinates) {
                const returnArray = [];
                returnArray.push(shape.coordinates)
                return returnArray;
            } else {
                return null
            }
        } else if (shape.type === 'LineString' || shape.type === 'MultiPoint') {
            if (shape.coordinates) {
                return shape.coordinates;
            } else {
                return null;
            }
        } else if (shape.type === 'Polygon' || shape.type === 'MultiLineString') {
            if (shape.coordinates) {
                for (i = 0; i < shape.coordinates.length; i++) {
                    coordinates = coordinates.concat(shape.coordinates[i]);
                }
                if (coordinates) {
                    return coordinates;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        } else if (shape.type === 'MultiPolygon') {
            if (shape.coordinates && shape.coordinates.length > 0) {
                for (i = 0; i < shape.coordinates.length; i++) {
                    for (j = 0; j < shape.coordinates[i].length; j++) {
                        coordinates = coordinates.concat(shape.coordinates[i][j]);
                    }
                }
                if (coordinates) {
                    return coordinates;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        } else if (shape.type === 'GeometryCollection') {
            for (const index in shape.geometries) {
                if (index) {
                    const delta = getCoordinates(shape.geometries[index]);
                    if (delta) {
                        coordinates = coordinates.concat(delta);
                    } else {
                        return null;
                    }
                }
            }
            return coordinates;
        }
    }

    function pointsEqual(a: any, b: any) {
        for (let bb = 0; bb < a.length; bb++) {
            if (a[bb] !== b[bb]) {
                return false;
            }
        }
        return true;
    }

    function closedPolygon(coordinates2: any) {
        const outer = [];
        for (const coordinate of coordinates2) {
            const inner = coordinate.slice();
            if (pointsEqual(inner[0], inner[inner.length - 1]) === false) {
                inner.push(inner[0]);
            }
            outer.push(inner);
        }
        return outer;
    }

    let cords;
    if (this.type === "Feature") {
        cords = getCoordinates((this as any).geometry);
    } else {
        cords = getCoordinates(this);
    }

    if (cords && cords.length >= 3) {
        return new Terraformer.Polygon({
            coordinates: closedPolygon([Terraformer.Tools.convexHull(cords)]),
            type: 'Polygon'
        });
    } else {
        console.log("Invalid geometry. At least 3 coordinates are required to generate a convex hull.")
        return null
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant