def line_offset(geojson: Feature, distance: float, unit: str = "km") -> Feature: """ Takes a linestring or multilinestring and returns a line at offset by the specified distance. :param geojson: input GeoJSON :param distance: distance to offset the line (can be of negative value) :param unit: Units in which distance to be calculated, values can be 'deg', 'rad', 'mi', 'km', default is 'km' :return: Line feature offset from the input line Example: >>> from geojson import MultiLineString, Feature >>> from turfpy.transformation import line_offset >>> ls = Feature(geometry=MultiLineString([ ... [(3.75, 9.25), (-130.95, 1.52)], ... [(23.15, -34.25), (-1.35, -4.65), (3.45, 77.95)] ... ])) >>> line_offset(ls, 2, unit='mi') """ if not geojson: raise Exception("geojson is required") if not distance: raise Exception("distance is required") type = get_type(geojson) properties = geojson.get("properties", {}) if type == "LineString": return line_offset_feature(geojson, distance, unit) elif type == "MultiLineString": coords = [] def callback_flatten_each(feature, feature_index, multi_feature_index): nonlocal coords coords.append( line_offset_feature(feature, distance, unit).geometry.coordinates) return True flatten_each(geojson, callback_flatten_each) return Feature(geometry=MultiLineString(coords), properties=properties)
def sector(center: Feature, radius: int, bearing1: int, bearing2: int, options: dict = {}) -> Feature: """ Creates a circular sector of a circle of given radius and center Point , between (clockwise) bearing1 and bearing2; 0 bearing is North of center point, positive clockwise. :param center: A `Point` object representing center point of circle. :param radius: An int representing radius of the circle. :param bearing1: Angle, in decimal degrees, of the first radius of the arc. :param bearing2: Angle, in decimal degrees, of the second radius of the arc. :param options: A dict representing additional properties, which can be `steps` which has default values as 64, `units` which has default values of `km`, and `properties` which will be added to resulting Feature as properties. :return: A polygon feature object. Example: >>> from turfpy.misc import sector >>> from geojson import Feature, Point >>> center = Feature(geometry=Point((-75, 40))) >>> radius = 5 >>> bearing1 = 25 >>> bearing2 = 45 >>> sector(center, radius, bearing1, bearing2) """ if not options: options = {} steps = int(options["steps"]) if options.get("steps") else 64 units = str(options.get("units")) if options.get("units") else "km" properties = options.get("properties") if options.get("properties") else {} if not center: raise Exception("center if required") if center.get("type") != "Feature": raise Exception("Invalid Feature value for center parameter") if not radius: raise Exception("Radius is required") if not bearing1: raise Exception("bearing1 is required") if not bearing2: raise Exception("bearing2 is required") if convert_angle_to_360(bearing1) == convert_angle_to_360(bearing2): return circle(center, radius, steps, units) coords = get_coords(center) arc = line_arc(center, radius, bearing1, bearing2, options) sliceCoords = [[coords]] def _callback_coord_each( coord, coord_index, feature_index, multi_feature_index, geometry_index, ): nonlocal sliceCoords sliceCoords[0].append(coord) coord_each(arc, _callback_coord_each) sliceCoords[0].append(coords) return Feature(geometry=Polygon(sliceCoords), properties=properties)
def line_arc(center: Feature, radius: int, bearing1: int, bearing2: int, options: dict = {}) -> Feature: """ Creates a circular arc, of a circle of the given radius and center point, between bearing1 and bearing2; 0 bearing is North of center point, positive clockwise. :param center: A `Point` object representing center point of circle. :param radius: An int representing radius of the circle. :param bearing1: Angle, in decimal degrees, of the first radius of the arc. :param bearing2: Angle, in decimal degrees, of the second radius of the arc. :param options: A dict representing additional properties,which can be `steps` which has default values as 64 and `units` which has default values of `km` :return: A Line String feature object. Example: >>> from turfpy.misc import line_arc >>> from geojson import Feature, Point >>> center = Feature(geometry=Point((-75, 40))) >>> radius = 5 >>> bearing1 = 25 >>> bearing2 = 47 >>> feature = line_arc(center=center, radius=radius, >>> bearing1=bearing1, bearing2=bearing2) """ if not options: options = {} steps = int(options["steps"]) if options.get("steps") else 64 units = str(options.get("units")) if options.get("units") else "km" angle1 = convert_angle_to_360(bearing1) angle2 = convert_angle_to_360(bearing2) properties = {} if center.get("type"): if center.get("type") == "Feature": properties = center.get("properties") else: raise Exception("Invalid Feature value for center parameter") if angle1 == angle2: return Feature( geometry=LineString( circle(center, radius, steps, units)["geometry"]["coordinates"][0]), properties=properties, ) arc_start_degree = angle1 arc_end_degree = angle2 if angle1 < angle2 else angle2 + 360 alfa = arc_start_degree coordinates = [] i = 0 while alfa < arc_end_degree: coordinates.append( destination(center, radius, alfa, { "steps": steps, "units": units })["geometry"]["coordinates"]) i += 1 alfa = arc_start_degree + i * 360 / steps if alfa > arc_end_degree: coordinates.append( destination(center, radius, arc_end_degree, { "steps": steps, "units": units })["geometry"]["coordinates"]) return Feature(geometry=LineString(coordinates, properties=properties))