geopro/src/controller/DatasetRenderStrategy.hpp

101 lines
5.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <functional>
#include <map>
#include <memory>
#include <string>
#include "controller/PlaneZRegistry.hpp"
namespace geopro::controller {
class VtkSceneController; // 策略委托回控制器既有渲染路径add→addDatasetAsync/add2DDatasetAsyncremove→view.removeDataset
// 平面底图抽象:控制器层不依赖 VTK/appgeopro_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 暂转调 add2DDatasetAsyncPhase 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