101 lines
5.5 KiB
C++
101 lines
5.5 KiB
C++
#pragma once
|
||
|
||
#include <QImage>
|
||
#include <QNetworkAccessManager>
|
||
#include <QObject>
|
||
|
||
#include <deque>
|
||
#include <functional>
|
||
#include <map>
|
||
#include <memory>
|
||
#include <set>
|
||
#include <utility>
|
||
#include <vector>
|
||
|
||
#include <vtkSmartPointer.h>
|
||
|
||
class vtkActor;
|
||
class vtkObject;
|
||
class vtkTexture;
|
||
class vtkRenderWindow;
|
||
class vtkInteractorObserver;
|
||
class vtkCallbackCommand;
|
||
class QNetworkReply;
|
||
namespace geopro::render { class Scene; }
|
||
namespace geopro::core { class GeoLocalFrame; }
|
||
|
||
namespace geopro::app {
|
||
|
||
// 天地图 WMTS 底图层(局部平面,B 方案)+ LOD:按相机视距自动选瓦片层级、覆盖可视范围,
|
||
// 缩放/平移结束后增量增删瓦片。复用轨迹图同款 token;瓦片经同一 GeoLocalFrame 配准。
|
||
class TileBasemap : public QObject {
|
||
Q_OBJECT
|
||
public:
|
||
enum Kind { Street = 0, Satellite = 1, Hidden = 2 };
|
||
TileBasemap(geopro::render::Scene& scene, vtkRenderWindow* rw,
|
||
std::shared_ptr<geopro::core::GeoLocalFrame> frame, QObject* parent = nullptr);
|
||
~TileBasemap() override;
|
||
|
||
void show(Kind kind); // 显示某底图(Hidden 等同 hide);记住类型供 LOD 刷新复用
|
||
void hide(); // 移除全部瓦片
|
||
void refresh(); // 按当前相机重算层级+覆盖,增量更新瓦片(交互结束回调)
|
||
void setVerticalExaggeration(double ve); // 地形垂向夸张(须与剖面 VE 一致才对齐)
|
||
// 数据半径提供者:刷新时查询当前所有勾选剖面的合并范围(半径,米),据此动态定底图最大范围。
|
||
void setDataRadiusProvider(std::function<double()> fn) { dataRadiusProvider_ = std::move(fn); }
|
||
|
||
private:
|
||
static long long tileKey(int z, int x, int y);
|
||
void ensureObserver(); // 首次显示时挂到交互样式的 EndInteractionEvent
|
||
void requestRender(); // 合并渲染:同一事件循环轮次多次请求只渲染一帧
|
||
void purgeStale(); // 本轮请求全部落地后再删旧层瓦片,避免缩放空白闪烁
|
||
// 四叉树细分:按瓦片投影屏幕尺寸递归(近细远粗),收集叶瓦片到 out。
|
||
void refineTile(int z, int x, int y, std::set<long long>& out, int& count);
|
||
void fetchTile(int z, int x, int y, long long key);
|
||
void fetchTerrain(int z, int x, int y, long long key,
|
||
vtkSmartPointer<vtkTexture> tex); // 拉覆盖该瓦片的 DEM(z>15 取祖先块)后落地
|
||
void placeActor(long long key, vtkSmartPointer<vtkActor> actor);
|
||
vtkSmartPointer<vtkActor> buildFlat(int z, int x, int y,
|
||
vtkSmartPointer<vtkTexture> tex); // 平面瓦片(DEM 兜底)
|
||
vtkSmartPointer<vtkActor> buildWarped(int sz, int sx, int sy, int dz, int dx, int dy,
|
||
vtkSmartPointer<vtkTexture> tex,
|
||
const QImage& dem); // DEM 位移网格 + 卫星贴图
|
||
void enqueueGet(const QString& url,
|
||
std::function<void(QNetworkReply*)> onDone); // 限并发取瓦片(回调内负责 deleteLater)
|
||
void pumpNetQueue();
|
||
static void onInteractionEnd(vtkObject*, unsigned long, void* clientData, void*);
|
||
|
||
geopro::render::Scene& scene_;
|
||
vtkRenderWindow* rw_;
|
||
std::shared_ptr<geopro::core::GeoLocalFrame> frame_;
|
||
QNetworkAccessManager nam_;
|
||
Kind kind_ = Hidden;
|
||
int generation_ = 0; // show/hide/换源 自增,丢弃过期回包
|
||
std::map<long long, vtkSmartPointer<vtkActor>> placed_; // 已贴瓦片:key→actor
|
||
std::set<long long> desired_; // 当前视野应显示的瓦片 key
|
||
std::set<long long> inFlight_; // 在途瓦片(续到起伏/平面最终落地)
|
||
std::map<long long, QImage> demCache_; // DEM 块缓存(key=DEMz/x/y),跨隐藏/重选复用
|
||
std::map<long long, vtkSmartPointer<vtkTexture>> texCache_; // 影像纹理缓存,重选/缩放回看免重拉
|
||
double ve_ = 1.0; // 地形垂向夸张(与剖面 verticalExaggeration 一致才对齐)
|
||
double maxTileDist_ = 2000.0; // 底图最大距离(米),每次刷新按剖面范围动态算
|
||
std::function<double()> dataRadiusProvider_; // 返回当前勾选剖面合并范围的半径
|
||
// 卫星层「学习到的」最大可用层级:天地图卫星影像各区域覆盖深度不同(内地到z18, 台湾等仅到z16),
|
||
// 超出则回固定「此级别下无影像」占位图。检测到占位即把上限降到 z-1 并重铺(改用父层真实影像放大),
|
||
// 使该区域不再请求无影像层。show()/换源时复位为 kMaxZoom 以便新区域重新探测。
|
||
int satMaxZoom_ = 18;
|
||
// 四叉树当前帧相机参数(refresh 写, refineTile 读):相机位置 + 投影系数 + 视锥 6 面。
|
||
double camX_ = 0, camY_ = 0, camZ_ = 0;
|
||
double projK_ = 1.0;
|
||
bool projParallel_ = false;
|
||
double frustum_[24] = {0}; // 6 个视锥平面(内法向),AABB 全在某面外则剔除
|
||
struct PendingGet { QString url; std::function<void(QNetworkReply*)> cb; };
|
||
std::deque<PendingGet> netQueue_; // 限并发请求队列(防瓦片暴发饱和卡死)
|
||
int netInFlight_ = 0;
|
||
bool terrainProbed_ = false; // 首次 fetchTerrain 打一行诊断日志
|
||
vtkSmartPointer<vtkInteractorObserver> styleObs_; // 持引用保证回调期有效
|
||
vtkSmartPointer<vtkCallbackCommand> observer_;
|
||
bool renderPending_ = false; // 合并渲染:同轮多次请求只渲染一帧
|
||
bool refreshing_ = false;
|
||
};
|
||
|
||
} // namespace geopro::app
|