Having the following information:
from shapely.geometry import Point
origin_point = Point(...,...)
end_point = Point(...,...)
center_point = Point(...,...)
distance = 100
bearing = 90
I would like to be able to generate an arc as close as possible with as few points as possible, obtaining the coordinates of this approximation.
A good functionality would be to be able to control the error tolerance and to be able to dynamically graduate the number of points to approximate the arc.
We must have in mind that we are working with coordinates and we cannot ignore surface curvature.
The expected output would be a function that obtains as inputs, the origin point, the end point, center point, distance, bearing and optionally the error tolerance and returns as output a series of point coordinates from the original point to the end point that approximately form the required arc.
Related links:
https://gis.stackexchange.com/questions/326871/generate-arc-from-projection-coordinates
Any help would be greatly appreciated.
import math
import numpy as np
from shapely.geometry import Point, LineString
def get_bearing(center_point, end_point):
lat3 = math.radians(end_point[0])
long3 = math.radians(end_point[1])
lat1 = math.radians(center_point[0])
long1 = math.radians(center_point[1])
dLon = long3 - long1
X = math.cos(lat3) * math.sin(dLon)
Y = math.cos(lat1) * math.sin(lat3) - math.sin(lat1) * math.cos(lat3) * math.cos(dLon)
end_brng = math.atan2(X, Y)
return end_brng
def get_arc_coordinates(center_point, origin_point, end_point, brng_init, distance):
'''
center_point: (center_latitude, center_long)
origin_point: (origin_latitude, origin_long)
end_point: (end_latitude, end_long)
brng_init: degrees
distance: aeronautical miles
'''
brng_init = math.radians(brng_init) #Bearing in degrees converted to radians.
d = distance * 1.852 #Distance in km
R = 6378.1 #Radius of the Earth
brng = get_bearing(center_point,end_point) #1.57 #Bearing is 90 degrees converted to radians.
list_bearings = np.arange(brng, brng_init, 0.1) # 0.1 value to be modify with tolerance
coordinates = []
for i in list_bearings:
lat1 = math.radians(center_point[0]) #Center lat point converted to radians
lon1 = math.radians(center_point[1]) #Center long point converted to radians
brng = i
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)
coordinates.append(Point(lat2, lon2))
return LineString(coordinates)