#pragma once #include #include #include #include #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(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 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> 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 dsToType_; // dsId→typeId(remove 只得 dsId,需自存反查) // 每 2D 类型一份平面矢量底图(贴该类型平面 z);随平面建/销/升降。键=typeId。 std::map> bms_; std::map bmKind_; // 该类型底图选择(0=矢量平面/1=无),重建时复用 std::map bmOpacity_; // 该类型底图透明度,重建时复用 PlaneBasemapFactory basemapFactory_; // app 注入的底图工厂(空=不建底图) }; } // namespace geopro::controller