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))
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 ]
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"])
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)
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
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)
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"])
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
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"])