feat: implement spatial boundary checks for Bari municipal area in GeoJSON handling

This commit is contained in:
gabdevele
2026-06-15 14:45:38 +02:00 Unverified
parent 088a2ed866
commit aab7420706
13 changed files with 310 additions and 15 deletions
+39
View File
@@ -1,5 +1,6 @@
#include "services/AdminService.h"
#include "common/GeoJson.h"
#include "common/Validation.h"
#include "repositories/Sql.h"
#include "services/UserService.h"
@@ -7,6 +8,7 @@
#include <drogon/drogon.h>
#include <algorithm>
#include <sstream>
namespace visione::services
{
@@ -87,6 +89,35 @@ bool isActiveField(const Json::Value &body)
{
return body.isMember("active") && body["active"].isBool();
}
std::optional<Json::Value> loadAllowedBoundary(const std::string &code)
{
const auto rows = drogon::app().getDbClient()->execSqlSync(
"SELECT JSON_UNQUOTE(JSON_EXTRACT(boundary_geojson, '$')) AS geojson "
"FROM allowed_boundaries WHERE code = ? AND active = TRUE LIMIT 1",
code);
if (rows.empty())
{
return std::nullopt;
}
Json::CharReaderBuilder builder;
Json::Value geojson;
std::string errors;
std::istringstream stream(rows[0]["geojson"].as<std::string>());
if (!Json::parseFromStream(builder, stream, &geojson, &errors))
{
return std::nullopt;
}
return geojson;
}
bool isAreaInsideAllowedBoundary(const Json::Value &boundaryGeojson)
{
const auto allowed = loadAllowedBoundary("BARI");
return allowed &&
geojson::polygonInsideGeometry(boundaryGeojson, *allowed);
}
} // namespace
Json::Value AdminService::createCategory(const auth::UserContext &user,
@@ -119,6 +150,10 @@ Json::Value AdminService::createArea(const auth::UserContext &user,
{
return failure("invalid_area");
}
if (!isAreaInsideAllowedBoundary(body["boundary_geojson"]))
{
return failure("area_outside_allowed_boundary");
}
Json::StreamWriterBuilder writer;
drogon::app().getDbClient()->execSqlSync(
@@ -410,6 +445,10 @@ Json::Value AdminService::updateArea(const auth::UserContext &user,
}
if (body["boundary_geojson"].isObject())
{
if (!isAreaInsideAllowedBoundary(body["boundary_geojson"]))
{
return failure("area_outside_allowed_boundary");
}
Json::StreamWriterBuilder writer;
db->execSqlSync(
"UPDATE areas SET boundary_geojson = CAST(? AS JSON) WHERE id = ?",