ifc_lite_landxml/alignment/numeric/
render.rs1use super::{
8 diagnostic, geometry::evaluate_segment, geometry::validate_segment, LandXmlNumericDiagnostic,
9};
10use crate::{
11 alignment::{LandXmlAlignmentPrimitive, LandXmlAlignmentSegment, LandXmlPlanPoint},
12 LandXmlSourceId,
13};
14
15#[derive(Clone, Debug, serde::Deserialize, PartialEq, serde::Serialize)]
18pub struct LandXmlAlignmentRenderSpan {
19 pub source_id: LandXmlSourceId,
20 pub points: Vec<LandXmlPlanPoint>,
21}
22
23impl LandXmlAlignmentSegment {
24 pub fn render_span(
28 &self,
29 point_count: usize,
30 ) -> Result<Option<LandXmlAlignmentRenderSpan>, LandXmlNumericDiagnostic> {
31 match &self.primitive {
32 LandXmlAlignmentPrimitive::Curve(_) | LandXmlAlignmentPrimitive::Spiral(_) => {}
33 LandXmlAlignmentPrimitive::Line(_)
34 | LandXmlAlignmentPrimitive::IrregularLine(_)
35 | LandXmlAlignmentPrimitive::UnsupportedSpiral(_) => return Ok(None),
36 }
37 if point_count < 2 {
38 return Err(diagnostic(
39 &self.source_id,
40 "LXMLA231",
41 "render sampling requires at least two points",
42 ));
43 }
44 let length = validate_segment(self)?;
45 let mut points = Vec::with_capacity(point_count);
46 for index in 0..point_count {
47 let distance = length * index as f64 / (point_count - 1) as f64;
48 points.push(evaluate_segment(self, distance)?.0);
49 }
50 Ok(Some(LandXmlAlignmentRenderSpan {
51 source_id: self.source_id.clone(),
52 points,
53 }))
54 }
55}