You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用OSMnx绘制各类OSM水体(适配全球任意区域)

解决OSMnx获取全球海岸/岛屿水体数据的问题

问题背景

我正在用Python脚本绘制地图的不同图层(水体、草地、岩石等),通过OSMnx调用OpenStreetMap数据,获取岩石图层的代码如下:

nature['rock'] = ox.features_from_point((latitude, longitude), dist=dist, tags={'natural': ['bare_rock', 'rock', 'scree']})

但目前无法获取全球任意区域(包括岛屿、海岸)的所有水体数据并统一绘制:

  • 尝试过tags={'natural': ['water', 'bay']}、tags={'natural': 'coastline'}标签,单独或组合调用后合并均无效
  • prettymaps包在海岸、岛屿场景下表现不佳

预期效果:
圣多明各预期水体效果

实际效果:
圣多明各OSM返回水体效果

解决方案

1. 用更全面的标签覆盖所有水体类型

OSM中海岸和岛屿区域的水体涉及多种标签组合,仅用natural=water或natural=coastline会遗漏部分数据。建议使用以下标签集合来覆盖内陆水、海域、海湾等:

# 覆盖各类水体类型的标签
water_tags = {
    'natural': ['water', 'bay'],
    'water': ['sea', 'ocean', 'lake', 'bay', 'lagoon'],
    'waterway': ['river', 'stream', 'canal']  # 可选,若需要包含河流等线性水体
}

# 获取水体数据
nature['water'] = ox.features_from_point((latitude, longitude), dist=dist, tags=water_tags)

2. 处理海岸线与水体多边形的合并

natural=coastline是线性边界,无法直接填充颜色。需要单独获取海域多边形并与其他水体数据合并:

import pandas as pd
import geopandas as gpd

# 获取海域多边形
sea_polygons = ox.features_from_point(
    (latitude, longitude), 
    dist=dist, 
    tags={'natural': 'water', 'water': ['sea', 'ocean']}
)

# 合并所有水体数据
all_water = pd.concat([nature['water'], sea_polygons], ignore_index=True)
# 修复几何错误并合并重叠多边形
all_water['geometry'] = all_water.geometry.make_valid()
all_water = all_water.dissolve()  # 合并为单一多边形,方便绘制

3. 改用边界框扩大查询范围

如果目标区域是岛屿或沿海地带,features_from_point的固定距离可能无法覆盖完整海域。建议先获取区域边界,再用边界框查询:

# 获取目标区域的地理边界(以圣多明各为例)
gdf = ox.geocode_to_gdf("Santo Domingo, Dominican Republic")
bbox = gdf.total_bounds  # 格式:(minx, miny, maxx, maxy)

# 通过边界框查询水体数据
water_gdf = ox.features_from_bbox(
    bbox[1], bbox[0], bbox[3], bbox[2], 
    tags=water_tags
)

4. 补充外部数据源(可选)

如果OSM数据在部分区域缺失,可结合Natural Earth的公开海域数据补充:

# 加载Natural Earth的低分辨率海域数据
ne_seas = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
ne_seas = ne_seas[ne_seas['featurecla'] == 'Ocean']

# 裁剪到目标区域
target_area = gdf.geometry.iloc[0]
ne_seas_cropped = ne_seas.clip(target_area)

# 合并OSM与Natural Earth数据
final_water = pd.concat([water_gdf, ne_seas_cropped], ignore_index=True).dissolve()

内容的提问来源于stack exchange,提问作者Jon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:25:14