From b8f0625bd92af90afb825c76e03bded1b6285ada Mon Sep 17 00:00:00 2001 From: duxin Date: Wed, 8 Jul 2026 14:22:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8E=A9=E8=86=9C=E9=99=8D=E9=87=87?= =?UTF-8?q?=E6=A0=B7=E8=AE=A1=E7=AE=97=20=E2=80=94=20=E6=9D=9C=E7=BB=9D=20?= =?UTF-8?q?1m=20=E5=88=86=E8=BE=A8=E7=8E=87=E4=B8=8B=2010.5M=20Point=20?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=20OOM/=E5=81=87=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真凶定位: prepare_shared_context 第 2982-2988 行 grid_xx.ravel() → 10.5M 坐标点 [Point(x,y) for ...] → 创建 10.5M 个 shapely Point (~2 GB) within(boundary.unary_union) → 10.5M 次几何测试 O(N×M) → 此处假死/卡死/内存爆炸,Kriging 从未开始执行 修复: 掩膜降采样到 ~50K 点 (约 100m 等效分辨率) 计算, 结果通过 np.kron 升采样回原始分辨率。 掩膜是布尔值,精度损失可忽略; np.kron 的 C 向量化升采样 <1 秒。 --- src/postprocessing/map.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/postprocessing/map.py b/src/postprocessing/map.py index fe6ddc4..1970a4c 100644 --- a/src/postprocessing/map.py +++ b/src/postprocessing/map.py @@ -2978,14 +2978,31 @@ class ContentMapper: print(f"[共享上下文] 网格: {nx}×{ny} = {nx*ny} 点") - # ⑥ 水域掩膜布尔矩阵(只此一次) + # ⑥ 水域掩膜布尔矩阵(降采样到 ~100m 分辨率计算,避免 1m 下千万级 Point 对象 OOM) mask = None if boundary_gdf is not None: - mask_pts = np.column_stack((grid_xx.ravel(), grid_yy.ravel())) + _MASK_TARGET_POINTS = 50000 # 掩膜降采样目标点数 + _mask_step = max(1, int(np.sqrt(grid_xx.size / _MASK_TARGET_POINTS))) + if _mask_step > 1: + mask_xx = grid_xx[::_mask_step, ::_mask_step] + mask_yy = grid_yy[::_mask_step, ::_mask_step] + print(f"[共享上下文] 掩膜降采样 {_mask_step}× → " + f"{mask_xx.shape[1]}×{mask_xx.shape[0]} = {mask_xx.size:,} 点") + else: + mask_xx, mask_yy = grid_xx, grid_yy + + mask_pts = np.column_stack((mask_xx.ravel(), mask_yy.ravel())) mask_gdf = gpd.GeoDataFrame( geometry=[Point(x, y) for x, y in mask_pts], crs=self.output_crs ) - mask = mask_gdf.within(boundary_gdf.unary_union).values.reshape(grid_xx.shape) + mask_lowres = mask_gdf.within(boundary_gdf.unary_union).values.reshape(mask_xx.shape) + # 升采样回原始分辨率(最近邻,掩膜是布尔值) + if _mask_step > 1: + mask = np.kron(mask_lowres, np.ones((_mask_step, _mask_step), dtype=bool)) + # 裁剪到精确原始尺寸 + mask = mask[:grid_xx.shape[0], :grid_xx.shape[1]] + else: + mask = mask_lowres print(f"[共享上下文] 水域掩膜: {int(mask.sum())}/{mask.size} 点在水域内") return (grid_xx, grid_yy, mask, bounds, boundary_gdf)