You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从GMT格式文本文件读取经纬度坐标并转换为Numpy数组用于Basemap绘图

解决GMT线段文本转Basemap兼容的NumPy数组问题

问题概述

你有GMT格式的线段数据,格式示例如下:

122 55 122 56 122.5 57 > 123 25.25 123 25.27

其中>是不同线段的分隔符,需要将这些坐标转换成二维NumPy数组,以便用Basemap结合plt.plotplt.scatter进行绘图。

完整实现方案

1. 解析GMT文本并转换为NumPy数组

核心思路是先按分隔符拆分线段,再将每个线段的坐标对整理成二维数组。下面是可直接复用的代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

# 替换成你的GMT文本内容,也可以从文件读取(比如用open().read())
gmt_data = "122 55 122 56 122.5 57 > 123 25.25 123 25.27"

# 1. 分割不同线段,清理空白内容
segments = [seg.strip() for seg in gmt_data.split(">") if seg.strip()]

# 2. 将每个线段转换为(n, 2)形状的NumPy数组
line_coords = []
for seg in segments:
    # 拆分坐标字符串为数值,再重塑为二维数组(每行对应一个经纬度点)
    coords = np.array(list(map(float, seg.split()))).reshape(-1, 2)
    line_coords.append(coords)

# 打印验证结果
for idx, arr in enumerate(line_coords):
    print(f"第{idx+1}条线段的坐标数组:")
    print(arr)

2. 结合Basemap绘制线段

拿到转换后的数组后,就可以直接对接Basemap的绘图函数了:

# 初始化Basemap实例(这里以东亚区域为例,可根据需求调整投影和范围)
m = Basemap(llcrnrlon=70, llcrnrlat=15, urcrnrlon=140, urcrnrlat=55,
            projection='lcc', lat_1=30, lat_2=60, lon_0=105)

# 绘制基础地图元素
m.drawcoastlines(linewidth=0.8)
m.drawcountries(linewidth=0.5)
m.drawparallels(np.arange(15, 56, 10), labels=[1,0,0,0])
m.drawmeridians(np.arange(70, 141, 10), labels=[0,0,0,1])

# 遍历每个线段数组,转换投影并绘图
for coords in line_coords:
    # 将原始经纬度转换为Basemap的投影坐标
    x, y = m(coords[:, 0], coords[:, 1])
    # 绘制线段,可自定义样式
    plt.plot(x, y, marker='^', linestyle='-', color='#ff4444', linewidth=2)

plt.title("GMT线段转换后Basemap绘图示例")
plt.show()

关键细节说明

  • 清理空白:分割后用strip()和空字符串过滤,避免因文本首尾或连续分隔符产生无效数据
  • 自动重塑reshape(-1, 2)会自动根据坐标数量调整行数,无需手动计算点数,适配任意长度的线段
  • 投影转换:Basemap要求先将经纬度转成它的投影坐标,再传入plt.plot,否则会出现坐标偏移

内容的提问来源于stack exchange,提问作者Pakox.Wang

火山引擎 最新活动