feat: implement spatial boundary checks for Bari municipal area in GeoJSON handling
This commit is contained in:
@@ -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 = ?",
|
||||
|
||||
Reference in New Issue
Block a user