From aea5b6b8cb7e912fb212220308620d74f12c40f9 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Tue, 30 Jun 2026 22:46:00 +0800 Subject: [PATCH] =?UTF-8?q?refactor(vtk):=20TileBasemap=20=E9=80=8F?= =?UTF-8?q?=E6=98=8E=E5=BA=A6=E5=8F=82=E6=95=B0=E5=8C=96(=E9=BB=98?= =?UTF-8?q?=E8=AE=A40.5)=E5=A4=87=E5=A4=9A=E5=AE=9E=E4=BE=8B=E4=B8=8E?= =?UTF-8?q?=E5=8F=AF=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/TileBasemap.cpp | 12 +++++++++--- src/app/TileBasemap.hpp | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app/TileBasemap.cpp b/src/app/TileBasemap.cpp index 943b83d..dabef54 100644 --- a/src/app/TileBasemap.cpp +++ b/src/app/TileBasemap.cpp @@ -56,7 +56,6 @@ constexpr double kGroundZ = 0.0; // 底图置于 z=0 地面参考(剖面 constexpr double kZEps = 0.02; // 每层级 Z 微偏移:高层级压上面,避免共面瓦片 z-fighting constexpr int kHardCap = 400; // 瓦片硬上限:超过则即便未落地也强制清理,兜底内存 constexpr double kPi = 3.14159265358979323846; -constexpr double kTerrainOpacity = 0.55; // 地形半透明:地下剖面可从任意角度透过地面看到(不再被遮挡) // 地面起伏:Mapbox terrain-RGB DEM 瓦片(原版 web 同款源,全球 CDN,比 AWS Terrarium 快)。 // 公式 elev(米) = -10000 + (R*65536 + G*256 + B)*0.1。数据到 z15,更高层级取祖先块。 @@ -208,6 +207,13 @@ void TileBasemap::setVerticalExaggeration(double ve) { if (kind_ != Hidden) show(kind_); // 重建地形(高程×新VE),与剖面 VE 保持一致 } +void TileBasemap::setOpacity(double o) { + o = std::clamp(o, 0.0, 1.0); + if (o == opacity_) return; + opacity_ = o; + if (kind_ != Hidden) show(kind_); // 重建套用新透明度 +} + void TileBasemap::refineTile(int z, int x, int y, std::set& out, int& count) { if (count >= kMaxLeaves) { out.insert(tileKey(z, x, y)); return; } // 安全上限:停止细分 const int n = 1 << z; @@ -452,7 +458,7 @@ vtkSmartPointer TileBasemap::buildFlat(int z, int x, int y, actor->SetMapper(mapper); actor->SetTexture(tex); actor->GetProperty()->LightingOff(); // 底图不受场景光照 - actor->GetProperty()->SetOpacity(kTerrainOpacity); // 半透明:不遮挡地下剖面 + actor->GetProperty()->SetOpacity(opacity_); // 半透明:不遮挡地下剖面 // 注意:UseBounds 保持默认 true → 参与相机裁剪面计算,否则底图会被裁剪面"蒙版"切掉。 // 坐标轴/取景不被底图撑大,由 VtkSceneView 改用"数据自身包围盒"解决(非靠 UseBounds=false)。 return actor; @@ -566,7 +572,7 @@ vtkSmartPointer TileBasemap::buildWarped(int sz, int sx, int sy, int d actor->SetMapper(mapper); actor->SetTexture(tex); actor->GetProperty()->LightingOff(); - actor->GetProperty()->SetOpacity(kTerrainOpacity); // 半透明:不遮挡地下剖面 + actor->GetProperty()->SetOpacity(opacity_); // 半透明:不遮挡地下剖面 return actor; // UseBounds 默认 true:参与裁剪面,避免被"蒙版"切掉 } diff --git a/src/app/TileBasemap.hpp b/src/app/TileBasemap.hpp index da6e7af..3119d3e 100644 --- a/src/app/TileBasemap.hpp +++ b/src/app/TileBasemap.hpp @@ -40,6 +40,7 @@ public: void hide(); // 移除全部瓦片 void refresh(); // 按当前相机重算层级+覆盖,增量更新瓦片(交互结束回调) void setVerticalExaggeration(double ve); // 地形垂向夸张(须与剖面 VE 一致才对齐) + void setOpacity(double o); // 底图半透明度[0,1],供渲染工具栏底图弹窗调节 // 数据半径提供者:刷新时查询当前所有勾选剖面的合并范围(半径,米),据此动态定底图最大范围。 void setDataRadiusProvider(std::function fn) { dataRadiusProvider_ = std::move(fn); } @@ -76,6 +77,7 @@ private: std::map demCache_; // DEM 块缓存(key=DEMz/x/y),跨隐藏/重选复用 std::map> texCache_; // 影像纹理缓存,重选/缩放回看免重拉 double ve_ = 1.0; // 地形垂向夸张(与剖面 verticalExaggeration 一致才对齐) + double opacity_ = 0.5; // 底图半透明:地下剖面可从任意角度透过地面看到(不再被遮挡) double maxTileDist_ = 2000.0; // 底图最大距离(米),每次刷新按剖面范围动态算 std::function dataRadiusProvider_; // 返回当前勾选剖面合并范围的半径 // 卫星层「学习到的」最大可用层级:天地图卫星影像各区域覆盖深度不同(内地到z18, 台湾等仅到z16),