Find distance inside on a Geopandas geometry edge, based on points and bearing

1.2k views Asked by At

I'm trying to geo-process some data in a .shp, using Geopandas.

I would like to find a point in a geometry edge, given a bearing and an initial point inside of it.

How can I do this in an optimized way, since the algorithm will process a lot of iterations (approx.: ten per point)?

Image

1

There are 1 answers

1
Alz On BEST ANSWER

It depends on whether you want to stick to lon/lat or you can switch to projected coordinate system like UTM; and also what exactly you mean by bearing. One possible way assuming projected coordinates and compass bearing (clock-wise degree from north: 0-360) is to draw a line in the direction of your bearing which is long enough to intersect with the Polygon and compute the coordinate of the intersection.

let's say we have a GeoDataFrame containing a Polygon of a district in Berlin:

berlin
# 
#    bbox_east  bbox_north  bbox_south  bbox_west   geometry    place_name
# 0 13.429402   52.540407   52.504037   13.36586    POLYGON ((389163.2519209321 5821873.324153989,...   Mitte, Berlin, Deutschland

compute the x/y of the centroid of the geometry(can be any point, here I use centroid for representing the idea):

x = berlin.centroid.geometry.item().x
y = berlin.centroid.geometry.item().y

Following function can compute coordinates of the new point:

from shapely.geometry import LineString, LinearRing

def find_point(polygon, x, y , bearing):

    east, south, west, north = polygon.bounds
    line_length = max(abs(east-west), abs(north-south)) * 2

    new_x = x + (np.sin(np.deg2rad(bearing)) * line_length)
    new_y = y + (np.cos(np.deg2rad(bearing)) * line_length)

    l = LineString([[x,y], [new_x, new_y]])
    lr = LinearRing(polygon.exterior.coords)
    intersections = lr.intersection(l)

    return intersections.x, intersections.y

try it with our input data:

x_, y_ = find_point(berlin.geometry[0], x, y, 120)

fig, ax = plt.subplots()

berlin.plot(ax=ax)
plt.scatter(x_, y_)
plt.scatter(x,y)

enter image description here