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

技术问询:地理坐标按国家分类存CSV及无GIS库添加绘图山脉

一、地理坐标按国家分类并保存为单独CSV

步骤说明

  1. 坐标格式转换:将N/S/E/W格式的坐标转为十进制经纬度数值(北纬、东经为正,南纬、西经为负)。
  2. 离线国家匹配:使用免费公开的国家边界数据集(如自然地球1:110m分辨率国家边界),通过射线法判断坐标所属国家。
  3. 分组与保存:按国家分组后,将每组数据写入单独的CSV文件。

代码实现

import csv
import json

# 坐标转换函数
def convert_coordinate(lat_str, lon_str):
    lat = float(lat_str[:-1])
    if lat_str.endswith('S'):
        lat = -lat
    lon = float(lon_str[:-1])
    if lon_str.endswith('W'):
        lon = -lon
    return lat, lon

# 射线法判断点是否在多边形内
def point_in_polygon(point, polygon):
    x, y = point
    inside = False
    n = len(polygon)
    for i in range(n):
        j = (i + 1) % n
        xi, yi = polygon[i]
        xj, yj = polygon[j]
        if ((yi > y) != (yj > y)):
            x_intersect = (y - yi) * (xj - xi) / (yj - yi) + xi
            if x <= x_intersect:
                inside = not inside
    return inside

# 加载本地国家边界GeoJSON数据(自然地球1:110m国家数据集)
with open('countries.geojson', 'r', encoding='utf-8') as f:
    countries_data = json.load(f)

# 待处理的坐标数据
input_data = [
    "Koforidua_ANUC,6.109N,0.302W",
    "Kuching,1.491N,110.349E",
    "Kuopio,62.892N,27.634E",
    "Kuwait_University,29.325N,47.971E"
]

# 按国家分组存储数据
country_groups = {}

for line in input_data:
    name, lat_str, lon_str = line.split(',')
    lat, lon = convert_coordinate(lat_str, lon_str)
    # 遍历国家边界匹配所属国家
    for feature in countries_data['features']:
        country_name = feature['properties']['NAME']
        geometry = feature['geometry']
        # 处理多边形和多多边形类型
        if geometry['type'] == 'Polygon':
            polygons = [geometry['coordinates'][0]]
        elif geometry['type'] == 'MultiPolygon':
            polygons = [poly[0] for poly in geometry['coordinates']]
        else:
            continue
        # 检查点是否在当前国家的任意多边形内
        for poly in polygons:
            if point_in_polygon((lon, lat), poly):
                country_groups.setdefault(country_name, []).append([name, lat, lon])
                break
        else:
            continue
        break

# 保存每个国家的CSV文件
for country, points in country_groups.items():
    safe_filename = country.replace(' ', '_').replace('/', '_')
    with open(f'{safe_filename}_coordinates.csv', 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['Name', 'Latitude', 'Longitude'])
        writer.writerows(points)

补充说明

  • 自然地球1:110m国家边界数据可免费下载后保存为本地countries.geojson文件使用。
  • 若坐标数据量极小,也可手动匹配国家后直接分组,跳过点在多边形判断步骤。

二、不使用GeoPandas添加区域山脉至绘图

步骤说明

  1. 获取离线山脉数据:使用自然地球免费公开的山脉矢量数据(如1:110m分辨率山脊线)。
  2. 读取解析数据:用纯Python读取GeoJSON格式的山脉数据,提取坐标信息。
  3. 叠加山脉绘图:在matplotlib中绘制山脉线条,再叠加自定义坐标点。

代码实现(以matplotlib为例)

import json
import matplotlib.pyplot as plt

# 加载本地山脊线GeoJSON数据(自然地球1:110m山脊线数据集)
with open('ridges.geojson', 'r', encoding='utf-8') as f:
    ridges_data = json.load(f)

# 初始化绘图
fig, ax = plt.subplots(figsize=(10, 8))

# 绘制山脉山脊线
for feature in ridges_data['features']:
    geometry = feature['geometry']
    if geometry['type'] == 'LineString':
        lons, lats = zip(*geometry['coordinates'])
        ax.plot(lons, lats, color='#888888', linewidth=0.8)
    elif geometry['type'] == 'MultiLineString':
        for line in geometry['coordinates']:
            lons, lats = zip(*line)
            ax.plot(lons, lats, color='#888888', linewidth=0.8)

# 叠加自定义坐标点
input_points = [
    (6.109, -0.302),  # Koforidua_ANUC
    (1.491, 110.349), # Kuching
    (62.892, 27.634), # Kuopio
    (29.325, 47.971)  # Kuwait_University
]
lats, lons = zip(*input_points)
ax.scatter(lons, lats, color='red', marker='o', label='Your Points')

# 绘图配置
ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
ax.set_title('Map with Mountains')
ax.legend()
plt.show()

补充说明

  • 自然地球还提供山脉多边形等数据,可根据需求选择下载。
  • 若使用Shapefile格式数据,可使用纯Python库pyshp读取,无需依赖GeoPandas。

内容的提问来源于stack exchange,提问作者S.Kociok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 09:05:38