fix(vtk): 剖面被切根因=远处底图把近裁剪面顶出去切掉近处剖面;调小近裁剪容差(1e-5)+底图限数据周围10km(远裁剪面有界)

This commit is contained in:
gaozheng 2026-06-17 17:25:40 +08:00
parent 052fdc1168
commit c5577ce071
2 changed files with 11 additions and 8 deletions

View File

@ -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<long long>& 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_) {

View File

@ -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<vtkSmartPointer<vtkProp>>& 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();