Пример #1
0
def centroid(features, options=None):
    """
    Takes one or more features and calculates the centroid using the mean of all vertices.
    This lessens the effect of small islands and artifacts when calculating the centroid of a set of polygons.

    :param features: GeoJSON features to be centered
    :param options: optional parameters
        [options["properties"]={}] Translate GeoJSON Properties to Point
    :return: a Point feature corresponding to the centroid of the input features
    """

    if not options:
        options = {}

    coords = get_coords_from_features(features)

    if get_input_dimensions(coords) == 1:
        coords = [coords]

    x_sum = 0
    y_sum = 0
    length = 0

    x_sum, y_sum, length = reduce(reduce_coords, coords,
                                  [x_sum, y_sum, length])

    return point([x_sum / length, y_sum / length],
                 options.get("properties", None))
Пример #2
0
def reduce_coords(sum_array, coords):

    input_dimension = get_input_dimensions(coords)

    if input_dimension >= 2:
        return reduce(lambda prev, coord: reduce_coords(prev, coord), coords,
                      sum_array)

    return [
        sum_array[0] + coords[0], sum_array[1] + coords[1], sum_array[2] + 1
    ]
Пример #3
0
    def _check_input(coordinates: Sequence) -> None:
        """
        Checks input given to Point class, and raises an error if input is invalid.

        :param coordinates: input coordinates
        """

        if (get_input_dimensions(coordinates) == 1 and len(coordinates) == 2
                and all(isinstance(x, (int, float)) for x in coordinates)):
            return

        raise InvalidInput(error_code_messages["InvalidPointInput"])
Пример #4
0
    def _check_input(self, coordinates: Sequence) -> None:
        """
        Checks input given to MultiPoint class, and raises an error if input is invalid.

        :param coordinates: input coordinates
        """

        if get_input_dimensions(coordinates) != 2:
            raise InvalidInput(error_code_messages["InvalidMultiInput"] +
                               "of Points")

        for coord in coordinates:
            super(MultiPoint, self)._check_input(coord)
Пример #5
0
def reduce_coordinates_to_points(
    coords: Sequence, properties: Dict
) -> Sequence[Feature]:
    """
    Transforms dimensionality of the incoming coordinates into Point Features

    :param coords: any sequence of coordinates
    :param properties: properties of the coordinates sequence
    :return: {Feature} points of transformed coordinates
    """

    dim = get_input_dimensions(coords)

    if dim == 1:
        coords = [coords]

    while dim > 2:
        coords = [c for coord in coords for c in coord]
        dim = get_input_dimensions(coords)

    points = [point(coord, properties) for coord in coords]

    return points
Пример #6
0
def bbox(features):
    """
    Takes a set of features and returns a bounding box containing of all input features.

    :param features: any GeoJSON feature or feature collection
    :return: bounding box extent in [minX, minY, maxX, maxY] order
    """

    bounding_box = [np.inf, np.inf, -np.inf, -np.inf]

    coords = get_coords_from_features(features)

    if get_input_dimensions(coords) == 1:
        coords = [coords]

    return reduce(reduce_coords, coords, bounding_box)
Пример #7
0
    def _check_input(self, coordinates: Sequence) -> None:
        """
        Checks input given to LineString class, and raises an error if input is invalid.

        :param coordinates: input coordinates
        """

        if get_input_dimensions(coordinates) != 2:
            raise InvalidInput(error_code_messages["InvalidLineStringInput"])

        if len(coordinates) >= 2 and all(
                all(isinstance(x, (int, float)) for x in y)
                for y in coordinates):
            return

        raise InvalidInput(error_code_messages["InvalidLinePoints"])
Пример #8
0
def reduce_coords(bounding_box, coord):

    input_dimension = get_input_dimensions(coord)

    if input_dimension >= 2:
        return reduce(lambda bb, c: reduce_coords(bb, c), coord, bounding_box)

    if bounding_box[0] > coord[0]:
        bounding_box[0] = coord[0]
    if bounding_box[1] > coord[1]:
        bounding_box[1] = coord[1]
    if bounding_box[2] < coord[0]:
        bounding_box[2] = coord[0]
    if bounding_box[3] < coord[1]:
        bounding_box[3] = coord[1]

    return bounding_box
Пример #9
0
    def _check_input(self, coordinates: Sequence) -> None:
        """
        Checks input given to Polygon class, and raises an error if input is invalid.

        :param coordinates: input coordinates
        """

        if get_input_dimensions(coordinates) != 3:
            raise InvalidInput(error_code_messages["InvalidPolygonInput"])

        for ring in coordinates:
            if not isinstance(ring, list):
                raise InvalidInput(error_code_messages["InvalidLinearRing"])

            if len(ring) < 4:
                raise InvalidInput(error_code_messages["InvalidLinearRing"])

            if ring[-1] != ring[0]:
                raise InvalidInput(
                    error_code_messages["InvalidFirstLastPoints"])