Reputation: 73
I am trying to calculate shortest distance from any ship position to coastline in nautical miles using this zip file.
I have tried using GeoPandas
, shapely
, geopy
but I have not found a way that properly works. I tried using below code to spot the nearest point and then calculate the distance, but it's always reading the wrong linestring
. I appreciate any help.
import pandas as pd
import geopandas as gpd
from geopandas import GeoSeries
from shapely.geometry import Point
p1=GeoSeries(Point(8.41655010639208, -83.11475151369626))
coastline=gpd.read_file('/Users/Danilo/Documents/Python/panama_coastline/panama_coastline.shp')
coastline=coastline[coastline['NATURAL']=='shoreline']
coastline=coastline['geometry']
coastline.reset_index(drop=True,inplace=True)
#coastline.geom_type
#coastline
#p1=Point(8.41655010639208, -83.11475151369626)
#coastline.to_crs(epsg=5368,inplace=True)
#coastline.crs
#coastline.geometry.distance(p1).min()
line=coastline[p1.distance(coastline)==p1.distance(coastline).min()]
line.reset_index
#type(ls1)
#line.geom_type
from shapely.ops import nearest_points
p=nearest_points(p1,line[0])
from geopy.distance import geodesic, Point
p0=Point(p[0].y,p[0].x)
p1=Point(p1.y,p1.x)
geodesic(p0,p1).nautical
coastline.plot()
p0
#geodesic(Point(8.41655010639208, -83.11475151369626),Point(8.41388, -83.11114)).nautical
coastline[0].distance(p1)
Upvotes: 2
Views: 888
Reputation: 1497
I am not sure what exactly the problem is, but here is a basic example that calculates the distance, and plots the points on the map.
import geopandas as gpd
import numpy as np
from shapely.geometry import Point, LineString
from shapely.ops import nearest_points
Data import
panama = gpd.read_file("panama_coastline/panama_coastline.shp")
I define function to get the closest line point. This is not optimal, and if you calculate +1M points you want to optimize this.
def closest_line(point, linestrings):
return np.argmin( [p.distance(linestring) for linestring in panama.geometry] )
With this we can define a point and test
p = Point(-80,9)
closest_linestring = panama.geometry[ closest_line(p, panama.geometry) ]
closest_point = nearest_points(p, closest_linestring)
And plot them both on a map
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1, figsize=(10, 20))
_ = panama.plot(ax=ax)
_ = gpd.GeoDataFrame(closest_point, columns=['geometry']).plot(ax=ax,c='red')
Edit: Added example to calcuatel distance in Miles
from sklearn.neighbors import DistanceMetric
dist = DistanceMetric.get_metric('haversine')
points_as_floats = [ np.array([p.y, p.x]) for p in closest_point ]
EARTH_RADIUS_IN_MILES = 3960
haversine_distances = dist.pairwise(np.radians(points_as_floats), np.radians(points_as_floats) )
haversine_distances *= EARTH_RADIUS_IN_MILES
print( haversine_distances[0][1] )
Upvotes: 2