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

球面非结构化经纬度网格Delaunay三角化绘图间隙问题求助

解决北极立体投影下Delaunay三角化的0°/360°间隙问题

你的问题核心是:在PlateCarree(经纬度)坐标系下做Delaunay三角化时,0°/360°经线在平面上是断开的(-180°和180°为平面两端),导致跨该经线的点无法被三角化连接,投影到北极立体投影后出现间隙。以下两种方法可以解决这个问题:

方法1:复制边界点扩展经度范围

通过复制0°经线附近的点,将其经度偏移±360°,让这些点在平面坐标系下相邻,从而让Delaunay生成跨边界的三角形。

修改后的代码:

import numpy as np
import pandas as pd
from scipy.spatial import Delaunay
import geoviews as gv
import holoviews as hv
import cartopy.crs as ccrs

def triangulate(vertices, x="Longitude", y="Latitude"):
    triang = Delaunay(vertices[[x, y]].values)
    return pd.DataFrame(triang.simplices, columns=['v0', 'v1', 'v2'])

# 原数据处理
x = ((np.rad2deg(data.clon) - 180) % 360) - 180
y = np.rad2deg(data.clat)
value = data[attr][t][i]

# 生成原始顶点
verts = pd.DataFrame({'Longitude': x, 'Latitude': y, 'value': value})

# 复制0°经线附近的点(可根据数据密度调整阈值,这里用±10°)
boundary_mask = verts['Longitude'].abs() < 10
boundary_verts = verts[boundary_mask].copy()

# 生成经度偏移±360°的副本
boundary_verts_plus = boundary_verts.assign(Longitude=lambda df: df['Longitude'] + 360)
boundary_verts_minus = boundary_verts.assign(Longitude=lambda df: df['Longitude'] - 360)

# 合并扩展顶点集
extended_verts = pd.concat([verts, boundary_verts_plus, boundary_verts_minus], ignore_index=True)

# 执行三角化
tris = triangulate(extended_verts)

# 绘图:投影时偏移后的点会与原边界点重合,自动填补间隙
trimesh = rasterize(gv.TriMesh((tris, hv.Points(extended_verts, vdims='value')), crs=ccrs.PlateCarree()))
trimesh.opts(
    cmap='Greys',
    fig_size=180,
    aspect=1,
    projection=ccrs.NorthPolarStereo()
)

方法2:在目标投影坐标系下做三角化(推荐)

直接将经纬度转换为北极立体投影的平面坐标,再执行Delaunay三角化,彻底避开经度周期性问题。

修改后的代码:

import numpy as np
import pandas as pd
from scipy.spatial import Delaunay
import geoviews as gv
import holoviews as hv
import cartopy.crs as ccrs

def triangulate_proj(vertices, x="proj_x", y="proj_y"):
    triang = Delaunay(vertices[[x, y]].values)
    return pd.DataFrame(triang.simplices, columns=['v0', 'v1', 'v2'])

# 原数据处理
x = ((np.rad2deg(data.clon) - 180) % 360) - 180
y = np.rad2deg(data.clat)
value = data[attr][t][i]

# 转换到北极立体投影坐标系
target_crs = ccrs.NorthPolarStereo()
proj_coords = target_crs.transform_points(ccrs.PlateCarree(), x.values, y.values)

# 提取投影后的平面坐标
verts_proj = pd.DataFrame({
    'proj_x': proj_coords[:, 0],
    'proj_y': proj_coords[:, 1],
    'value': value
})

# 在投影坐标下执行三角化
tris_proj = triangulate_proj(verts_proj)

# 绘图
trimesh_proj = rasterize(gv.TriMesh((tris_proj, hv.Points(verts_proj, vdims='value'))))
trimesh_proj.opts(
    cmap='Greys',
    fig_size=180,
    aspect=1,
    projection=target_crs
)

方法对比

  • 复制边界点:保留经纬度坐标系的三角化结果,适合后续需要基于经纬度的操作,但需手动调整边界阈值。
  • 投影后三角化:彻底规避经度周期性问题,三角化结果更贴合北极投影的空间关系,是更可靠的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:15:21