This commit is contained in:
@@ -11,6 +11,8 @@ namespace lm {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char* kBaseImageName = "map_base.png";
|
||||
|
||||
constexpr const char* kMapSelect =
|
||||
"SELECT id, name, description, site_id, created_by, width, height, resolution, "
|
||||
"origin_x, origin_y, origin_yaw, image_file, yaml_file, zones_json, created_at, updated_at "
|
||||
@@ -220,7 +222,14 @@ bool MapStore::update(const std::string& id, const nlohmann::json& payload, std:
|
||||
merged[key] = payload[key];
|
||||
}
|
||||
if (payload.contains("zones"))
|
||||
{
|
||||
if (!payload["zones"].is_array())
|
||||
{
|
||||
err = "zones must be an array";
|
||||
return false;
|
||||
}
|
||||
merged["zones"] = payload["zones"];
|
||||
}
|
||||
|
||||
const std::string now = IdUtil::nowIso8601();
|
||||
const std::string zones_str = merged.value("zones", nlohmann::json::array()).dump();
|
||||
@@ -307,6 +316,14 @@ std::optional<std::filesystem::path> MapStore::imagePath(const std::string& id)
|
||||
return path;
|
||||
}
|
||||
|
||||
std::optional<std::filesystem::path> MapStore::baseImagePath(const std::string& id) const
|
||||
{
|
||||
const auto base = mapDir(id) / kBaseImageName;
|
||||
if (std::filesystem::exists(base))
|
||||
return base;
|
||||
return imagePath(id);
|
||||
}
|
||||
|
||||
std::optional<std::filesystem::path> MapStore::yamlPath(const std::string& id) const
|
||||
{
|
||||
const auto map = find(id);
|
||||
@@ -338,6 +355,13 @@ bool MapStore::saveImageFile(const std::string& id,
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto base_path = mapDir(id) / kBaseImageName;
|
||||
if (!FileUtil::writeBinaryAtomic(base_path, bytes))
|
||||
{
|
||||
err = "failed to write base image file";
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string now = IdUtil::nowIso8601();
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
sqlite3_stmt* stmt = nullptr;
|
||||
@@ -360,6 +384,99 @@ bool MapStore::saveImageFile(const std::string& id,
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool MapStore::saveCompositeImageFile(const std::string& id, const std::string& bytes, std::string& err)
|
||||
{
|
||||
const auto map = find(id);
|
||||
if (!map)
|
||||
{
|
||||
err = "map not found";
|
||||
return false;
|
||||
}
|
||||
const std::string filename = map->value("image_file", "map.png");
|
||||
if (filename.empty())
|
||||
{
|
||||
err = "map has no image file";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(mapDir(id), ec);
|
||||
const auto path = mapDir(id) / filename;
|
||||
if (!FileUtil::writeBinaryAtomic(path, bytes))
|
||||
{
|
||||
err = "failed to write composite image file";
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto base_path = mapDir(id) / kBaseImageName;
|
||||
if (!std::filesystem::exists(base_path))
|
||||
{
|
||||
if (!FileUtil::writeBinaryAtomic(base_path, bytes))
|
||||
{
|
||||
err = "failed to initialize base image file";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string now = IdUtil::nowIso8601();
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
sqlite3_stmt* stmt = nullptr;
|
||||
if (sqlite3_prepare_v2(db_.handle(),
|
||||
"UPDATE maps SET updated_at = ?2 WHERE id = ?1",
|
||||
-1,
|
||||
&stmt,
|
||||
nullptr) != SQLITE_OK)
|
||||
{
|
||||
err = sqlite3_errmsg(db_.handle());
|
||||
return false;
|
||||
}
|
||||
sqlite3_bind_text(stmt, 1, id.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 2, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
const bool ok = sqlite3_step(stmt) == SQLITE_DONE;
|
||||
if (!ok)
|
||||
err = sqlite3_errmsg(db_.handle());
|
||||
sqlite3_finalize(stmt);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool MapStore::saveBaseImageFile(const std::string& id, const std::string& bytes, std::string& err)
|
||||
{
|
||||
if (!find(id))
|
||||
{
|
||||
err = "map not found";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(mapDir(id), ec);
|
||||
const auto path = mapDir(id) / kBaseImageName;
|
||||
if (!FileUtil::writeBinaryAtomic(path, bytes))
|
||||
{
|
||||
err = "failed to write base image file";
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string now = IdUtil::nowIso8601();
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
sqlite3_stmt* stmt = nullptr;
|
||||
if (sqlite3_prepare_v2(db_.handle(),
|
||||
"UPDATE maps SET updated_at = ?2 WHERE id = ?1",
|
||||
-1,
|
||||
&stmt,
|
||||
nullptr) != SQLITE_OK)
|
||||
{
|
||||
err = sqlite3_errmsg(db_.handle());
|
||||
return false;
|
||||
}
|
||||
sqlite3_bind_text(stmt, 1, id.c_str(), -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 2, now.c_str(), -1, SQLITE_TRANSIENT);
|
||||
const bool ok = sqlite3_step(stmt) == SQLITE_DONE;
|
||||
if (!ok)
|
||||
err = sqlite3_errmsg(db_.handle());
|
||||
sqlite3_finalize(stmt);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool MapStore::saveYamlFile(const std::string& id, const std::string& yaml_text, std::string& err)
|
||||
{
|
||||
if (!find(id))
|
||||
|
||||
Reference in New Issue
Block a user