From c5577ce071b0dee7b5ed6f9e1c3f0c1ad116ac82 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Wed, 17 Jun 2026 17:25:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(vtk):=20=E5=89=96=E9=9D=A2=E8=A2=AB?= =?UTF-8?q?=E5=88=87=E6=A0=B9=E5=9B=A0=3D=E8=BF=9C=E5=A4=84=E5=BA=95?= =?UTF-8?q?=E5=9B=BE=E6=8A=8A=E8=BF=91=E8=A3=81=E5=89=AA=E9=9D=A2=E9=A1=B6?= =?UTF-8?q?=E5=87=BA=E5=8E=BB=E5=88=87=E6=8E=89=E8=BF=91=E5=A4=84=E5=89=96?= =?UTF-8?q?=E9=9D=A2;=E8=B0=83=E5=B0=8F=E8=BF=91=E8=A3=81=E5=89=AA?= =?UTF-8?q?=E5=AE=B9=E5=B7=AE(1e-5)+=E5=BA=95=E5=9B=BE=E9=99=90=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=91=A8=E5=9B=B410km(=E8=BF=9C=E8=A3=81=E5=89=AA?= =?UTF-8?q?=E9=9D=A2=E6=9C=89=E7=95=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/TileBasemap.cpp | 5 +++++ src/app/VtkSceneView.cpp | 14 ++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/app/TileBasemap.cpp b/src/app/TileBasemap.cpp index d4788f7..2bbf928 100644 --- a/src/app/TileBasemap.cpp +++ b/src/app/TileBasemap.cpp @@ -43,6 +43,7 @@ const char* kTk = "aca91d8c9f59a4f779f39061b8a07737"; constexpr int kRootZoom = 9; // 四叉树根层级(单块~78km,±1 覆盖~234km 到天边) constexpr double kTargetPx = 384.0; // 瓦片屏幕像素阈值:超过则细分(越小越清晰但块更多) constexpr int kMaxLeaves = 200; // 一次覆盖的叶瓦片上限(安全兜底,防细分爆炸) +constexpr double kMaxTileDist = 10000.0; // 底图离数据中心最大距离(米):远裁剪面有界,且免无限拉远 constexpr int kMaxConcurrent = 8; // 瓦片请求最大并发(防暴发饱和单域名连接) constexpr int kMinZoom = 3; constexpr int kMaxZoom = 18; @@ -216,6 +217,10 @@ void TileBasemap::refineTile(int z, int x, int y, std::set& out, int& const double cx = (sw.x + ne.x) * 0.5, cy = (sw.y + ne.y) * 0.5; // 瓦片中心(局部米) const double g = std::max(std::abs(ne.x - sw.x), std::abs(ne.y - sw.y)); // 瓦片地面尺寸(米) + // 距离上限:数据中心在局部原点(0,0);瓦片离它太远则不加载——远裁剪面有界(剖面不被近裁剪面切), + // 也避免拉远时无限铺。叶块本身可大于此距离(其近端仍在范围内即保留)。 + if (std::sqrt(cx * cx + cy * cy) - g * 0.5 > kMaxTileDist) return; + // 该瓦片投影到屏幕的近似像素尺寸 > 阈值且未到最大层级 → 细分为 4 子块(近处更细)。 double screenPx; if (projParallel_) { diff --git a/src/app/VtkSceneView.cpp b/src/app/VtkSceneView.cpp index f5b9334..f14bbeb 100644 --- a/src/app/VtkSceneView.cpp +++ b/src/app/VtkSceneView.cpp @@ -64,7 +64,11 @@ VtkSceneView::VtkSceneView(geopro::render::Scene& scene, vtkRenderWindow* render : scene_(scene), renderWindow_(renderWindow), frame_(std::move(frame)), - zRefElev_(zRefElev) {} + zRefElev_(zRefElev) { + // 近裁剪容差调小:场景含近处剖面 + 远处底图(几十km),默认容差会把近裁剪面随远面推出去、 + // 切掉离相机近的剖面。调小后近面可贴近,剖面不被切(代价:远处深度精度略降,不可见层无所谓)。 + scene_.renderer()->SetNearClippingPlaneTolerance(1e-5); +} void VtkSceneView::removeProps(std::vector>& props) { for (auto& p : props) @@ -187,13 +191,7 @@ void VtkSceneView::setAxes(geopro::controller::AxesMode mode, geopro::controller void VtkSceneView::applyCameraView(geopro::controller::ViewDir dir) { geopro::render::applyView(scene_.renderer(), toRenderViewDir(dir)); // 设朝向(内部 ResetCamera 含底图) double bounds[6]; - const bool ok = computeDataBounds(bounds); - qInfo() << "[view] 预设取景 computeDataBounds=" << ok << " ds数=" << int(dsProps_.size()) - << (ok ? QString(" bounds[%1,%2 %3,%4 %5,%6]") - .arg(bounds[0]).arg(bounds[1]).arg(bounds[2]) - .arg(bounds[3]).arg(bounds[4]).arg(bounds[5]) - : QString()); - if (ok) + if (computeDataBounds(bounds)) scene_.renderer()->ResetCamera(bounds); // 重新取景到数据(否则被~公里级底图推到超远) scene_.renderer()->ResetCameraClippingRange(); // 裁剪面含底图 if (renderWindow_) renderWindow_->Render();