2

I have the following code in Python:

import geopandas as gpd

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
us = world[world['name']=='United States of America'].dissolve(by='name')
coastline = gpd.clip(gpd.read_file('./data/ne_coastline/ne_10m_coastline.shp').to_crs('EPSG:4326'), us)
coastline.distance(Point(30.121735, -81.735374)).min()

# 153.78644123108657

But upon manually examination in Google Maps, this isn't correct. To simplify the problem, I found the coordinate approximating the closest coastline point (30.135054573782618, -81.34892671159952).

import geopandas as gpd
from shapely.geometry import Point

points_df = gpd.GeoDataFrame({'geometry': [Point(30.135054573782618, -81.34892671159952), Point(30.121735, -81.735374)]}, crs='EPSG:4326')
points_df = points_df.to_crs('EPSG:3087') # https://epsg.io/3087
points_df2 = points_df.shift() # shift the dataframe by 1 to align points
points_df.distance(points_df2)

# 0            NaN
# 1    4872.316273
# dtype: float64

But this is also far off from the correct answer in meters (which I double check manually in Google Maps):

from geopy.distance import distance
distance((30.135054573782618, -81.34892671159952), (30.121735, -81.735374)).m

# 37268.01227017112

I imagine my coordinate reference system is incorrect, but I'm unsure why given the reported accuracy of EPSG:3087. How can I correctly output the minimum distance to the coastline in meters given a coordinate?

0

1 Answer 1

4

You're measuring the distance from Antarctica to the US coastline (in decimal degrees in your first example)...

Unless you mean Point(-81.735374, 30.121735)? which is in Florida.

Point(coords) uses x, y ordering so you need Point(longitude, latitude)

import geopandas as gpd
from shapely.geometry import Point

points_df = gpd.GeoDataFrame({
    'geometry': [
        Point(-81.34892671159952, 30.135054573782618), 
        Point(-81.735374, 30.121735)]}, crs='EPSG:4326')

points_df = points_df.to_crs('EPSG:3087') # https://epsg.io/3087
points_df2 = points_df.shift() # shift the dataframe by 1 to align points

points_df.distance(points_df2)

Output:

0             NaN
1    37219.622729
dtype: float64

And based on this answer, you could do something like this:

import geopandas as gpd
from shapely.geometry import Point

def min_distance(point, lines):
    return lines.distance(point).min()

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
us = world[world['name']=='United States of America'].dissolve(by='name')
coastline = gpd.clip(gpd.read_file('ne_10m_coastline.shp'), us).to_crs('EPSG:3087')
points_df = gpd.GeoDataFrame({
    'geometry': [
        Point(-81.34892671159952, 30.135054573782618), 
        Point(-81.735374, 30.121735)]}, crs='EPSG:4326')
points_df = points_df.to_crs('EPSG:3087') # https://epsg.io/3087

points_df['min_dist_to_coast'] = points_df.geometry.apply(min_distance, args=(coastline,))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.