From 83c64104669016723d72b70630e818dccecab0e7 Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Sun, 9 Aug 2026 17:07:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/Local_Server/Data_Source/Data_Source.h | 16 ++-- .../Local_Server/server/Adminive_Config.cpp | 75 ++++++++++++++++++- module/Local_Server/server/Config.cpp | 9 ++- module/Local_Server/server/Config.h | 14 ++++ module/Local_Server/server/tiles.cpp | 19 ++++- 5 files changed, 116 insertions(+), 17 deletions(-) diff --git a/module/Local_Server/Data_Source/Data_Source.h b/module/Local_Server/Data_Source/Data_Source.h index f0768e2..f6643d8 100644 --- a/module/Local_Server/Data_Source/Data_Source.h +++ b/module/Local_Server/Data_Source/Data_Source.h @@ -119,14 +119,14 @@ struct Type_Descriptor { ADMINIVE_FIELD_LABEL(T, base_station_show, "显示基站").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, aircraft_show, "显示飞机").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, constant_screen_size, "固定屏幕尺寸").creatable().editable().boolean_input(), - ADMINIVE_FIELD_LABEL(T, color, "颜色").creatable().editable().color_input(), + ADMINIVE_FIELD_LABEL(T, color, "飞机标注颜色").creatable().editable().color_input(), ADMINIVE_FIELD_LABEL(T, track_point_color, "航迹点颜色").creatable().editable().color_input(), ADMINIVE_FIELD_LABEL(T, base_station_color, "基站颜色").creatable().editable().color_input(), - ADMINIVE_FIELD_LABEL(T, aircraft_pixel_size, "飞机像素尺寸").creatable().editable().number_input(), - ADMINIVE_FIELD_LABEL(T, base_station_pixel_size, "基站像素尺寸").creatable().editable().number_input(), - ADMINIVE_FIELD_LABEL(T, track_point_pixel_size, "航迹点像素尺寸").creatable().editable().number_input(), - ADMINIVE_FIELD_LABEL(T, aircraft_scale, "飞机缩放").creatable().editable().number_input(), - ADMINIVE_FIELD_LABEL(T, base_station_scale, "基站缩放").creatable().editable().number_input(), + ADMINIVE_FIELD_LABEL(T, aircraft_pixel_size, "飞机显示大小").creatable().editable().number_input(), + ADMINIVE_FIELD_LABEL(T, base_station_pixel_size, "基站显示大小").creatable().editable().number_input(), + ADMINIVE_FIELD_LABEL(T, track_point_pixel_size, "轨迹点大小").creatable().editable().number_input(), + ADMINIVE_FIELD_LABEL(T, aircraft_scale, "飞机缩放比例").creatable().editable().number_input(), + ADMINIVE_FIELD_LABEL(T, base_station_scale, "基站显示大小").creatable().editable().number_input(), ADMINIVE_FIELD_LABEL(T, show_icao, "显示 ICAO").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, show_call_sign, "显示呼号").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, show_fly_status, "显示飞行状态").creatable().editable().boolean_input()); @@ -146,14 +146,14 @@ struct Type_Descriptor { static auto get() { using T = Data_Source_Data; return object("data_source_config", "数据源公共配置", - ADMINIVE_FIELD_LABEL(T, base_station_has_valid_position, "基站位置有效").creatable().editable().boolean_input(), + ADMINIVE_FIELD_LABEL(T, base_station_has_valid_position, "基站有效定位").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, map_display, "地图显示").creatable().editable(), ADMINIVE_FIELD_LABEL(T, lat, "纬度").creatable().editable().number_input(), ADMINIVE_FIELD_LABEL(T, lon, "经度").creatable().editable().number_input(), ADMINIVE_FIELD_LABEL(T, alt, "高度").creatable().editable().number_input(), ADMINIVE_FIELD_LABEL(T, ignore_msg_time, "忽略消息时间戳").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, update_form_gps, "从 GPS 更新位置").creatable().editable().boolean_input(), - ADMINIVE_FIELD_LABEL(T, keep_mode, "保留模式").creatable().editable().boolean_input()); + ADMINIVE_FIELD_LABEL(T, keep_mode, "基站最大范围保持模式").creatable().editable().boolean_input()); } }; } diff --git a/module/Local_Server/server/Adminive_Config.cpp b/module/Local_Server/server/Adminive_Config.cpp index 769ce6f..d397dcd 100644 --- a/module/Local_Server/server/Adminive_Config.cpp +++ b/module/Local_Server/server/Adminive_Config.cpp @@ -754,15 +754,84 @@ Json archive_operations_schema() { const auto formats = Json::array({Json{{"label", "ZIP (.zip)"}, {"value", "zip"}, {"format", "zip"}, {"filter", ""}, {"extension", "zip"}}, Json{{"label", "TAR (.tar)"}, {"value", "tar"}, {"format", "pax"}, {"filter", ""}, {"extension", "tar"}}, Json{{"label", "TAR.GZ (.tar.gz)"}, {"value", "tar.gz"}, {"format", "pax"}, {"filter", "gzip"}, {"extension", "tar.gz"}}, Json{{"label", "TAR.XZ (.tar.xz)"}, {"value", "tar.xz"}, {"format", "pax"}, {"filter", "xz"}, {"extension", "tar.xz"}}, Json{{"label", "TAR.ZST (.tar.zst)"}, {"value", "tar.zst"}, {"format", "pax"}, {"filter", "zstd"}, {"extension", "tar.zst"}}, Json{{"label", "TAR.BZ2 (.tar.bz2)"}, {"value", "tar.bz2"}, {"format", "pax"}, {"filter", "bzip2"}, {"extension", "tar.bz2"}}, Json{{"label", "TAR.LZ4 (.tar.lz4)"}, {"value", "tar.lz4"}, {"format", "pax"}, {"filter", "lz4"}, {"extension", "tar.lz4"}}, Json{{"label", "7Z (.7z)"}, {"value", "7z"}, {"format", "7zip"}, {"filter", ""}, {"extension", "7z"}}}); return Json{{"title", "导入导出"}, {"formats", std::move(formats)}, {"exports", Json::array({Json{{"name", "版本"}, {"api", "/api/export_version"}, {"allow_version_selection", true}}, Json{{"name", "日志"}, {"api", "/api/export_logs"}, {"allow_version_selection", false}}})}, {"import_api", "/api/import_version"}, {"import_accept", ".tar.zstd,.tar.zst,.tar.gz,.tgz,.tar.xz,.txz,.tar.bz2,.tbz2,.tar.lz4,.zip,.7z,.rar,.tar,.cpio,.iso,.xar"}}; } +Json data_source_descriptor() { + auto descriptor = adminive::to_descriptor_json(); + const auto tile_view_descriptor = adminive::to_descriptor_json(); + const auto map_view_descriptor = adminive::to_descriptor_json(); + const auto graphics_descriptor = adminive::to_descriptor_json(); + descriptor["sidebar"] = Json{ + {"title", "数据源配置"}, + {"common", Json{{"fields", Json::array({"update_form_gps", "base_station_has_valid_position", "keep_mode", "ignore_msg_time"})}}}, + {"position", Json{{"fields", Json::array({"lat", "lon", "alt"})}}}, + {"display", Json{ + {"map2d", Json{ + {"title", "2D显示配置"}, + {"object_path", "map_display.map2d"}, + {"fields", Json::array({"aircraft_show", "base_station_show", "show_icao", "show_call_sign", "show_fly_status", "aircraft_pixel_size", "base_station_pixel_size", "track_point_pixel_size", "color", "track_point_color", "base_station_color"})} + }}, + {"map3d", Json{ + {"title", "3D显示配置"}, + {"object_path", "map_display.map3d"}, + {"fields", Json::array({"aircraft_show", "base_station_show", "constant_screen_size", "show_icao", "show_call_sign", "show_fly_status", "aircraft_scale", "base_station_scale", "track_point_pixel_size", "color", "track_point_color", "base_station_color"})} + }} + }}, + {"rules", Json::array({ + Json{{"field", "base_station_has_valid_position"}, {"disabled_when", Json{{"field", "update_form_gps"}, {"equals", true}}}}, + Json{{"field", "lat"}, {"disabled_when", Json{{"field", "update_form_gps"}, {"equals", true}}}}, + Json{{"field", "lon"}, {"disabled_when", Json{{"field", "update_form_gps"}, {"equals", true}}}}, + Json{{"field", "alt"}, {"disabled_when", Json{{"field", "update_form_gps"}, {"equals", true}}}} + })}, + {"tiles", Json{ + {"title", "瓦片显示"}, + {"fields", Json::array({"tile_display_maximum_level"})}, + {"descriptor_fields", tile_view_descriptor.at("fields")} + }}, + {"view3d", Json{ + {"graphics", Json{ + {"title", "辅助显示"}, + {"fields", Json::array({"surface_navigation_reference_visible", "view_axes_visible"})}, + {"descriptor_fields", graphics_descriptor.at("fields")} + }}, + {"map_view", Json{ + {"title", "定位视图"}, + {"fields", Json::array({"base_station_fly_to_height_offset_meters"})}, + {"descriptor_fields", map_view_descriptor.at("fields")} + }} + }} + }; + return descriptor; +} Json cesium_models_schema(Global* global) { Json aircraft_types = Json::array(); global->map_model_config.read([&](const auto& config) { for(const auto& [key, value] : config.aircraft_models) { static_cast(value); - aircraft_types.push_back(key); + auto label = key; + for(std::uint8_t raw = 1; raw <= 21; ++raw) { + const auto type = static_cast(raw); + if(SSR::Vortex_Type_to_key(type) == key) { + label = SSR::Vortex_Type_to_label(type); + break; + } + } + aircraft_types.push_back(Json{{"key", key}, {"label", label}}); } }); - return Json{{"title", "Cesium 模型设置"}, {"data_api", "/map/models"}, {"upload_accept", ".glb"}, {"aircraft_types", std::move(aircraft_types)}}; + const auto item_descriptor = adminive::to_descriptor_json(); + return Json{ + {"title", "Cesium 模型设置"}, + {"data_api", "/map/models"}, + {"upload_accept", ".glb"}, + {"item_descriptor", item_descriptor}, + {"groups", Json::array({ + Json{{"title", "默认飞机模型"}, {"path", "aircraft_model"}, {"upload", Json{{"model_type", "aircraft"}, {"label", "上传飞机模型"}, {"success_message", "默认飞机模型已更新"}}}}, + Json{{"title", "基站模型"}, {"path", "base_station_model"}, {"upload", Json{{"model_type", "base_station"}, {"label", "上传基站模型"}, {"success_message", "基站模型已更新"}}}}, + Json{{"title", "设备模型"}, {"path", "device_model"}, {"upload", Json{{"model_type", "device"}, {"label", "上传设备模型"}, {"success_message", "设备模型已更新"}}}} + })}, + {"collections", Json::array({ + Json{{"title", "按涡流/目标类型选择飞机模型"}, {"path", "aircraft_models"}, {"upload_model_type", "aircraft_type"}, {"upload_label", "上传 GLB"}, {"upload_success_message", "分类飞机模型已更新"}, {"items", std::move(aircraft_types)}} + })} + }; } Json system_actions_schema() { return Json{{"type", "panel"}, {"title", "设备操作"}, {"body", Json::array({Json{{"type", "button"}, {"label", "重启 FPGA 设备"}, {"level", "primary"}, {"actionType", "ajax"}, {"confirmText", "确定重启 FPGA 设备?"}, {"api", Json{{"method", "post"}, {"url", "/api/restart_device"}}}}})}}; @@ -830,7 +899,7 @@ private: const auto patch = adminive::make_drogon_constraints(drogon::Patch, {}); const auto remove = adminive::make_drogon_constraints(drogon::Delete, {}); app.registerHandler(data_sources_path + "/descriptor", [](const drogon::HttpRequestPtr&, std::function&& callback) { - callback(adminive::make_drogon_response(adminive::make_http_success(adminive::to_descriptor_json()))); + callback(adminive::make_drogon_response(adminive::make_http_success(data_source_descriptor()))); }, get); app.registerHandler(data_sources_path + "/view", [](const drogon::HttpRequestPtr&, std::function&& callback) { callback(adminive::make_drogon_response(adminive::make_http_success(adminive::to_view_json(adminive::describe_table_view())))); diff --git a/module/Local_Server/server/Config.cpp b/module/Local_Server/server/Config.cpp index acd1a4e..dec60d2 100644 --- a/module/Local_Server/server/Config.cpp +++ b/module/Local_Server/server/Config.cpp @@ -459,10 +459,11 @@ void Map_View_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_ map2d.from_base_json(that_json->get("map2d"), not_exist_use_default_value); map3d.from_base_json(that_json->get("map3d"), not_exist_use_default_value); camera.from_base_json(that_json->get("camera"), not_exist_use_default_value); + const auto height_key = that_json->get("base_station_fly_to_height_offset_meters") + ? "base_station_fly_to_height_offset_meters" + : "baseStationFlyToHeightOffsetMeters"; base_station_fly_to_height_offset_meters = - std::max(100.0, - read_optional_double_field(that_json, "baseStationFlyToHeightOffsetMeters", - base_station_fly_to_height_offset_meters)); + std::max(100.0, read_optional_double_field(that_json, height_key, base_station_fly_to_height_offset_meters)); } Psc::JSON Map_View_Config::to_base_json() const { auto ret = Psc::JSON::object(); @@ -470,7 +471,7 @@ Psc::JSON Map_View_Config::to_base_json() const { ret.append({"map2d", map2d.to_base_json()}); ret.append({"map3d", map3d.to_base_json()}); ret.append({"camera", camera.to_base_json()}); - ret.append({"baseStationFlyToHeightOffsetMeters", base_station_fly_to_height_offset_meters}); + ret.append({"base_station_fly_to_height_offset_meters", base_station_fly_to_height_offset_meters}); return ret; } void Cesium_Graphics_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { diff --git a/module/Local_Server/server/Config.h b/module/Local_Server/server/Config.h index 846041c..0c095c7 100644 --- a/module/Local_Server/server/Config.h +++ b/module/Local_Server/server/Config.h @@ -400,6 +400,20 @@ struct Map_Model_Item_Config { void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; }; +namespace adminive { +template <> +struct Type_Descriptor { + static auto get() { + using T = Map_Model_Item_Config; + return object("map_model_item_config", "Cesium 模型", + ADMINIVE_FIELD_LABEL(T, url, "模型地址"), + ADMINIVE_FIELD_LABEL(T, built_in_size, "模型原始尺寸").editable().number_input(), + ADMINIVE_FIELD_LABEL(T, heading_offset_degrees, "航向偏移(度)").editable().number_input(), + ADMINIVE_FIELD_LABEL(T, pitch_offset_degrees, "俯仰偏移(度)").editable().number_input(), + ADMINIVE_FIELD_LABEL(T, roll_offset_degrees, "横滚偏移(度)").editable().number_input()); + } +}; +} struct Map_Model_Config { Map_Model_Item_Config aircraft_model{"/ui/model/aircraft.glb", 50.0, -90.0, 0.0, 0.0}; std::map aircraft_models; diff --git a/module/Local_Server/server/tiles.cpp b/module/Local_Server/server/tiles.cpp index 9169a9f..7b5e943 100644 --- a/module/Local_Server/server/tiles.cpp +++ b/module/Local_Server/server/tiles.cpp @@ -545,9 +545,24 @@ void register_map_graphics_handler() { {drogon::Get, drogon::Post}); } Psc::JSON make_map_view_response(Global* global) { - auto ret = global->map_view_config.read([](const auto& config) { - return config.to_base_json(); + auto view = global->map_view_config.read([](const auto& config) { + return config; }); + global->map_resources_config.read([&](const auto& config) { + const auto first_key = [&](Map_Tile_Type type) { + const auto item = std::ranges::find_if(config.tile_sources, [type](const auto& source) { + return source.tile_type == type; + }); + return item == config.tile_sources.end() ? std::string{} : item->key; + }; + if(!config.is_imagery_key(view.map2d.current_imagery_key)) + view.map2d.current_imagery_key = config.current_imagery_key; + if(!config.is_imagery_key(view.map3d.current_imagery_key)) + view.map3d.current_imagery_key = config.current_imagery_key; + if(!view.map3d.current_terrain_key.empty() && !config.is_terrain_key(view.map3d.current_terrain_key)) + view.map3d.current_terrain_key = first_key(Map_Tile_Type::terrain); + }); + auto ret = view.to_base_json(); global->map_resources_config.read([&](const auto& config) { ret.append({"current_imagery_key", config.current_imagery_key}); });