101 lines
5.2 KiB
C++
101 lines
5.2 KiB
C++
#pragma once
|
||
#include <functional>
|
||
#include <map>
|
||
#include <memory>
|
||
#include <string>
|
||
|
||
#include "controller/PlaneZRegistry.hpp"
|
||
|
||
namespace geopro::controller {
|
||
|
||
class VtkSceneController; // 策略委托回控制器既有渲染路径(add→addDatasetAsync/add2DDatasetAsync;remove→view.removeDataset)
|
||
|
||
// 平面底图抽象:控制器层不依赖 VTK/app(geopro_controller 仅链 geopro_data+Qt::Core)。
|
||
// app 层(main.cpp)经工厂注入具体 TileBasemap 适配器,仿既有 I3dSceneView/VtkSceneView 边界,
|
||
// 避免 geopro_controller 反向依赖 app 层与 VTK。
|
||
class IPlaneBasemap {
|
||
public:
|
||
virtual ~IPlaneBasemap() = default;
|
||
virtual void show(int kind) = 0; // 0=矢量平面(Street)/其它=无(hide)
|
||
virtual void hide() = 0;
|
||
virtual void setOpacity(double o) = 0; // 半透明度[0,1]
|
||
virtual void setGroundZ(double z) = 0; // 直接平移平面高程 z(拖 z 值滑块):改瓦片 position,无重铺
|
||
};
|
||
// 工厂:按平面 z 造一份平面底图(底图所需 scene/渲染窗/frame/数据半径规则由 app 闭包捕获)。
|
||
// 未注入(空)则不建底图——便于无 VTK 的纯逻辑单测。
|
||
using PlaneBasemapFactory = std::function<std::unique_ptr<IPlaneBasemap>(double groundZ)>;
|
||
|
||
class IDatasetRenderStrategy {
|
||
public:
|
||
virtual ~IDatasetRenderStrategy() = default;
|
||
virtual void add(const std::string& typeId, const std::string& dsId) = 0;
|
||
virtual void remove(const std::string& dsId) = 0;
|
||
virtual void onTypeActivated(const std::string& /*typeId*/) {}
|
||
virtual void onTypeDeactivated(const std::string& /*typeId*/) {}
|
||
};
|
||
|
||
class RenderStrategyRegistry {
|
||
public:
|
||
void registerStrategy(std::string id, std::unique_ptr<IDatasetRenderStrategy> s) {
|
||
strategies_[std::move(id)] = std::move(s);
|
||
}
|
||
IDatasetRenderStrategy* get(const std::string& id) const {
|
||
auto it = strategies_.find(id);
|
||
return it == strategies_.end() ? nullptr : it->second.get();
|
||
}
|
||
private:
|
||
std::map<std::string, std::unique_ptr<IDatasetRenderStrategy>> strategies_;
|
||
};
|
||
|
||
// 3 策略:各持 VtkSceneController& 引用,把 add/remove 委托回控制器既有渲染路径。
|
||
// Volume/Curtain::add 均转调 addDatasetAsync(其内部按 isVolumeDataset 自分体/帘面分支);
|
||
// Plane2D::add 暂转调 add2DDatasetAsync(Phase E/F 改平面 z + 底图)。remove 统一 view.removeDataset。
|
||
class VolumeRenderStrategy : public IDatasetRenderStrategy {
|
||
public:
|
||
explicit VolumeRenderStrategy(VtkSceneController& ctrl) : ctrl_(ctrl) {}
|
||
void add(const std::string& typeId, const std::string& dsId) override;
|
||
void remove(const std::string& dsId) override;
|
||
private:
|
||
VtkSceneController& ctrl_;
|
||
};
|
||
|
||
class CurtainRenderStrategy : public IDatasetRenderStrategy {
|
||
public:
|
||
explicit CurtainRenderStrategy(VtkSceneController& ctrl) : ctrl_(ctrl) {}
|
||
void add(const std::string& typeId, const std::string& dsId) override;
|
||
void remove(const std::string& dsId) override;
|
||
private:
|
||
VtkSceneController& ctrl_;
|
||
};
|
||
|
||
// 每个 2D 类型(段)的勾选足迹落到该类型「同一平面」上:首勾的 ds 定平面 z,后续投影到该 z;
|
||
// 全消则平面消失(z 遗忘)。平面 z 生命周期由 PlaneZRegistry 维护;足迹摆放经 add2DDatasetAsync(z)。
|
||
class Plane2DRenderStrategy : public IDatasetRenderStrategy {
|
||
public:
|
||
explicit Plane2DRenderStrategy(VtkSceneController& ctrl) : ctrl_(ctrl) {}
|
||
void add(const std::string& typeId, const std::string& dsId) override;
|
||
void remove(const std::string& dsId) override;
|
||
void onTypeActivated(const std::string& typeId) override; // 首勾:建该类型平面矢量底图
|
||
void onTypeDeactivated(const std::string& typeId) override; // 全消:销毁该类型底图(瓦片随之消失)
|
||
// 滑块整体升降该类型平面 z:更新 planeReg_ 后,对该类型已勾选足迹移除并按新 z 重摆 + 底图重建于新 z。
|
||
void setPlaneZ(const std::string& typeId, double z);
|
||
// 底图工厂注入(main.cpp 构造后一次性下发;未注入则底图建造静默跳过,便于纯逻辑单测)。
|
||
void setBasemapFactory(PlaneBasemapFactory f) { basemapFactory_ = std::move(f); }
|
||
void setBasemapKind(const std::string& typeId, int kind); // 0=矢量平面(show)/1=无(hide)
|
||
void setBasemapOpacity(const std::string& typeId, double o); // 该类型底图半透明度[0,1]
|
||
private:
|
||
void createBasemap(const std::string& typeId); // 按当前 z/kind/opacity 建(或重建)该类型底图
|
||
|
||
VtkSceneController& ctrl_;
|
||
PlaneZRegistry planeReg_; // 按类型的平面 z 生命周期
|
||
std::map<std::string, std::string> dsToType_; // dsId→typeId(remove 只得 dsId,需自存反查)
|
||
|
||
// 每 2D 类型一份平面矢量底图(贴该类型平面 z);随平面建/销/升降。键=typeId。
|
||
std::map<std::string, std::unique_ptr<IPlaneBasemap>> bms_;
|
||
std::map<std::string, int> bmKind_; // 该类型底图选择(0=矢量平面/1=无),重建时复用
|
||
std::map<std::string, double> bmOpacity_; // 该类型底图透明度,重建时复用
|
||
PlaneBasemapFactory basemapFactory_; // app 注入的底图工厂(空=不建底图)
|
||
};
|
||
|
||
} // namespace geopro::controller
|