简体   繁体   中英

Trying to find the point closest to a user inputted point in a geopandas dataframe

import datetime as dt
import pandas as pd
import pandas_datareader as pdr
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as dates
import numpy as np
#import natlparks as pnp
import geopandas as gpd
import geopy as gp
import googlemaps as gm
import shapely
import scipy
from geopy.geocoders import Nominatim
from shapely.geometry import Point
from shapely.ops import nearest_points
#import streamlit as st
#st.title("Finding NY National Parks Near You")
def close_by(pt, location):
    data = pd.read_csv('National_Register_of_Historic_Places (3).csv')
    close_locations = []
    location_latitude = float(location.latitude)
    location_longitude = float(location.longitude)
    #for index, row in data.itterrows():
    close_locations = [shapely.geometry.Point(lon, lat) for lon,lat in zip(data['Longitude'], data['Latitude'])]
    gdf = gpd.GeoDataFrame(data, geometry=close_locations, crs={"init":"EPSG:4326"})
    pts = gdf.geometry.unary_union
    for i, row in gdf:
        print(nearest_points(pt, pts)[0])
    print(gpd[nearest].get_values()[0])
    print(pts)
    print(gdf)




def main():
    data = pd.read_csv('National_Register_of_Historic_Places (3).csv')
    streetNum = input("Enter your number")
    streetName = input("Enter Your Street Name")
    city = input("Enter your city")
    geolocator = Nominatim(user_agent="Final_Project_Python")
    location = geolocator.geocode(f"{streetNum} {streetName} {city} ")
    print(location.address)
    print(location.latitude, location.longitude)
    pt = Point(location.longitude, location.latitude)
    print(float(location.latitude))
    print(float(location.longitude))
    close_by(pt, location)
main()

Currently, the program is meant to try and find the closest national park from the csv data by finding the nearest point after the user enters their address. What do I do to run through the dataset and find the closest point? CSV has columns 'Resource Name', 'County', 'National Register Date', 'National Register Number', 'Longitude', 'Latitude', and 'Georeference'

  • use public sources of geojson for national parks
  • use public source of addresses - picked hospitals
  • these addresses do include longitude / latitude. This can be looked up with APIs if you have a post code
  • real approach
    1. generate combinations of NPs and addresses
    2. calculate distances using geopy
    3. filter down to nearest NP to address
  • provide sample output - from my knowledge of England looks correct
import geopandas as gpd
import pandas as pd
import requests, io, json
import geopy.distance

# get national parks in England
np = gpd.read_file(io.StringIO(json.dumps(requests.get("https://opendata.arcgis.com/datasets/d333c7529754444894e2d7f5044d1bbf_0.geojson").json())))
# get some public addressess - hospitals
dfhos = pd.read_csv(io.StringIO(requests.get("http://media.nhschoices.nhs.uk/data/foi/Hospital.csv").text), sep="¬", engine="python")

# use centre of NP as geo co-ords.  Ignore warning of CRS system!
np["centre"] = np.centroid.apply(lambda x: (x.y,x.x))

# pick an address in each county...
dfhos = dfhos.dropna(subset=["County"]).loc[dfhos.groupby("County", as_index=False).cumcount().lt(1)]

# cartesian product of addresses to NPs - all combinations
dfm = pd.merge(
    np.loc[:,["NAME","centre"]].reset_index().rename(columns={"index":"np_index"}).assign(foo=1)
    ,dfhos.loc[:,["OrganisationName","County","Postcode","Longitude","Latitude"]].reset_index().rename(columns={"index":"addr_index"}).assign(foo=1)
    ,on="foo"
).drop(columns="foo")

# calc distance between centre of NP and addresses, then filter down to nearest NP
dfnearest = (dfm.assign(distance=dfm.apply(lambda r: geopy.distance.geodesic(r["centre"], 
                                                                             (r["Latitude"], r["Longitude"])).km, axis=1))
 .sort_values(["addr_index","distance"], ascending=[1,1])
 .groupby(["addr_index"], as_index=False).first()
)

dfnearest.sort_values("distance").loc[:,["np_index","NAME","OrganisationName","County","Postcode","distance"]].head(10)

np_index NAME OrganisationName County Postcode distance
26 6 NEW FOREST Southampton General Hospital Hampshire SO16 6YD 14.0999
42 5 NORTH YORK MOORS Guisborough General Hospital Cleveland TS14 6HZ 21.3057
27 3 PEAK DISTRICT Charles Clifford Dental Hospital South Yorkshire S10 2SZ 22.4807
51 6 NEW FOREST St Mary's Isle of Wight PO30 5TG 26.3622
5 4 DARTMOOR Torbay Hospital Devon TQ2 7AA 27.3006
21 3 PEAK DISTRICT Chesterfield Royal Hospital Derbyshire S44 5BL 27.7963
36 8 LAKE DISTRICT Cockermouth Community Hospital Cumbria CA13 9HT 28.9103
13 3 PEAK DISTRICT The Christie main site Greater Manchester M20 4BX 31.9218
2 0 SOUTH DOWNS Royal Surrey County Hospital Surrey GU2 7XX 32.5091
15 5 NORTH YORK MOORS St Monicas Hospital North Yorkshire YO61 3JD 34.7372

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM