mirror of
https://github.com/valmojr/armatak.git
synced 2026-08-18 16:02:58 +00:00
318 lines
7.7 KiB
Rust
318 lines
7.7 KiB
Rust
use arma_rs::{FromArma, FromArmaError};
|
|
|
|
#[derive(Clone)]
|
|
struct DrawPoint {
|
|
lat: f64,
|
|
lon: f64,
|
|
hae: f32,
|
|
}
|
|
|
|
pub struct DrawEllipsePayload {
|
|
pub uuid: String,
|
|
pub cot_type: String,
|
|
pub center_lat: f64,
|
|
pub center_lon: f64,
|
|
pub center_hae: f32,
|
|
pub major: f64,
|
|
pub minor: f64,
|
|
pub angle: f32,
|
|
pub callsign: String,
|
|
pub stale_seconds: i64,
|
|
pub stroke_color: i32,
|
|
pub fill_color: i32,
|
|
pub stroke_weight: f64,
|
|
pub milsym: String,
|
|
}
|
|
|
|
pub struct DrawLinksPayload {
|
|
pub uuid: String,
|
|
pub cot_type: String,
|
|
pub center_lat: f64,
|
|
pub center_lon: f64,
|
|
pub center_hae: f32,
|
|
pub points: String,
|
|
pub callsign: String,
|
|
pub stale_seconds: i64,
|
|
pub stroke_color: i32,
|
|
pub fill_color: i32,
|
|
pub stroke_weight: f64,
|
|
pub stroke_style: String,
|
|
pub closed: bool,
|
|
pub milsym: String,
|
|
}
|
|
|
|
impl FromArma for DrawEllipsePayload {
|
|
fn from_arma(data: String) -> Result<Self, FromArmaError> {
|
|
let (
|
|
uuid,
|
|
cot_type,
|
|
center_lat,
|
|
center_lon,
|
|
center_hae,
|
|
major,
|
|
minor,
|
|
angle,
|
|
callsign,
|
|
stale_seconds,
|
|
stroke_color,
|
|
fill_color,
|
|
stroke_weight,
|
|
milsym,
|
|
) = <(
|
|
String,
|
|
String,
|
|
f64,
|
|
f64,
|
|
f32,
|
|
f64,
|
|
f64,
|
|
f32,
|
|
String,
|
|
i64,
|
|
i32,
|
|
i32,
|
|
f64,
|
|
String,
|
|
)>::from_arma(data)?;
|
|
|
|
Ok(Self {
|
|
uuid,
|
|
cot_type,
|
|
center_lat,
|
|
center_lon,
|
|
center_hae,
|
|
major,
|
|
minor,
|
|
angle,
|
|
callsign,
|
|
stale_seconds,
|
|
stroke_color,
|
|
fill_color,
|
|
stroke_weight,
|
|
milsym,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl FromArma for DrawLinksPayload {
|
|
fn from_arma(data: String) -> Result<Self, FromArmaError> {
|
|
let (
|
|
uuid,
|
|
cot_type,
|
|
center_lat,
|
|
center_lon,
|
|
center_hae,
|
|
points,
|
|
callsign,
|
|
stale_seconds,
|
|
stroke_color,
|
|
fill_color,
|
|
stroke_weight,
|
|
stroke_style,
|
|
closed,
|
|
milsym,
|
|
) = <(
|
|
String,
|
|
String,
|
|
f64,
|
|
f64,
|
|
f32,
|
|
String,
|
|
String,
|
|
i64,
|
|
i32,
|
|
i32,
|
|
f64,
|
|
String,
|
|
bool,
|
|
String,
|
|
)>::from_arma(data)?;
|
|
|
|
Ok(Self {
|
|
uuid,
|
|
cot_type,
|
|
center_lat,
|
|
center_lon,
|
|
center_hae,
|
|
points,
|
|
callsign,
|
|
stale_seconds,
|
|
stroke_color,
|
|
fill_color,
|
|
stroke_weight,
|
|
stroke_style,
|
|
closed,
|
|
milsym,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl DrawEllipsePayload {
|
|
pub fn to_xml(&self, now: &str, stale: &str) -> String {
|
|
shape_event(
|
|
&self.uuid,
|
|
&self.cot_type,
|
|
self.center_lat,
|
|
self.center_lon,
|
|
self.center_hae,
|
|
now,
|
|
stale,
|
|
&self.callsign,
|
|
&ellipse_shape_detail(
|
|
&self.uuid,
|
|
self.major,
|
|
self.minor,
|
|
self.angle,
|
|
self.stroke_color,
|
|
self.fill_color,
|
|
self.stroke_weight,
|
|
),
|
|
self.stroke_color,
|
|
self.fill_color,
|
|
self.stroke_weight,
|
|
"solid",
|
|
&self.milsym,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl DrawLinksPayload {
|
|
pub fn to_xml(&self, now: &str, stale: &str) -> String {
|
|
let points = parse_points(&self.points);
|
|
let shape_detail = links_detail(&points, self.closed);
|
|
|
|
shape_event(
|
|
&self.uuid,
|
|
&self.cot_type,
|
|
self.center_lat,
|
|
self.center_lon,
|
|
self.center_hae,
|
|
now,
|
|
stale,
|
|
&self.callsign,
|
|
&shape_detail,
|
|
self.stroke_color,
|
|
self.fill_color,
|
|
self.stroke_weight,
|
|
&self.stroke_style,
|
|
&self.milsym,
|
|
)
|
|
}
|
|
}
|
|
|
|
fn shape_event(
|
|
uid: &str,
|
|
cot_type: &str,
|
|
lat: f64,
|
|
lon: f64,
|
|
hae: f32,
|
|
now: &str,
|
|
stale: &str,
|
|
callsign: &str,
|
|
shape_detail: &str,
|
|
stroke_color: i32,
|
|
fill_color: i32,
|
|
stroke_weight: f64,
|
|
stroke_style: &str,
|
|
milsym: &str,
|
|
) -> String {
|
|
let milsym_detail = if milsym.trim().is_empty() {
|
|
String::new()
|
|
} else {
|
|
format!(r#"<__milsym id="{}" />"#, escape_attr(milsym))
|
|
};
|
|
|
|
format!(
|
|
r#"<?xml version="1.0" encoding="UTF-8" ?><event version="2.0" uid="{uid}" type="{cot_type}" time="{now}" start="{now}" stale="{stale}" how="h-e" access="Undefined"><point lat="{lat}" lon="{lon}" hae="{hae}" ce="10.9" le="9999999.0" /><detail>{shape_detail}<__shapeExtras cpvis="true" editable="true" /><contact callsign="{callsign}" /><remarks /><archive /><labels_on value="true" /><strokeColor value="{stroke_color}" /><strokeWeight value="{stroke_weight}" /><strokeStyle value="{stroke_style}" /><fillColor value="{fill_color}" /><precisionlocation altsrc="GPS" geopointsrc="GPS" />{milsym_detail}</detail></event>"#,
|
|
uid = escape_attr(uid),
|
|
cot_type = escape_attr(cot_type),
|
|
now = now,
|
|
stale = stale,
|
|
lat = lat,
|
|
lon = lon,
|
|
hae = hae,
|
|
shape_detail = shape_detail,
|
|
callsign = escape_attr(callsign),
|
|
stroke_color = stroke_color,
|
|
stroke_weight = stroke_weight,
|
|
stroke_style = escape_attr(stroke_style),
|
|
fill_color = fill_color,
|
|
milsym_detail = milsym_detail
|
|
)
|
|
}
|
|
|
|
fn ellipse_shape_detail(
|
|
uid: &str,
|
|
major: f64,
|
|
minor: f64,
|
|
angle: f32,
|
|
stroke_color: i32,
|
|
fill_color: i32,
|
|
stroke_weight: f64,
|
|
) -> String {
|
|
format!(
|
|
r#"<shape><ellipse major="{major}" minor="{minor}" angle="{angle}" /><link uid="{style_uid}" type="b-x-KmlStyle" relation="p-c"><Style><LineStyle><color>{stroke_hex}</color><width>{stroke_weight}</width></LineStyle><PolyStyle><color>{fill_hex}</color></PolyStyle></Style></link></shape>"#,
|
|
major = major,
|
|
minor = minor,
|
|
angle = angle,
|
|
style_uid = escape_attr(&format!("{}.Style", uid)),
|
|
stroke_hex = argb_hex(stroke_color),
|
|
stroke_weight = stroke_weight,
|
|
fill_hex = argb_hex(fill_color)
|
|
)
|
|
}
|
|
|
|
fn links_detail(points: &[DrawPoint], closed: bool) -> String {
|
|
let mut detail = String::new();
|
|
|
|
for point in points {
|
|
detail.push_str(&link_detail(point));
|
|
}
|
|
|
|
if closed {
|
|
if let Some(first) = points.first() {
|
|
detail.push_str(&link_detail(first));
|
|
}
|
|
}
|
|
|
|
detail
|
|
}
|
|
|
|
fn link_detail(point: &DrawPoint) -> String {
|
|
format!(
|
|
r#"<link point="{lat},{lon},{hae}" />"#,
|
|
lat = point.lat,
|
|
lon = point.lon,
|
|
hae = point.hae
|
|
)
|
|
}
|
|
|
|
fn parse_points(raw: &str) -> Vec<DrawPoint> {
|
|
raw.split(';')
|
|
.filter_map(|entry| {
|
|
let parts: Vec<_> = entry.split(',').collect();
|
|
if parts.len() != 3 {
|
|
return None;
|
|
}
|
|
|
|
Some(DrawPoint {
|
|
lat: parts[0].parse().ok()?,
|
|
lon: parts[1].parse().ok()?,
|
|
hae: parts[2].parse().ok()?,
|
|
})
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn argb_hex(color: i32) -> String {
|
|
format!("{:08x}", color as u32)
|
|
}
|
|
|
|
fn escape_attr(value: &str) -> String {
|
|
value
|
|
.replace('&', "&")
|
|
.replace('"', """)
|
|
.replace('<', "<")
|
|
.replace('>', ">")
|
|
}
|