shape_contour/
contours.rs1#![allow(unused)]
13#![allow(non_snake_case)]
16#![allow(non_camel_case_types)]
17#![allow(non_upper_case_globals)]
18
19mod cshapefil;
20use cshapefil::*;
21
22use std::error::Error;
23use std::collections::BTreeMap;
24
25pub use shapelib::shape; pub fn get_min_max(points: &Vec<shape::Pt2d>) -> Vec<shape::Pt2d> {
29 let mut r: Vec<shape::Pt2d> = (0..2).into_iter().map(|_| {
30 shape::Pt2d{x: points[0].x, y: points[0].y} }).collect();
31 for p in points {
32 if r[0].x > p.x { r[0].x = p.x };
33 if r[0].y > p.y { r[0].y = p.y };
34 if r[1].x < p.x { r[1].x = p.x };
35 if r[1].y < p.y { r[1].y = p.y };
36 }
37 r
38}
39
40pub fn get_mm_of_contours(contours: &shape::Contours2d) -> Vec<shape::Pt2d> {
42 let mut r = Vec::<shape::Pt2d>::with_capacity(2);
43 for (i, contour) in contours.iter().enumerate() {
44 let mut q = get_min_max(&contour);
45 if i == 0 {
46 for p in q { r.push(p); } } else {
48 for p in &r { q.push(shape::Pt2d{x: p.x, y: p.y}); } for (j, p) in get_min_max(&q).into_iter().enumerate() {
50 r[j] = p; }
52 }
53 }
54 r
55}
56
57#[derive(Debug)]
59pub struct Pt {
60 pub x: i32,
62 pub y: i32
64}
65
66pub type Contour2 = Vec<Pt>;
68
69pub type Contours2 = Vec<Contour2>;
71
72pub type MapContours = BTreeMap<i32, Contours2>;
74
75#[derive(Debug)]
77pub struct GrpContoursInf {
78 pub scale: f64,
80 pub offset: shape::Pt2d,
82 pub mm: Vec<shape::Pt2d>,
84 pub grp_contours: Vec<i32>,
86 pub grp_scaled_contours: MapContours,
88 pub sci: shape::ShpContoursInf
90}
91
92impl GrpContoursInf {
94 pub fn new(sci: shape::ShpContoursInf) ->
96 Result<GrpContoursInf, Box<dyn Error>> {
97 Ok(GrpContoursInf{
98 scale: 0.0,
99 offset: shape::Pt2d{x: 0.0, y: 0.0},
100 mm: (0..2).into_iter().map(|_| shape::Pt2d{x: 0.0, y: 0.0}).collect(),
101 grp_contours: vec![],
102 grp_scaled_contours: vec![].into_iter().collect(),
103 sci: sci})
104 }
105
106 pub fn get_grp_contours(&mut self, scale: f64, w_pref: i32, w_city: i32,
108 ignore: bool) -> Result<(), Box<dyn Error>> {
109 for si in 0..self.sci.shp.len() as i32 {
110 let flds = &self.sci.rec[&si];
111 let (pref, city) = match shape::get_pref_city(flds[0].as_str()) {
112 Err(e) => { if !ignore { println!("{} at {}\x07", e, si) }; (0, 0) },
113 Ok(r) => r
114 };
115if w_pref != 0 && pref != w_pref { continue; }
120 if w_city != 0 && city != w_city { continue; }
121 let shp_k = &self.sci.shp[&si];
122 let mut mmc = get_mm_of_contours(shp_k);
123 if self.grp_contours.len() == 0 {
124 self.mm.clear();
126 for p in mmc { self.mm.push(p); } } else {
128 for p in &self.mm { mmc.push(shape::Pt2d{x: p.x, y: p.y}); } for (j, p) in get_min_max(&mmc).into_iter().enumerate() {
130 self.mm[j] = p; }
132 }
133 self.grp_contours.push(si);
134 }
135 let range = shape::Pt2d{
136 x: self.mm[1].x - self.mm[0].x, y: self.mm[1].y - self.mm[0].y};
137 self.offset = shape::Pt2d{x: self.mm[0].x, y: self.mm[0].y};
138 let xscale = (self.sci.minmax[1][0] - self.sci.minmax[0][0]) / range.x;
139 let yscale = (self.sci.minmax[1][1] - self.sci.minmax[0][1]) / range.y;
140 self.scale = scale * (if xscale < yscale { xscale } else { yscale });
141Ok(())
157 }
158
159 pub fn get_scaled_contours(&mut self, si: i32, ofs: &shape::Pt2d) ->
161 Result<i32, Box<dyn Error>> {
162 let contours = self.grp_scaled_contours.entry(si).or_insert_with(|| {
163 let mut cts = Vec::<Contour2>::with_capacity(self.sci.shp[&si].len());
164 for pts in &self.sci.shp[&si] {
165 let mut contour = Vec::<Pt>::with_capacity(pts.len());
166 for p in pts {
167 contour.push(Pt{ x: ((ofs.x + p.x) * self.scale) as i32,
169 y: ((ofs.y + p.y) * self.scale) as i32});
170 }
171 cts.push(contour);
172 }
173 cts
174 });
175 Ok(contours.len() as i32)
176 }
177
178 pub fn whole_scaled(&mut self) -> Result<i32, Box<dyn Error>> {
180 let mut total = 0i32;
181 let offset = shape::Pt2d{x: 0.0, y: 0.0};
182 for i in 0..self.grp_contours.len() { total += self.get_scaled_contours(self.grp_contours[i], &offset)?;
184 }
185 Ok(total)
186 }
187}