计算邮政编码/邮政编码之间的(公路旅行)距离python

2024-04-29 11:12:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有开始和结束邮政编码的csv文件(英国相当于美国邮政编码),我想计算这两者之间的简单距离、公路旅行距离和旅行时间。我想现在的方法应该是以某种方式使用谷歌地图。我第一次尝试使用一些电子表格和以下url http://maps.google.com/maps?saddr=“&B2&;”&daddr=“&A2&;”但是

  1. 我不知道如何从google地图中检索结果距离
  2. 我想知道一些更像Python的方法来解决这个问题

Tags: 文件csv方法httpurl距离google方式
3条回答

这看起来是您的理想资源(它们以各种格式为英国的每个邮政编码提供lat和long值):https://www.freemaptools.com/download-uk-postcode-lat-lng.htm 尤其是这个CSV文件(链接在同一页中): https://www.freemaptools.com/download/full-postcodes/ukpostcodes.zip

一旦你将地理坐标与你拥有的每个邮政编码相匹配(超出了这个问题的范围),假设你有一个表,其中有4列(即每个邮政编码有2个(lat,long)值)。 你可以用numpy计算距离。下面是一个例子:

import numpy as np
latlong = np.random.random((3,4))
# Dummy table containing 3 records, will look like this:
# array([[ 0.258906  ,  0.66073909,  0.25845113,  0.87433443],
#        [ 0.7657047 ,  0.48898144,  0.39812762,  0.66054291],
#        [ 0.2839561 ,  0.04679014,  0.40685189,  0.09550362]])
# The following will produce a numpy array with as many elements as your records
# (It's the Euclidean distance between the points)
distances = np.sqrt((latlong[:, 3] - latlong[:, 1])**2 + (latlong[:, 2] - latlong[:, 0])**2)
# and it look like this:
# array([ 0.21359582,  0.405643  ,  0.13219825])

寻找两个邮政编码之间的距离的主要问题是它们不是为它设计的。

For the purposes of directing mail, the United Kingdom is divided by Royal Mail into postcode areas. -Wikipedia

邮政编码本身不提供有用的信息,因此您需要外部来源的帮助。位于http://maps.google.com的Google地图服务没有任何用处,因为它不是为您检索这样的信息而设计的。


选项1-Google Maps API

Google Maps API是功能打包的,将为您提供很多选择。上面的链接指向距离矩阵API,它将帮助计算两点之间的距离。由此产生的结果将基于旅行(因此行驶距离),这可能是您想要的,也可能不是您想要的。

示例

Python3

import urllib.request
import json

res = urllib.request.urlopen("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=SE1%208XX&destinations=B2%205NY").read()
data = json.loads(res.decode())
print(data["rows"][0]["elements"][0]["distance"])
# {'text': '127 mi', 'value': 204914}

Note: Google Maps API is subject to usage limits.

选项2-用postcodes.io自己动手

postcodes.io有一个很好的API,由一个公共数据集支持。Example lookup。结果是JSON格式的,可以使用json模块将其映射到Python字典。这里的缺点是它不提供检查距离的方法,因此您必须使用返回的经度和纬度自己进行检查。

示例

Python3

import urllib.request
import json

res = urllib.request.urlopen("http://api.postcodes.io/postcodes/SE18XX").read()
data = json.loads(res)
print(data["result"]["longitude"], data["result"]["latitude"])
# -0.116825494204512 51.5057668390097

计算距离

我不想过多地讨论这个问题,因为这是一个大的话题,而且根据你所要达到的目标有很大的不同,但是一个好的起点是Haversine Formula,它考虑到了地球的曲率。然而,它假设地球是一个完美的球体(事实并非如此)。

The haversine formula determines the great-circle distance between two points on a sphere given their longitudes and latitudes. Important in navigation, it is a special case of a more general formula in spherical trigonometry, the law of haversines, that relates the sides and angles of spherical triangles.

下面是一个用Python实现的示例:https://stackoverflow.com/a/4913653/7220776

邮政编码之间的距离可以通过pgeocode库获得。与上述响应不同,它不查询web API,因此更适合处理大量数据

 >>> import pgeocode

 >>> dist = pgeocode.GeoDistance('GB')
 >>> dist.query_postal_code('WC2N', 'EH53')
 536.5  # retured distance in km

有关这些邮政编码的更多信息,包括纬度和经度,可以使用

 >>> nomi = pgeocode.Nominatim('GB')
 >>> nomi.query_postal_code(['WC2N', 'EH53'])
   postal_code country code                                     place_name  \
 0        WC2N           GB                                         London   
 1        EH53           GB  Pumpherston, Mid Calder, East Calder, Oakbank   

   state_name state_code     county_name county_code community_name  \
 0    England        ENG  Greater London    11609024            NaN   
 1   Scotland        SCT    West Lothian         WLN            NaN   

   community_code  latitude  longitude  accuracy  
 0            NaN   51.5085  -0.125700       4.0  
 1            NaN   55.9082  -3.479025       4.0

这使用GeoNames postal code dataset获得GPS坐标,然后计算这些坐标上的Haversine(大圆)距离。大多数国家都得到支持。

在英国的特定情况下,只有向外的代码包含在GB数据集中,完整的数据集也可以作为GB_full使用,但它目前是not supported在pgeocode中。

相关问题 更多 >