1use crate::{
8 alignment::{
9 LandXmlAlignment as LandXmlHorizontalAlignment, LandXmlAlignmentDocument,
10 LandXmlAlignmentRenderData,
11 },
12 LandXmlAlignment as LandXmlTerrainAlignment, LandXmlCapabilityDiagnostic, LandXmlCgPoint,
13 LandXmlCrossSection, LandXmlCrossSectionSurface, LandXmlExtension, LandXmlMonument,
14 LandXmlParcel, LandXmlPipeFeature, LandXmlPipeNetwork, LandXmlPipeNetworkCollection,
15 LandXmlPipeNetworkDocument, LandXmlPipeRefusal, LandXmlPlanDocument, LandXmlPlanFeature,
16 LandXmlPlanPoint, LandXmlPlanSourceBatch, LandXmlPreservedOnlyExtension, LandXmlProfile,
17 LandXmlRoadway, LandXmlTinDocument, LandXmlUnits,
18};
19use serde::{Deserialize, Serialize};
20
21#[derive(Clone, Debug, Serialize)]
22pub struct LandXmlStreamHeader {
23 pub version: String,
24 pub units: Option<LandXmlUnits>,
27}
28
29#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
30#[serde(rename_all = "snake_case")]
31pub enum LandXmlSurfaceComponent {
32 Start,
33 Points,
34 CanonicalVertices,
35 SourceDataPoints,
36 Faces,
37 Boundaries,
38 Breaklines,
39 Contours,
40 End,
41}
42
43#[derive(Clone, Debug, Serialize)]
44pub struct LandXmlSurfaceFragment {
45 pub source_id: String,
46 pub component: LandXmlSurfaceComponent,
47 pub sequence: usize,
48 pub continued: bool,
49 pub payload_utf8: Vec<u8>,
50}
51
52#[derive(Clone, Debug, Serialize)]
53#[serde(tag = "kind", rename_all = "snake_case")]
54pub enum LandXmlStreamEvent {
55 Header(LandXmlStreamHeader),
56 Surface(LandXmlSurfaceFragment),
57 Metadata(Box<LandXmlMetadataStreamEvent>),
60}
61
62#[derive(Clone, Debug, Serialize)]
66pub struct LandXmlMetadataStreamHeader {
67 pub stream: LandXmlStreamHeader,
68 pub terrain: LandXmlTinDocument,
69 pub plan: LandXmlPlanDocument,
70 pub alignments: LandXmlAlignmentDocument,
71 pub pipe_networks: LandXmlPipeNetworkDocument,
72}
73
74#[derive(Clone, Debug, Deserialize, Serialize)]
77#[serde(tag = "record", content = "value", rename_all = "snake_case")]
78pub enum LandXmlMetadataRecord {
79 TerrainExtension(LandXmlExtension),
80 TerrainWarning(String),
81 TerrainAlignment(LandXmlTerrainAlignment),
82 TerrainProfile(LandXmlProfile),
83 TerrainCrossSection(LandXmlCrossSection),
84 TerrainCrossSectionSurface(LandXmlCrossSectionSurface),
85 TerrainRoadway(LandXmlRoadway),
86 TerrainCapabilityDiagnostic(LandXmlCapabilityDiagnostic),
87 TerrainPreservedOnlyExtension(LandXmlPreservedOnlyExtension),
88 PlanCogoPoint(LandXmlCgPoint),
89 PlanMonument(LandXmlMonument),
90 PlanFeature(LandXmlPlanFeature),
91 PlanParcel(LandXmlParcel),
92 PlanWarning(String),
93 PlanSourceBatch(LandXmlPlanSourceBatch),
96 PlanParcelProbe(LandXmlPlanParcelProbe),
97 PlanResolvedMonument(LandXmlPlanResolvedMonument),
98 PlanResolvedGeometry(LandXmlPlanResolvedGeometry),
99 AlignmentRenderSpan(crate::alignment::LandXmlAlignmentRenderSpan),
100 AlignmentRenderRefusal(crate::alignment::LandXmlAlignmentRenderRefusal),
101 AlignmentRenderTruncated(bool),
102 HorizontalAlignment(LandXmlHorizontalAlignment),
103 HorizontalAlignmentWarning(String),
104 PipeCollection(LandXmlPipeNetworkCollection),
105 PipeFeature(LandXmlPipeFeature),
106 PipePreflightRefusal(LandXmlPipeRefusal),
109 PipeNetwork(LandXmlPipeNetwork),
110 PipeRefusal(LandXmlPipeRefusal),
111}
112
113#[derive(Clone, Debug, Deserialize, Serialize)]
115pub struct LandXmlPlanParcelProbe {
116 pub source_id: crate::LandXmlSourceId,
117 #[serde(flatten)]
118 pub probe: crate::LandXmlParcelProbe,
119}
120
121#[derive(Clone, Debug, Deserialize, Serialize)]
123pub struct LandXmlPlanResolvedMonument {
124 pub source_id: crate::LandXmlSourceId,
125 pub point: Option<LandXmlPlanPoint>,
126}
127
128#[derive(Clone, Debug, Deserialize, Serialize)]
130pub struct LandXmlPlanResolvedGeometry {
131 pub source_id: crate::LandXmlSourceId,
132 pub start: Option<LandXmlPlanPoint>,
133 pub end: Option<LandXmlPlanPoint>,
134 pub center: Option<LandXmlPlanPoint>,
135 pub pi: Option<LandXmlPlanPoint>,
136}
137
138#[derive(Clone, Debug, Serialize)]
140pub struct LandXmlMetadataStreamEnd {
141 pub surfaces_drained: usize,
142 pub renderable_surfaces: usize,
143 pub preserved_surfaces: usize,
144 pub plan_cogo_points: usize,
145 pub plan_parcels: usize,
146 pub horizontal_alignments: usize,
147 pub has_pipe_networks: bool,
150 pub pipe_networks: usize,
151 pub pipe_structures: usize,
152 pub pipes: usize,
153 pub pipe_refusals: usize,
154}
155
156#[derive(Clone, Debug, Serialize)]
158#[serde(tag = "metadata_kind", rename_all = "snake_case")]
159pub enum LandXmlMetadataStreamEvent {
160 Header(Box<LandXmlMetadataStreamHeader>),
163 Record(Box<LandXmlMetadataRecord>),
166 RecordFragment(LandXmlMetadataRecordFragment),
171 End(LandXmlMetadataStreamEnd),
172}
173
174#[derive(Clone, Debug, Serialize)]
176pub struct LandXmlMetadataRecordFragment {
177 pub record: String,
178 pub sequence: usize,
179 pub continued: bool,
180 pub payload_utf8: Vec<u8>,
181}
182
183impl LandXmlMetadataRecord {
184 pub(crate) fn wire_name(&self) -> &'static str {
185 match self {
186 Self::TerrainExtension(_) => "terrain_extension",
187 Self::TerrainWarning(_) => "terrain_warning",
188 Self::TerrainAlignment(_) => "terrain_alignment",
189 Self::TerrainProfile(_) => "terrain_profile",
190 Self::TerrainCrossSection(_) => "terrain_cross_section",
191 Self::TerrainCrossSectionSurface(_) => "terrain_cross_section_surface",
192 Self::TerrainRoadway(_) => "terrain_roadway",
193 Self::TerrainCapabilityDiagnostic(_) => "terrain_capability_diagnostic",
194 Self::TerrainPreservedOnlyExtension(_) => "terrain_preserved_only_extension",
195 Self::PlanCogoPoint(_) => "plan_cogo_point",
196 Self::PlanMonument(_) => "plan_monument",
197 Self::PlanFeature(_) => "plan_feature",
198 Self::PlanParcel(_) => "plan_parcel",
199 Self::PlanWarning(_) => "plan_warning",
200 Self::PlanSourceBatch(_) => "plan_source_batch",
201 Self::PlanParcelProbe(_) => "plan_parcel_probe",
202 Self::PlanResolvedMonument(_) => "plan_resolved_monument",
203 Self::PlanResolvedGeometry(_) => "plan_resolved_geometry",
204 Self::AlignmentRenderSpan(_) => "alignment_render_span",
205 Self::AlignmentRenderRefusal(_) => "alignment_render_refusal",
206 Self::AlignmentRenderTruncated(_) => "alignment_render_truncated",
207 Self::HorizontalAlignment(_) => "horizontal_alignment",
208 Self::HorizontalAlignmentWarning(_) => "horizontal_alignment_warning",
209 Self::PipeCollection(_) => "pipe_collection",
210 Self::PipeFeature(_) => "pipe_feature",
211 Self::PipePreflightRefusal(_) => "pipe_preflight_refusal",
212 Self::PipeNetwork(_) => "pipe_network",
213 Self::PipeRefusal(_) => "pipe_refusal",
214 }
215 }
216
217 pub(crate) fn serialize_value(&self) -> Result<Vec<u8>, serde_json::Error> {
218 match self {
219 Self::TerrainExtension(value) => serde_json::to_vec(value),
220 Self::TerrainWarning(value) => serde_json::to_vec(value),
221 Self::TerrainAlignment(value) => serde_json::to_vec(value),
222 Self::TerrainProfile(value) => serde_json::to_vec(value),
223 Self::TerrainCrossSection(value) => serde_json::to_vec(value),
224 Self::TerrainCrossSectionSurface(value) => serde_json::to_vec(value),
225 Self::TerrainRoadway(value) => serde_json::to_vec(value),
226 Self::TerrainCapabilityDiagnostic(value) => serde_json::to_vec(value),
227 Self::TerrainPreservedOnlyExtension(value) => serde_json::to_vec(value),
228 Self::PlanCogoPoint(value) => serde_json::to_vec(value),
229 Self::PlanMonument(value) => serde_json::to_vec(value),
230 Self::PlanFeature(value) => serde_json::to_vec(value),
231 Self::PlanParcel(value) => serde_json::to_vec(value),
232 Self::PlanWarning(value) => serde_json::to_vec(value),
233 Self::PlanSourceBatch(value) => serde_json::to_vec(value),
234 Self::PlanParcelProbe(value) => serde_json::to_vec(value),
235 Self::PlanResolvedMonument(value) => serde_json::to_vec(value),
236 Self::PlanResolvedGeometry(value) => serde_json::to_vec(value),
237 Self::AlignmentRenderSpan(value) => serde_json::to_vec(value),
238 Self::AlignmentRenderRefusal(value) => serde_json::to_vec(value),
239 Self::AlignmentRenderTruncated(value) => serde_json::to_vec(value),
240 Self::HorizontalAlignment(value) => serde_json::to_vec(value),
241 Self::HorizontalAlignmentWarning(value) => serde_json::to_vec(value),
242 Self::PipeCollection(value) => serde_json::to_vec(value),
243 Self::PipeFeature(value) => serde_json::to_vec(value),
244 Self::PipePreflightRefusal(value) => serde_json::to_vec(value),
245 Self::PipeNetwork(value) => serde_json::to_vec(value),
246 Self::PipeRefusal(value) => serde_json::to_vec(value),
247 }
248 }
249}
250
251#[derive(Clone, Debug, Serialize)]
255pub struct LandXmlStreamMetadata {
256 pub terrain: LandXmlTinDocument,
257 pub plan: LandXmlPlanDocument,
258 pub alignments: LandXmlAlignmentDocument,
259 pub alignment_render: LandXmlAlignmentRenderData,
260}
261
262#[derive(Clone, Debug, Serialize)]
265pub struct LandXmlStreamSummary {
266 pub header: LandXmlStreamHeader,
267 pub surfaces_drained: usize,
268 pub renderable_surfaces: usize,
269 pub preserved_surfaces: usize,
270 pub plan_cogo_points: usize,
271 pub plan_parcels: usize,
272 pub horizontal_alignments: usize,
273 pub pipe_networks: usize,
276 pub pipe_structures: usize,
277 pub pipes: usize,
278 pub pipe_refusals: usize,
279 pub metadata: LandXmlStreamMetadata,
280}