惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
T
Troy Hunt's Blog
L
Lohrmann on Cybersecurity
S
Schneier on Security
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
G
GRAHAM CLULEY
博客园 - 【当耐特】
有赞技术团队
有赞技术团队
SecWiki News
SecWiki News
博客园 - 叶小钗
博客园 - Franky
V
Vulnerabilities – Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
O
OpenAI News
小众软件
小众软件
V
V2EX
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
博客园 - 三生石上(FineUI控件)
The Hacker News
The Hacker News
Project Zero
Project Zero
The Last Watchdog
The Last Watchdog
雷峰网
雷峰网
Google Online Security Blog
Google Online Security Blog
T
Tailwind CSS Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
量子位
D
Docker
Recent Announcements
Recent Announcements
T
Threat Research - Cisco Blogs
P
Privacy International News Feed
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Jina AI
Jina AI
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
V2EX - 技术
V2EX - 技术
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
博客园 - 聂微东
Cloudbric
Cloudbric
S
Security Affairs
F
Fortinet All Blogs

俟河清

【牛GN】白色相簿 2 动画版 / IC 浅谈 【牛GN】最终幻想 16 【牛体力学】流体力学的基本概念 1 【牛体力学】 前置:场论及张量 【牛GN】iPhone 80 Ultra & Apple Watch 6 Pro 2025 年总结:变了很多,但也没变。 【牛GN】最终幻想 7:重生 【牛 GN】女神异闻录 3 重制版 【牛GN】那些年用过的外围设备 MODIS 遥感产品数据处理及转换 【牛GN】那些年用过的电脑们 【牛GN】那些年用过的爪机们 【牛GN】葬送的芙莉莲 降水序列重建思路 【All in Boom】第 2 期:服务部署 【牛GN】Darling in the Franxx 动漫随笔:败犬女主实在是太多了 【All in Boom】第 1.5 期:反向代理及内网 HTTPS 构建 动漫随笔:Mygo、Ave Mujica和孤独摇滚
经纬度转换的那些麻烦事
SatyrLee · 2025-08-15 · via 俟河清

但是处理太平洋地区的时候就会出现问题:由于跨过了国际日期变更线,导致太平洋数据会分为 100 ~ 180,-180 ~-50 两片区域。这就会对 EOF 操作出现问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import xarray as xr
import numpy as np

def wrap_longitude(
ds: xr.Dataset,
*,
to: Literal["-180_180", "0_360"] = "-180_180",
coord_priority: Optional[Tuple[str, ...]] = ("lon","longitude","x"),
sort: bool = True,
drop_edge_duplicate: bool = True
) -> xr.Dataset:
"""
Wrap the longitude coordinate without copying data by default:
- to="-180_180": new_lon = ((lon + 180) % 360) - 180
- to="0_360": new_lon = lon % 360
Then (optionally) sort by longitude and drop edge duplicates (0/360 or -180/180).
Works for any lon coordinate name among ('lon','longitude','x').
"""
# find lon coordinate name
lon_name = None
for cand in (coord_priority or ()):
if cand in ds.coords:
lon_name = cand; break
if lon_name is None:
# fall back to detection
_, lon_name = _detect_lat_lon(ds)
if lon_name is None:
raise ValueError("Longitude coordinate not found.")

# Handle wrapping
if to == "-180_180":
# Full reprojection: build new lon grid from -180 to 180 and remap data
# detect lat coordinate
lat_name, _ = _detect_lat_lon(ds)
if lat_name is None:
raise ValueError("Latitude coordinate not found for reprojection.")
lons = ds[lon_name].values
lats = ds[lat_name].values
lon_res = np.abs(lons[1] - lons[0])
target_lons = np.arange(-180, 180 + lon_res/2, lon_res)
# prepare new dataset with coords
new_coords = {lat_name: lats, lon_name: target_lons}
ds2 = xr.Dataset(coords=new_coords)
# remap each data variable
for var in ds.data_vars:
arr = ds[var].values
new_shape = (len(lats), len(target_lons))
new_data = np.full(new_shape, np.nan, dtype=arr.dtype)
mask1 = lons <= 180
if np.any(mask1):
idxs = np.searchsorted(target_lons, lons[mask1])
new_data[:, idxs] = arr[:, mask1]
mask2 = lons > 180
if np.any(mask2):
lons2 = lons[mask2] - 360
idxs2 = np.searchsorted(target_lons, lons2)
new_data[:, idxs2] = arr[:, mask2]
ds2[var] = xr.DataArray(new_data, coords=new_coords, dims=(lat_name, lon_name))
elif to == "0_360":
# Simple modulo wrap
new_lon = (ds[lon_name] % 360)
ds2 = ds.assign_coords({lon_name: new_lon})
else:
raise ValueError(f"Unsupported target: {to}")

if sort:
ds2 = ds2.sortby(lon_name)

if drop_edge_duplicate:
# Remove duplicates introduced by wrap, e.g., both 0 and 360
vals = ds2[lon_name].values
unique_vals = _drop_duplicate_coords(vals)
if unique_vals.size < vals.size:
ds2 = ds2.sel({lon_name: unique_vals})

return ds2