1#![expect(
2 clippy::print_stdout,
3 reason = "the example intentionally displays the map data it reads"
4)]
5#![expect(
6 clippy::unwrap_used,
7 reason = "the example input is expected to contain nonempty objects and known symbols"
8)]
9#![expect(
10 clippy::expect_used,
11 reason = "the example input is expected to give the named symbol its documented type"
12)]
13
14use std::{cell::RefCell, rc::Weak};
15
16use geo_types::{Coord, LineString};
17#[cfg(feature = "geo_ref")]
18use omap::geo_referencing::GeoRef;
19#[cfg(feature = "geo_ref")]
20use omap::objects::MapObject;
21use omap::{
22 Code, Error, Omap,
23 colors::Color,
24 objects::{LineObject, TextGeometry, TextObject},
25 symbols::{TextSymbol, WeakLinePathSymbol},
26};
27
28fn main() -> Result<(), Error> {
29 let mut map = Omap::from_path("./example_data/from_path.omap")?;
30
31 #[cfg(feature = "geo_ref")]
32 {
33 let old_transform = map.geo_referencing.get_transform();
35
36 let mut mean_pos = Coord::zero();
37 let mut num_coords = 0;
38 for obj in map.parts.iter().flat_map(|part| part.iter_all_objects()) {
39 match obj {
40 MapObject::Point(object) => {
41 mean_pos = mean_pos + object.get_geometry().0;
42 num_coords += 1;
43 }
44 MapObject::Line(object) => {
45 let geometry = object.get_geometry(0.1)?;
46 mean_pos =
47 mean_pos + geometry.0.iter().copied().reduce(|sum, c| sum + c).unwrap();
48 num_coords += geometry.0.len();
49 }
50 MapObject::Area(object) => {
51 let geometry = object.get_geometry(0.1)?;
52 mean_pos = mean_pos
53 + geometry
54 .exterior()
55 .0
56 .iter()
57 .copied()
58 .reduce(|sum, c| sum + c)
59 .unwrap();
60 num_coords += geometry.exterior().0.len();
61 }
62 MapObject::Text(object) => {
63 match object.get_geometry() {
64 TextGeometry::SingleAnchor(coord) => mean_pos = mean_pos + *coord,
65 TextGeometry::WrapBox(wrap_box) => mean_pos = mean_pos + wrap_box.anchor,
66 }
67 num_coords += 1;
68 }
69 }
70 }
71 mean_pos = mean_pos / num_coords as f64;
72
73 let mean_proj_pos = old_transform.to_projected(mean_pos);
75
76 let new_gr = GeoRef::initialize(
78 mean_proj_pos,
79 map.geo_referencing.crs_type,
80 2_469.,
81 map.geo_referencing.scale_denominator,
82 )
83 .unwrap();
84
85 map.geo_referencing = new_gr;
87
88 let new_transform = map.geo_referencing.get_transform();
90
91 map.apply_affine_between(&old_transform, &new_transform)
97 .unwrap();
98 };
99
100 println!("Map colors in order:");
101 for color in map.colors.iter() {
102 match color {
103 Color::SpotColor(ref_cell) => {
104 let b = ref_cell.try_borrow().unwrap();
105 println!("{} with spot name {}", b.color_name, b.spotcolor_name);
106 }
107 Color::MixedColor(ref_cell) => {
108 println!("{}", ref_cell.try_borrow().unwrap().color_name);
109 }
110 }
111 }
112
113 let erosion_gully = map
114 .symbols
115 .get_symbol_by_code(Code::new(107, 0, 0))
116 .unwrap()
117 .downgrade();
118
119 let mut ls = LineObject::new(
120 WeakLinePathSymbol::try_from(erosion_gully).unwrap(),
121 LineString::new(vec![Coord { x: -60., y: -50. }, Coord { x: 60., y: -50. }]),
123 );
124 ls.tags.insert("Some Key".to_owned(), "My value".to_owned());
125
126 map.parts.0[0].add_object(ls);
127
128 let weak_symbol = map
129 .symbols
130 .get_symbol_by_name("Contour value")
131 .unwrap()
132 .downgrade();
133
134 let ts = TextObject::new(
135 Weak::<RefCell<TextSymbol>>::try_from(weak_symbol)
136 .expect("The symbol type of Contour value is not Text"),
137 TextGeometry::SingleAnchor(Coord { x: 0., y: 0. }),
138 "This is the middle of the map".to_owned(),
139 );
140 map.parts.0[0].add_object(ts);
141
142 map.write_to_file("./from_path_out.omap")
143}