use chrono::{DateTime, NaiveDate, Utc};
use serde::{Deserialize, Serialize};
use crate::models::{NetRelation, Netelement};
pub const DEFAULT_RETRIEVAL_BUFFER_METERS: f64 = 1000.0;
pub const DEFAULT_RINF_ENDPOINT: &str = "https://graph.data.era.europa.eu/repositories/rinf-plus";
pub const COARSE_GEOMETRY_LENGTH_THRESHOLD_METERS: f64 = 250.0;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct RetrievalArea {
pub min_longitude: f64,
pub max_longitude: f64,
pub min_latitude: f64,
pub max_latitude: f64,
pub expansion_meters: f64,
pub polygon_wkt: String,
pub source_crs: String,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum WorkflowKind {
Projection,
PathCalculation,
DetectionPreparation,
PathReview,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AutoTopologyRequest {
pub workflow_kind: WorkflowKind,
pub supplied_topology_present: bool,
pub rinf_endpoint_url: String,
pub retrieval_area: Option<RetrievalArea>,
pub requested_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RinfNetelementRow {
pub netelement_iri: String,
pub netelement_id: String,
pub wkt: String,
pub geometry_point_count: usize,
pub length_meters: f64,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "PascalCase")]
pub enum RinfNavigability {
Both,
AB,
BA,
None,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RinfNetrelationRow {
pub netrelation_iri: String,
pub element_a_id: String,
pub element_b_id: String,
pub is_on_origin_of_element_a: bool,
pub is_on_origin_of_element_b: bool,
pub navigability: RinfNavigability,
pub valid_on_date: NaiveDate,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TopologyValidationStatus {
Valid,
MissingCoverage,
IncompleteTopology,
InvalidInput,
EndpointFailure,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TopologyValidationReport {
pub status: TopologyValidationStatus,
pub netelement_count: usize,
pub netrelation_count: usize,
pub coarse_geometry_ids: Vec<String>,
pub uncovered_gnss_indices: Vec<usize>,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetrievedTopology {
pub netelements: Vec<Netelement>,
pub netrelations: Vec<NetRelation>,
pub retrieval_area: RetrievalArea,
pub endpoint_url: String,
pub retrieved_at: DateTime<Utc>,
pub validation_report: TopologyValidationReport,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TopologySource {
SuppliedTopology,
EraRinf,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum RetrievalStatus {
Success,
InvalidInput,
MissingCoverage,
IncompleteTopology,
EndpointFailure,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetrievalOutcome {
pub source_used: TopologySource,
pub status: RetrievalStatus,
pub detail_message: String,
pub diagnostic_area_wkt: Option<String>,
pub affected_gnss_indices: Vec<usize>,
}
impl RetrievalOutcome {
pub fn supplied_success() -> Self {
Self {
source_used: TopologySource::SuppliedTopology,
status: RetrievalStatus::Success,
detail_message: "Using supplied topology".to_string(),
diagnostic_area_wkt: None,
affected_gnss_indices: Vec::new(),
}
}
}