python - 使用公共(public) GPS 数据计算速度

标签 python gps web-scraping

我正在抓取一个显示公交车纬度和经度的 Web API。

网络服务似乎没有固定的 GPS 位置更新时间,可能需要 1 秒到最多 30 秒。

当更新时间较长时,我会得到合理的速度(10km/h~80km/h),但当更新发生在不到 10 秒时,我会得到不真实的速度,最高可达 1000 km/h。

def haversine(lon1, lat1, lon2, lat2):
    """Calculate the distance between two points"""
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    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 = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

def get_speed(new_lat, new_lng, cur_time):
    old_lat, old_lng, old_time = buses[bus_prefix]
    if (new_lat, new_lng) != (old_lat, old_lng):
        distance = haversine(old_lng, old_lat, new_lng, new_lat)
        speed = distance / (cur_time - old_time) * 3600
        _speed = "%.1f km/h" % speed
        updated_time = "%02d:%02d"%(divmod(cur_time-old_time, 60))
        return _speed, updated_time

    return None, None

url = 'http://api.plataforma.cittati.com.br/m3p/js/vehicles/service/22233'

buses = {}

with requests.session() as s:
    while True:
        response = s.get(url)
        t = time.time()
        content = json.loads(response.content)
        for bus in content:
            bus_prefix = bus['prefix']
            latitude = bus['lat']
            longitude = bus['lng']
            if bus_prefix in buses:
                speed, update_time = get_speed(latitude, longitude, t)
                if speed and update_time:
                    print "Bus {bus_prefix} is traveling at {speed}\t" \
                    "Last update in: {update_time}".format(**locals())
            buses[bus_prefix] = latitude, longitude, t
        time.sleep(1)

也许我做错了一些数学,或者我所在城市的公交车正在赛车,但我仔细检查了所有内容,包括赛车!

这是我为了弄清楚发生了什么而进行的调试:

old_lat = -32.0916777778
new_lat = -32.0937277778

new_lng = -52.1608333333
old_lng = -52.1598611111

distance = 0.245660526035 in kms

old_time = 1436580324.66 in epoch seconds
cur_time =  1436580325.94 in epoch seconds

delta time = 1.28700017929 in seconds
speed = 687.162214861 in km/h

Bus 1145 is traveling at 687.2 km/h Last update in: 00:01

有人能发现任何错误吗?或者这是正确的方法吗? Haversine 是适合这项工作的工具吗?

最佳答案

从您发布的url,我得到了以下输出:

[{"plate":"IUZ4600","prefix":"1310","ts":1436583122000,"lat":-32.061505555555556,"lng":-52.147172222222224,"bearing":37} ,{"plate":"ISO8600","prefix":"1145","ts":1436583099000,"lat":-32.15838333333333,"lng":-52.19098888888889,"bearing":309}]

这是一个字典列表,我假设每个字典都引用一辆公共(public)汽车,

在每个字典中,都有一个名为tskey,它应该是每次更新的latlong的时间戳,应将其相应的用于计算速度,以便为您提供更准确的结果:

t = 总线["ts"]

关于python - 使用公共(public) GPS 数据计算速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31352752/

相关文章:

python - 在Python中,如何将列表中的第一个元素乘以一个数字(在列表的列表中)?

Python 在没有装饰器的情况下使用坚韧重试

php - 如何根据给定条件选择最短的GPS坐标?

android - 仅在位置更改时更新位置

ruby - 更改 HTTP header 、Ruby、Linux

python - Scrapy 抓取被 403/503 阻止

python - 如何使用语音识别和 Python 短语打开门

android - 不调用 GPS 更新

html - 使用 nokogiri 抓取后字符串的正则表达式是什么

Python itertools 排列如何包含重复字符