我有带多边形的地址数据和形状文件,正在尝试确定每个地址与每个多边形的最近距离(以英里为单位),然后创建一个包含所有信息的嵌套dict,格式如下:
nested_dict = {poly_1: {address1: distance, address2 : distance},
poly2: {address1: distance, address2: distance}, etc}
我使用的完整、适用的代码是:
import pandas as pd
from shapely.geometry import mapping, Polygon, LinearRing, Point
import geopandas as gpd
from math import radians, cos, sin, asin, sqrt
address_dict = {k: [] for k in addresses_geo.input_string}
sludge_dtc = {k: [] for k in sf_geo.unique_name}
def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 3956 # Radius of earth in miles. Use 6371 for kilometers
return c * r
# Here's the key loop that isn't working correctly
for unique_name, i in zip(sf_geo.unique_name, sf_geo.index):
for address, pt in zip(addresses_geo.input_string, addresses_geo.index):
pol_ext = LinearRing(sf_geo.iloc[i].geometry.exterior.coords)
d = pol_ext.project(addresses_geo.iloc[pt].geometry)
p = pol_ext.interpolate(d)
closest_point_coords = list(p.coords)[0]
# print(closest_point_coords)
dist = haversine(addresses_geo.iloc[pt].geometry.x,
addresses_geo.iloc[pt].geometry.y,
closest_point_coords[0], closest_point_coords[1])
address_dict[address] = dist
sludge_dtc[unique_name] = address_dict
# Test results on a single address
addresses_with_sludge_distance = pd.DataFrame(sludge_dtc)
print(addresses_with_sludge_distance.iloc[[1]].T)
如果我把这段代码分解出来,并尝试计算单个多边形的距离,它似乎工作得很好。但是,当我创建DataFrame并检查地址时,它会为每个多边形列出相同的距离。你知道吗
因此,内部dict键“123 Main Street”对于外部dict中的每个多边形键将有5.25英里,而“456 South Street”对于外部dict中的每个多边形键将有6.13英里
我意识到我一定在用for循环设置的方式做一些愚蠢的事情,但我想不出来。我颠倒了for语句的顺序,弄乱了缩进——结果都一样。你知道吗
我想说清楚的是:
你知道我遗漏了什么吗?你知道吗
问题很简单,您总是使用相同的
address_dict
实例。 你只需要在每个键循环中重新创建它。你知道吗另一个考虑因素:
您正在创建以空列表作为值的空字典,但是在您直接设置值之后(将替换空列表)。如果需要收集值列表,则应将
append
值添加到现有列表中,例如:以及
相关问题 更多 >
编程相关推荐