3D
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "Core/Base/Check.h"
|
||||
#include "Core/Net_Adapter/Net_Adapter.h"
|
||||
#include "Global.h"
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
#undef interface
|
||||
@@ -26,6 +27,281 @@ std::string get_config_path() {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static std::vector<std::string> read_string_array(const Psc::JSON* json, std::string_view key) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr || field->valueType != Psc::Array) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
std::vector<std::string> ret;
|
||||
ret.reserve(field->children.size());
|
||||
for (const auto& child : field->children) {
|
||||
if (child.valueType != Psc::String) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
ret.emplace_back(child.val);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static Psc::JSON write_string_array(std::string_view key, const std::vector<std::string>& list) {
|
||||
auto array = Psc::JSON::array();
|
||||
for (const auto& path : list) {
|
||||
array.append(Psc::JSON(path));
|
||||
}
|
||||
return Psc::JSON(key, array);
|
||||
}
|
||||
static std::string read_string_field(const Psc::JSON* json, std::string_view key) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr || field->valueType != Psc::String) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->val;
|
||||
}
|
||||
static std::uint32_t read_uint32_field(const Psc::JSON* json, std::string_view key) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr || field->valueType != Psc::Number) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->number_val<std::uint32_t>();
|
||||
}
|
||||
static std::string read_optional_string_field(const Psc::JSON* json, std::string_view key) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr) {
|
||||
return {};
|
||||
}
|
||||
if (field->valueType != Psc::String) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->val;
|
||||
}
|
||||
static std::string read_optional_string_field(const Psc::JSON* json, std::string_view key, std::string_view fallback) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr) {
|
||||
return std::string(fallback);
|
||||
}
|
||||
if (field->valueType != Psc::String) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->val;
|
||||
}
|
||||
static bool read_optional_bool_field(const Psc::JSON* json, std::string_view key, bool fallback) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr) {
|
||||
return fallback;
|
||||
}
|
||||
if (field->valueType != Psc::Bool) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->bool_val();
|
||||
}
|
||||
static std::uint32_t read_optional_uint32_field(const Psc::JSON* json, std::string_view key, std::uint32_t fallback) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr) {
|
||||
return fallback;
|
||||
}
|
||||
if (field->valueType != Psc::Number) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->number_val<std::uint32_t>();
|
||||
}
|
||||
static double read_optional_double_field(const Psc::JSON* json, std::string_view key, double fallback) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr) {
|
||||
return fallback;
|
||||
}
|
||||
if (field->valueType != Psc::Number) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
}
|
||||
return field->number_val<double>();
|
||||
}
|
||||
void Map_Tile_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
if (that_json == nullptr || that_json->valueType != Psc::Object) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map tile config");
|
||||
}
|
||||
directories = read_string_array(that_json, "directories");
|
||||
path_layout = read_string_field(that_json, "path_layout");
|
||||
y_axis = read_string_field(that_json, "y_axis");
|
||||
projection = read_string_field(that_json, "projection");
|
||||
extension = read_string_field(that_json, "extension");
|
||||
tile_size = read_uint32_field(that_json, "tile_size");
|
||||
minimum_level = read_uint32_field(that_json, "minimum_level");
|
||||
maximum_level = read_uint32_field(that_json, "maximum_level");
|
||||
encoding = read_optional_string_field(that_json, "encoding");
|
||||
}
|
||||
Psc::JSON Map_Tile_Config::to_base_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append(write_string_array("directories", directories));
|
||||
ret.append({"path_layout", path_layout});
|
||||
ret.append({"y_axis", y_axis});
|
||||
ret.append({"projection", projection});
|
||||
ret.append({"extension", extension});
|
||||
ret.append({"tile_size", tile_size});
|
||||
ret.append({"minimum_level", minimum_level});
|
||||
ret.append({"maximum_level", maximum_level});
|
||||
if (!encoding.empty()) {
|
||||
ret.append({"encoding", encoding});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
Psc::JSON Map_Tile_Config::to_public_json(std::string_view url) const {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"url", std::string(url)});
|
||||
ret.append({"minimum_level", minimum_level});
|
||||
ret.append({"maximum_level", maximum_level});
|
||||
ret.append({"tile_size", tile_size});
|
||||
ret.append({"projection", projection});
|
||||
ret.append({"y_axis", y_axis});
|
||||
if (!encoding.empty()) {
|
||||
ret.append({"encoding", encoding});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void Map_Resources_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
if (that_json == nullptr || that_json->valueType != Psc::Object) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map_resources");
|
||||
}
|
||||
current_imagery_key = read_optional_string_field(that_json, "current_imagery_key");
|
||||
if (current_imagery_key.empty()) {
|
||||
current_imagery_key = "imagery";
|
||||
}
|
||||
imagery.from_base_json(that_json->get("imagery"));
|
||||
google_imagery.from_base_json(that_json->get("google_imagery"));
|
||||
terrain.from_base_json(that_json->get("terrain"));
|
||||
if (!is_imagery_key(current_imagery_key)) {
|
||||
current_imagery_key = "imagery";
|
||||
}
|
||||
}
|
||||
Psc::JSON Map_Resources_Config::to_base_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"current_imagery_key", current_imagery_key});
|
||||
ret.append({"imagery", imagery.to_base_json()});
|
||||
ret.append({"google_imagery", google_imagery.to_base_json()});
|
||||
ret.append({"terrain", terrain.to_base_json()});
|
||||
return ret;
|
||||
}
|
||||
static Psc::JSON make_public_imagery_source(std::string_view key, std::string_view name, const Psc::JSON& resource) {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"key", std::string(key)});
|
||||
ret.append({"name", std::string(name)});
|
||||
ret.append({"resource", resource});
|
||||
return ret;
|
||||
}
|
||||
static Psc::JSON make_osm_public_resource() {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"url", "https://tile.openstreetmap.org/{z}/{x}/{y}.png"});
|
||||
ret.append({"minimum_level", 0});
|
||||
ret.append({"maximum_level", 19});
|
||||
ret.append({"tile_size", 256});
|
||||
ret.append({"projection", "web_mercator"});
|
||||
ret.append({"y_axis", "xyz"});
|
||||
ret.append({"credit", "OpenStreetMap contributors"});
|
||||
return ret;
|
||||
}
|
||||
Psc::JSON Map_Resources_Config::to_public_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
auto imagery_json = imagery.to_public_json("/map/imagery/{z}/{x}/{y}");
|
||||
auto google_imagery_json = google_imagery.to_public_json("/tiles/{z}/{x}/{y}");
|
||||
auto osm_json = make_osm_public_resource();
|
||||
auto sources = Psc::JSON::array();
|
||||
sources.append(make_public_imagery_source("imagery", "本地卫星影像", imagery_json));
|
||||
sources.append(make_public_imagery_source("google_imagery", "本地Google瓦片", google_imagery_json));
|
||||
sources.append(make_public_imagery_source("osm_online", "OpenStreetMap在线", osm_json));
|
||||
ret.append({"current_imagery_key", current_imagery_key});
|
||||
ret.append({"imagery_sources", sources});
|
||||
ret.append({"imagery", imagery_json});
|
||||
ret.append({"google_imagery", google_imagery_json});
|
||||
ret.append({"terrain", terrain.to_public_json("/map/terrain/{z}/{x}/{y}")});
|
||||
return ret;
|
||||
}
|
||||
bool Map_Resources_Config::is_imagery_key(std::string_view key) const {
|
||||
return key == "imagery" || key == "google_imagery" || key == "osm_online";
|
||||
}
|
||||
void Map_Camera_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
if (that_json == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (that_json->valueType != Psc::Object) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map camera");
|
||||
}
|
||||
longitude = read_optional_double_field(that_json, "longitude", longitude);
|
||||
latitude = read_optional_double_field(that_json, "latitude", latitude);
|
||||
height = read_optional_double_field(that_json, "height", height);
|
||||
heading = read_optional_double_field(that_json, "heading", heading);
|
||||
pitch = read_optional_double_field(that_json, "pitch", pitch);
|
||||
roll = read_optional_double_field(that_json, "roll", roll);
|
||||
}
|
||||
Psc::JSON Map_Camera_Config::to_base_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"longitude", longitude});
|
||||
ret.append({"latitude", latitude});
|
||||
ret.append({"height", height});
|
||||
ret.append({"heading", heading});
|
||||
ret.append({"pitch", pitch});
|
||||
ret.append({"roll", roll});
|
||||
return ret;
|
||||
}
|
||||
bool Map_View_Config::is_scene_mode(std::string_view mode) {
|
||||
return mode == "2d" || mode == "2.5d" || mode == "3d";
|
||||
}
|
||||
void Map_View_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
if (that_json == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (that_json->valueType != Psc::Object) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "map_view");
|
||||
}
|
||||
auto next_scene_mode = read_optional_string_field(that_json, "scene_mode", scene_mode);
|
||||
if (!is_scene_mode(next_scene_mode)) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "scene_mode");
|
||||
}
|
||||
scene_mode = next_scene_mode;
|
||||
camera.from_base_json(that_json->get("camera"));
|
||||
}
|
||||
Psc::JSON Map_View_Config::to_base_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"scene_mode", scene_mode});
|
||||
ret.append({"camera", camera.to_base_json()});
|
||||
return ret;
|
||||
}
|
||||
void Cesium_Graphics_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
if (that_json == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (that_json->valueType != Psc::Object) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "cesium_graphics");
|
||||
}
|
||||
debug_show_frames_per_second = read_optional_bool_field(that_json, "debug_show_frames_per_second", debug_show_frames_per_second);
|
||||
target_frame_rate = std::clamp(read_optional_uint32_field(that_json, "target_frame_rate", target_frame_rate), 1u, 120u);
|
||||
use_browser_recommended_resolution = read_optional_bool_field(that_json, "use_browser_recommended_resolution", use_browser_recommended_resolution);
|
||||
resolution_scale = std::clamp(read_optional_double_field(that_json, "resolution_scale", resolution_scale), 0.2, 1.5);
|
||||
msaa_samples = std::clamp(read_optional_uint32_field(that_json, "msaa_samples", msaa_samples), 1u, 8u);
|
||||
fxaa = read_optional_bool_field(that_json, "fxaa", fxaa);
|
||||
shadows = read_optional_bool_field(that_json, "shadows", shadows);
|
||||
enable_lighting = read_optional_bool_field(that_json, "enable_lighting", enable_lighting);
|
||||
maximum_screen_space_error = std::clamp(read_optional_uint32_field(that_json, "maximum_screen_space_error", maximum_screen_space_error), 1u, 16u);
|
||||
terrain_enabled_in_3d = read_optional_bool_field(that_json, "terrain_enabled_in_3d", terrain_enabled_in_3d);
|
||||
terrain_exaggeration = std::clamp(read_optional_double_field(that_json, "terrain_exaggeration", terrain_exaggeration), 0.0, 5.0);
|
||||
terrain_limit_maximum_level = read_optional_bool_field(that_json, "terrain_limit_maximum_level", terrain_limit_maximum_level);
|
||||
terrain_maximum_level = std::clamp(read_optional_uint32_field(that_json, "terrain_maximum_level", terrain_maximum_level), 0u, 24u);
|
||||
terrain_cache_tiles = std::clamp(read_optional_uint32_field(that_json, "terrain_cache_tiles", terrain_cache_tiles), 16u, 2048u);
|
||||
}
|
||||
Psc::JSON Cesium_Graphics_Config::to_base_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
ret.append({"debug_show_frames_per_second", debug_show_frames_per_second});
|
||||
ret.append({"target_frame_rate", target_frame_rate});
|
||||
ret.append({"use_browser_recommended_resolution", use_browser_recommended_resolution});
|
||||
ret.append({"resolution_scale", resolution_scale});
|
||||
ret.append({"msaa_samples", msaa_samples});
|
||||
ret.append({"fxaa", fxaa});
|
||||
ret.append({"shadows", shadows});
|
||||
ret.append({"enable_lighting", enable_lighting});
|
||||
ret.append({"maximum_screen_space_error", maximum_screen_space_error});
|
||||
ret.append({"terrain_enabled_in_3d", terrain_enabled_in_3d});
|
||||
ret.append({"terrain_exaggeration", terrain_exaggeration});
|
||||
ret.append({"terrain_limit_maximum_level", terrain_limit_maximum_level});
|
||||
ret.append({"terrain_maximum_level", terrain_maximum_level});
|
||||
ret.append({"terrain_cache_tiles", terrain_cache_tiles});
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Mode_ACS_Config::server(Global *g) {
|
||||
auto &svr = g->svr;
|
||||
|
||||
Reference in New Issue
Block a user