查看: 710|回复: 0

用 Overpy 快速操作 OpenStreetMap 数据,地图开发新体验!

[复制链接]
发表于 3 天前 | 显示全部楼层 |阅读模式
今天聊聊一个有趣又实用的 Python 库—— Overpy 。

它可以让你轻松操作 OpenStreetMap(简称 OSM)数据,适合那些对地图开发感兴趣的小伙伴。

如果你曾经想从 OSM 获取路网、建筑、甚至河流数据,却被复杂的 API 文档吓退,那 Overpy 就是你的好帮手!

下面咱们一步步来看看它怎么用。



1.

什么是 Overpy?

简单点说,Overpy 是一个 Python 库,专门用来通过 Overpass API 查询和操作 OpenStreetMap 数据。

Overpass API 是 OSM 的一个查询接口,允许我们用一种叫 Overpass QL 的语言快速获取地图上的各种数据,比如道路、建筑物、公园等等。

Overpy 把这种查询封装得简单易用,几行代码就能搞定。

再直白一点,Overpy 就是帮你从 OSM 这个“地图巨头”里挖东西的工具,挖到的数据可以直接用来做可视化、分析,甚至游戏地图!



2.

安装 Overpy

没有安装,别谈用。咱们先把 Overpy 装上:

pip install overpy

这一步没啥技术含量,没报错就算成功。

如果遇到网络问题,用国内源试试:

pip install overpy -i https://pypi.tuna.tsinghua.edu.cn/simple


用 Overpy 快速操作 OpenStreetMap 数据,地图开发新体验!-9744

3.

查询 OSM 数据

来点实际的。咱们用 Overpy 查询某个区域的道路数据。先写个简单的例子,看看怎么从 Overpy 获取数据。

代码示例:查询城市道路

import overpy

# 初始化 Overpass API
api = overpy.Overpass()

# 查询某个区域的道路数据
query = “”“
[out:json];
area[”name“=”Shanghai“]->.searchArea;
(
  way[”highway“](area.searchArea);
);
out body;
>;
out skel qt;
”“”

# 执行查询
result = api.query(query)

# 输出道路名称和 ID
for way in result.ways:
    print(f“道路名称:{way.tags.get('name', '无名路')} | ID:{way.id}”)
运行结果

运行上面的代码后,你会得到一堆道路信息,比如:

道路名称:延安东路 | ID:123456789
道路名称:无名路 | ID:987654321

解释一下代码:


    area[“name”=“Shanghai”]->.searchArea;:找到上海这个区域。

    way[“highway”](area.searchArea);:取出上海区域内的所有道路。

    out body;:输出查询结果。

    result.ways:查询结果中的所有道路。

温馨提示:
记得检查你的网络环境,有时 Overpass API 的响应速度可能会有点慢,耐心等一下。



用 Overpy 快速操作 OpenStreetMap 数据,地图开发新体验!-3846

4.

查询建筑数据

道路搞定了,咱们来试试查询建筑物。换个区域,看看北京的建筑数据咋样。

代码示例:查询建筑

query = “”“
[out:json];
area[”name“=”Beijing“]->.searchArea;
(
  way[”building“](area.searchArea);
);
out body;
>;
out skel qt;
”“”

result = api.query(query)

# 输出建筑名称和 ID
for way in result.ways:
    print(f“建筑名称:{way.tags.get('name', '无名建筑')} | ID:{way.id}”)

运行这段代码,你会发现一堆“无名建筑”。别惊讶,这很正常,OSM 数据不是所有建筑都有名字。这些数据仍然可以用来绘制城市轮廓,特别适合搞一些可视化项目。



5.

查询 POI 数据

POI(Point of Interest,兴趣点)是地图数据的灵魂,比如餐馆、学校、地铁站这些。如果你想根据 OSM 数据做个本地生活服务,这部分数据会非常重要。

代码示例:查询兴趣点

query = “”“
[out:json];
node[”amenity“=”restaurant“](around:1000,39.9042,116.4074);
out body;
”“”

result = api.query(query)

# 输出餐馆名称和坐标
for node in result.nodes:
    print(f“餐馆名称:{node.tags.get('name', '未知餐馆')} | 坐标:({node.lat}, {node.lon})”)

代码解读:

用 Overpy 快速操作 OpenStreetMap 数据,地图开发新体验!-4034


    node[“amenity”=“restaurant”]:查询类型为“餐馆”的节点。

    around:1000,39.9042,116.4074:查询范围是以 (39.9042, 116.4074) 为中心,半径 1000 米的区域。

运行后,你会得到类似的结果:

餐馆名称:海底捞 | 坐标:(39.905, 116.406)
餐馆名称:未知餐馆 | 坐标:(39.903, 116.408)

温馨提示:
注意 around 的范围单位是米,范围太大可能会导致查询超时。



6.

数据存储与处理

查询完数据后,你可能想保存到本地,方便后续分析。以下是保存为 JSON 文件的简单示例。

代码示例:保存数据为 JSON 文件

import json

# 把道路数据保存到 JSON 文件
output = []
for way in result.ways:
    output.append({
        “id”:way.id,
        “name”:way.tags.get(“name”, “无名路”),
        “nodes”:way.get_nodes(resolve_missing=True)
    })

with open(“roads.json”, “w”, encoding=“utf-8”) as f:
    json.dump(output, f, ensure_ascii=False, indent=4)

print(“数据已保存到 roads.json”)

运行完后,你会得到一个结构化的 JSON 文件,方便后续用其他工具处理。



用 Overpy 快速操作 OpenStreetMap 数据,地图开发新体验!-1941

7.

常见坑和解决方法


    查询超时 :
    如果查询范围太大,Overpass API 可能会返回超时错误。解决办法是缩小查询范围或者分块查询。

    数据字段不全 :
    OSM 数据是用户贡献的,某些字段可能缺失,比如道路名称。这种情况下可以用 tags.get(“字段名”, “默认值”) 设置默认值。

    网络问题 :
    如果查询速度慢,可以尝试用国内镜像,比如:

    api = overpy.Overpass(url=“https://overpass.kumi.systems/api/interpreter”)


8.

还能干点啥?

Overpy 的用法远不止这些。除了查询道路、建筑和 POI,你还可以:


    测量距离 :通过获取节点坐标计算两点之间的距离。

    地理分析 :结合其他库(如 shapely)做空间数据分析。

    地图可视化 :用 folium 或 leaflet 把查询结果渲染成交互式地图。

这些都可以为你的地图项目增色不少。



9.

嗯,就这样

Overpy 是个轻量又强大的工具,让你可以高效操作 OpenStreetMap 数据。

不管是开发地图应用,还是做数据分析,它都能派上大用场。

趁热打铁,试着用它挖掘自己城市的数据,或许会有意想不到的发现!

您需要登录后才可以回帖 登录 | 加入联盟

本版积分规则

快速回复 返回顶部 返回列表