from typing import Dict, List, Sequence, TypeVar
from turf.invariant import get_coords_from_features, get_coords_from_geometry
from turf.helpers import feature_collection, point
from turf.helpers import Feature, FeatureCollection, Geometry
from turf.utils.helpers import get_input_dimensions
from turf.utils.error_codes import error_code_messages
from turf.utils.exceptions import InvalidInput
from turf.helpers._features import all_geometry_types
GeoJson = TypeVar("GeoJson", Dict, Feature, FeatureCollection, Geometry)
[docs]def explode(features: GeoJson) -> FeatureCollection:
"""
Takes a feature or set of features and returns all positions as {Point|points}.
:param features: any GeoJSON feature or feature collection
:return: {FeatureCollection} points representing the exploded input features
"""
points = []
try:
geojson_type = features.get("type")
except AttributeError:
raise InvalidInput(error_code_messages["InvalidGeometry"](all_geometry_types))
if geojson_type in ["FeatureCollection", "GeometryCollection"]:
key = "features" if geojson_type == "FeatureCollection" else "geometries"
for feature in features[key]:
properties = feature.get("properties", {})
coords = get_coords_from_features(feature)
points.extend(reduce_coordinates_to_points(coords, properties))
else:
properties = features.get("properties", {})
coords = get_coords_from_geometry(features)
points.extend(reduce_coordinates_to_points(coords, properties))
return feature_collection(points)
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