1use serde::{Deserialize, Serialize};
2use serde_json::{json, Error, Value};
3use std::collections::HashMap;
4
5const DEFAULT_CRS_BASE_URL: &str = "https://www.opengis.net/def/crs";
6
7#[derive(Clone)]
8pub enum SortingStrategy {
9 Random,
10 Lexicographical,
11 Morton, Hilbert, }
14
15#[derive(Serialize, Deserialize, Debug, Clone)]
16pub struct CityJSON {
17 #[serde(rename = "type")]
18 pub thetype: String,
19 pub version: String,
20 pub transform: Transform,
21 #[serde(rename = "CityObjects")]
22 pub city_objects: HashMap<String, CityObject>,
23 pub vertices: Vec<Vec<i64>>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub metadata: Option<Metadata>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub appearance: Option<Appearance>,
28 #[serde(rename = "geometry-templates")]
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub geometry_templates: Option<GeometryTemplates>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub extensions: Option<Value>,
33 #[serde(flatten)]
34 pub other: serde_json::Value,
35 #[serde(skip)]
36 sorted_ids: Vec<String>,
37 #[serde(skip)]
38 transform_correction: Option<Transform>,
39}
40impl CityJSON {
41 pub fn new() -> Self {
43 let co: HashMap<String, CityObject> = HashMap::new();
44 let v: Vec<Vec<i64>> = Vec::new();
45 let tr = Transform::new();
46 CityJSON {
47 thetype: "CityJSON".to_string(),
48 version: "2.0".to_string(),
49 transform: tr,
50 city_objects: co,
51 vertices: v,
52 metadata: None,
53 appearance: None,
54 geometry_templates: None,
55 extensions: None,
56 other: json!(null),
57 sorted_ids: vec![],
58 transform_correction: None,
59 }
60 }
61 pub fn from_str(s: &str) -> Result<Self, Error> {
63 let mut cjj: CityJSON = serde_json::from_str(s)?;
64 for (key, co) in &cjj.city_objects {
66 if co.is_toplevel() {
67 cjj.sorted_ids.push(key.clone());
68 }
69 }
70 Ok(cjj)
71 }
72
73 pub fn get_metadata(&self) -> Self {
75 let co: HashMap<String, CityObject> = HashMap::new();
76 let v: Vec<Vec<i64>> = Vec::new();
77 let mut cj0 = CityJSON {
78 thetype: self.thetype.clone(),
79 version: self.version.clone(),
80 transform: self.transform.clone(),
81 metadata: self.metadata.clone(),
82 city_objects: co,
83 vertices: v,
84 appearance: None,
85 geometry_templates: self.geometry_templates.clone(),
86 other: self.other.clone(),
87 extensions: self.extensions.clone(),
88 sorted_ids: vec![],
89 transform_correction: None,
90 };
91 match &self.geometry_templates {
94 Some(x) => {
95 let mut gts2: GeometryTemplates = x.clone();
96 let mut m_oldnew: HashMap<usize, usize> = HashMap::new();
97 let mut t_oldnew: HashMap<usize, usize> = HashMap::new();
98 let mut t_v_oldnew: HashMap<usize, usize> = HashMap::new();
99 for g in &mut gts2.templates {
100 g.update_material(&mut m_oldnew);
101 g.update_texture(&mut t_oldnew, &mut t_v_oldnew, 0);
102 }
103 if self.appearance.is_some() {
105 let a = self.appearance.as_ref().unwrap();
106 let mut acjf: Appearance = Appearance::new();
107 acjf.default_theme_material = a.default_theme_material.clone();
108 acjf.default_theme_texture = a.default_theme_texture.clone();
109 if a.materials.is_some() {
110 let am = a.materials.as_ref().unwrap();
111 let mut mats2: Vec<Value> = Vec::new();
112 mats2.resize(m_oldnew.len(), json!(null));
113 for (old, new) in &m_oldnew {
114 mats2[*new] = am[*old].clone();
115 }
116 acjf.materials = Some(mats2);
117 }
118 if a.textures.is_some() {
119 let at = a.textures.as_ref().unwrap();
120 let mut texs2: Vec<Value> = Vec::new();
121 texs2.resize(t_oldnew.len(), json!(null));
122 for (old, new) in &t_oldnew {
123 texs2[*new] = at[*old].clone();
124 }
125 acjf.textures = Some(texs2);
126 }
127 if a.vertices_texture.is_some() {
128 let atv = a.vertices_texture.as_ref().unwrap();
129 let mut t_new_vertices: Vec<Vec<f64>> = Vec::new();
130 t_new_vertices.resize(t_v_oldnew.len(), vec![]);
131 for (old, new) in &t_v_oldnew {
132 t_new_vertices[*new] = atv[*old].clone();
133 }
134 acjf.vertices_texture = Some(t_new_vertices);
135 }
136 cj0.appearance = Some(acjf);
137 }
138 }
139 None => (),
140 }
141 cj0
142 }
143 pub fn get_cjfeature(&self, i: usize) -> Option<CityJSONFeature> {
146 let i2 = self.sorted_ids.get(i);
147 if i2.is_none() {
148 return None;
149 }
150 let obj = self.city_objects.get(i2.unwrap());
151 if obj.is_none() {
152 return None;
153 }
154 let co = obj.unwrap();
155 let mut cjf = CityJSONFeature::new();
157 let mut co2: CityObject = co.clone();
158 let mut g_vi_oldnew: HashMap<usize, usize> = HashMap::new();
159 let mut m_oldnew: HashMap<usize, usize> = HashMap::new();
160 let mut t_oldnew: HashMap<usize, usize> = HashMap::new();
161 let mut t_v_oldnew: HashMap<usize, usize> = HashMap::new();
162 match &mut co2.geometry {
163 Some(x) => {
164 for g in x.iter_mut() {
165 g.update_geometry_boundaries(&mut g_vi_oldnew);
166 g.update_material(&mut m_oldnew);
167 g.update_texture(&mut t_oldnew, &mut t_v_oldnew, 0);
168 }
169 }
170 None => (),
171 }
172 cjf.add_co(self.sorted_ids[i].clone(), co2);
173 cjf.id = self.sorted_ids[i].to_string();
174 for childkey in co.get_children_keys() {
177 let coc = self.city_objects.get(&childkey).unwrap();
178 let mut coc2: CityObject = coc.clone();
179 match &mut coc2.geometry {
180 Some(x) => {
181 for g in x.iter_mut() {
182 g.update_geometry_boundaries(&mut g_vi_oldnew);
183 g.update_material(&mut m_oldnew);
184 g.update_texture(&mut t_oldnew, &mut t_v_oldnew, 0);
185 }
186 }
187 None => (),
188 }
189 cjf.add_co(childkey.clone(), coc2);
190 }
191 let allvertices = &self.vertices;
193 let mut g_new_vertices: Vec<Vec<i64>> = Vec::new();
194 g_new_vertices.resize(g_vi_oldnew.len(), vec![]);
195 for (old, new) in &g_vi_oldnew {
196 g_new_vertices[*new] = allvertices[*old].clone();
197 }
198 cjf.vertices = g_new_vertices;
199 if self.appearance.is_some() {
201 let a = self.appearance.as_ref().unwrap();
202 let mut acjf: Appearance = Appearance::new();
203 acjf.default_theme_material = a.default_theme_material.clone();
204 acjf.default_theme_texture = a.default_theme_texture.clone();
205 if a.materials.is_some() {
206 let am = a.materials.as_ref().unwrap();
207 let mut mats2: Vec<Value> = Vec::new();
208 mats2.resize(m_oldnew.len(), json!(null));
209 for (old, new) in &m_oldnew {
210 mats2[*new] = am[*old].clone();
211 }
212 acjf.materials = Some(mats2);
213 }
214 if a.textures.is_some() {
215 let at = a.textures.as_ref().unwrap();
216 let mut texs2: Vec<Value> = Vec::new();
217 texs2.resize(t_oldnew.len(), json!(null));
218 for (old, new) in &t_oldnew {
219 texs2[*new] = at[*old].clone();
220 }
221 acjf.textures = Some(texs2);
222 }
223 if a.vertices_texture.is_some() {
224 let atv = a.vertices_texture.as_ref().unwrap();
225 let mut t_new_vertices: Vec<Vec<f64>> = Vec::new();
226 t_new_vertices.resize(t_v_oldnew.len(), vec![]);
227 for (old, new) in &t_v_oldnew {
228 t_new_vertices[*new] = atv[*old].clone();
229 }
230 acjf.vertices_texture = Some(t_new_vertices);
231 }
232 cjf.appearance = Some(acjf);
233 }
234 Some(cjf)
235 }
236 pub fn add_transform_correction(&mut self, t: Transform) {
239 self.transform_correction = Some(t);
240 }
241 pub fn add_cjfeature(&mut self, cjf: &mut CityJSONFeature) {
242 let mut m_oldnew: HashMap<usize, usize> = HashMap::new();
243 let mut t_oldnew: HashMap<usize, usize> = HashMap::new();
244 let mut t_v_oldnew: HashMap<usize, usize> = HashMap::new();
245 let g_offset = self.vertices.len();
246 let mut t_offset = 0;
247 if let Some(cjf_app) = &cjf.appearance {
248 if let Some(cjf_mat) = &cjf_app.materials {
249 for (i, m) in cjf_mat.iter().enumerate() {
250 m_oldnew.insert(i, self.add_material(m.clone()));
251 }
252 }
253 if let Some(cjf_tex) = &cjf_app.textures {
254 for (i, m) in cjf_tex.iter().enumerate() {
255 t_oldnew.insert(i, self.add_texture(m.clone()));
256 }
257 }
258 if let Some(cjf_v_tex) = &cjf_app.vertices_texture {
259 t_offset = cjf_v_tex.len();
260 self.add_vertices_texture(cjf_v_tex.clone());
261 }
262 }
263
264 for (key, co) in &mut cjf.city_objects {
265 if let Some(ref mut geoms) = &mut co.geometry {
267 for g in geoms.iter_mut() {
268 g.offset_geometry_boundaries(g_offset);
270 g.update_material(&mut m_oldnew);
273 g.update_texture(&mut t_oldnew, &mut t_v_oldnew, t_offset);
275 }
276 }
277 self.add_co(key.to_string(), co.clone());
279 }
280 self.add_vertices(&mut cjf.vertices);
282 self.sorted_ids.push(cjf.id.clone());
284 }
285 pub fn remove_duplicate_vertices(&mut self) {
286 let mut h: HashMap<String, usize> = HashMap::new();
288 let mut newids: HashMap<usize, usize> = HashMap::new();
289 let mut newvertices: Vec<Vec<i64>> = Vec::new();
290 for (i, v) in self.vertices.iter().enumerate() {
291 let k = format!("{} {} {}", v[0], v[1], v[2]);
293 match h.get(&k) {
294 Some(x) => {
295 let _ = newids.insert(i, *x);
296 }
297 None => {
298 newids.insert(i, newvertices.len());
299 h.insert(k.clone(), newvertices.len());
300 newvertices.push(v.clone());
301 }
302 }
303 }
304 let cos = &mut self.city_objects;
306 for (_key, co) in cos.iter_mut() {
307 match &mut co.geometry {
308 Some(x) => {
309 for g in x.iter_mut() {
310 g.update_geometry_boundaries(&mut newids);
311 }
312 }
313 None => (),
314 }
315 }
316 self.vertices = newvertices;
318 }
319 pub fn update_geographicalextent(&mut self) {
320 if let Some(m) = &mut self.metadata {
321 if let Some(ref mut ge) = m.geographical_extent {
322 let mut mins: Vec<i64> = vec![i64::MAX, i64::MAX, i64::MAX];
323 let mut maxs: Vec<i64> = vec![i64::MIN, i64::MIN, i64::MIN];
324 for v in &self.vertices {
325 for i in 0..3 {
326 if v[i] < mins[i] {
327 mins[i] = v[i];
328 }
329 if v[i] > maxs[i] {
330 maxs[i] = v[i];
331 }
332 }
333 }
334 *ge = [
335 mins[0] as f64 * self.transform.scale[0] + self.transform.translate[0],
336 mins[1] as f64 * self.transform.scale[1] + self.transform.translate[1],
337 mins[2] as f64 * self.transform.scale[2] + self.transform.translate[2],
338 maxs[0] as f64 * self.transform.scale[0] + self.transform.translate[0],
339 maxs[1] as f64 * self.transform.scale[1] + self.transform.translate[1],
340 maxs[2] as f64 * self.transform.scale[2] + self.transform.translate[2],
341 ];
342 }
343 }
344 }
345 pub fn update_transform(&mut self) {
346 let mut newvertices: Vec<Vec<i64>> = Vec::new();
347 let mut mins: Vec<i64> = vec![i64::MAX, i64::MAX, i64::MAX];
348 for v in &self.vertices {
350 for i in 0..3 {
351 if v[i] < mins[i] {
352 mins[i] = v[i];
353 }
354 }
355 }
356 for v in &self.vertices {
358 let v: Vec<i64> = vec![v[0] - mins[0], v[1] - mins[1], v[2] - mins[2]];
359 newvertices.push(v);
360 }
361 self.vertices = newvertices;
363 let ttx = (mins[0] as f64 * self.transform.scale[0]) + self.transform.translate[0];
365 let tty = (mins[1] as f64 * self.transform.scale[1]) + self.transform.translate[1];
366 let ttz = (mins[2] as f64 * self.transform.scale[2]) + self.transform.translate[2];
367 self.transform.translate = vec![ttx, tty, ttz];
368 }
369 pub fn number_of_city_objects(&self) -> usize {
370 let mut total: usize = 0;
371 for (_key, co) in &self.city_objects {
372 if co.is_toplevel() {
373 total += 1;
374 }
375 }
376 total
377 }
378 pub fn sort_cjfeatures(&mut self, ss: SortingStrategy) {
381 self.sorted_ids.clear();
382 match ss {
383 SortingStrategy::Random => {
384 for (key, co) in &self.city_objects {
385 if co.is_toplevel() {
386 self.sorted_ids.push(key.clone());
387 }
388 }
389 }
390 SortingStrategy::Lexicographical => {
391 for (key, co) in &self.city_objects {
392 if co.is_toplevel() {
393 self.sorted_ids.push(key.clone());
394 }
395 }
396 self.sorted_ids.sort();
397 }
398 _ => todo!(),
399 }
400 }
401 fn add_co(&mut self, id: String, co: CityObject) {
402 self.city_objects.insert(id.clone(), co);
403 }
404 fn add_vertices(&mut self, vs: &mut Vec<Vec<i64>>) {
405 if self.transform_correction.is_none() {
406 self.vertices.append(vs);
407 } else {
408 let c = self.transform_correction.as_ref().unwrap();
410 for v in vs {
411 let cx: i64 = (((v[0] as f64 * c.scale[0]) + c.translate[0]
412 - self.transform.translate[0])
413 / self.transform.scale[0])
414 .round() as i64;
415 let cy: i64 = (((v[1] as f64 * c.scale[1]) + c.translate[1]
416 - self.transform.translate[1])
417 / self.transform.scale[1])
418 .round() as i64;
419 let cz: i64 = (((v[2] as f64 * c.scale[2]) + c.translate[2]
420 - self.transform.translate[2])
421 / self.transform.scale[2])
422 .round() as i64;
423 self.vertices.push(vec![cx, cy, cz]);
424 }
425 }
426 }
427 fn add_vertices_texture(&mut self, vs: Vec<Vec<f64>>) {
428 match &mut self.appearance {
429 Some(x) => x.add_vertices_texture(vs),
430 None => {
431 let mut a: Appearance = Appearance::new();
432 a.add_vertices_texture(vs);
433 self.appearance = Some(a);
434 }
435 };
436 }
437 fn add_material(&mut self, jm: Value) -> usize {
438 let re = match &mut self.appearance {
439 Some(x) => x.add_material(jm),
440 None => {
441 let mut a: Appearance = Appearance::new();
442 let re = a.add_material(jm);
443 self.appearance = Some(a);
444 re
445 }
446 };
447 re
448 }
449 fn add_texture(&mut self, jm: Value) -> usize {
450 let re = match &mut self.appearance {
451 Some(x) => x.add_texture(jm),
452 None => {
453 let mut a: Appearance = Appearance::new();
454 let re = a.add_texture(jm);
455 self.appearance = Some(a);
456 re
457 }
458 };
459 re
460 }
461}
462
463#[derive(Serialize, Deserialize, Debug, Clone)]
464pub struct CityJSONFeature {
465 #[serde(rename = "type")]
466 pub thetype: String,
467 pub id: String,
468 #[serde(rename = "CityObjects")]
469 pub city_objects: HashMap<String, CityObject>,
470 pub vertices: Vec<Vec<i64>>,
471 #[serde(skip_serializing_if = "Option::is_none")]
472 pub appearance: Option<Appearance>,
473}
474impl CityJSONFeature {
475 pub fn new() -> Self {
476 let co: HashMap<String, CityObject> = HashMap::new();
477 let v: Vec<Vec<i64>> = Vec::new();
478 CityJSONFeature {
479 thetype: "CityJSONFeature".to_string(),
480 id: "".to_string(),
481 city_objects: co,
482 vertices: v,
483 appearance: None,
484 }
485 }
486 pub fn from_str(s: &str) -> Result<Self, Error> {
487 let cjf: CityJSONFeature = serde_json::from_str(&s)?;
488 Ok(cjf)
489 }
490 pub fn add_co(&mut self, id: String, co: CityObject) {
491 self.city_objects.insert(id, co);
492 }
493 pub fn centroid(&self) -> Vec<f64> {
494 let mut totals: Vec<f64> = vec![0., 0., 0.];
495 for v in &self.vertices {
496 for i in 0..3 {
497 totals[i] += v[i] as f64;
498 }
499 }
500 for i in 0..3 {
501 totals[i] /= self.vertices.len() as f64;
502 }
503 return totals;
504 }
505}
506
507#[derive(Serialize, Deserialize, Debug, Clone)]
508pub struct CityObject {
509 #[serde(rename = "type")]
510 pub thetype: String,
511 #[serde(rename = "geographicalExtent")]
512 #[serde(skip_serializing_if = "Option::is_none")]
513 pub geographical_extent: Option<Vec<f64>>,
514 #[serde(skip_serializing_if = "Option::is_none")]
515 pub attributes: Option<Value>,
516 #[serde(skip_serializing_if = "Option::is_none")]
517 pub geometry: Option<Vec<Geometry>>,
518 #[serde(skip_serializing_if = "Option::is_none")]
519 pub children: Option<Vec<String>>,
520 #[serde(skip_serializing_if = "Option::is_none")]
521 pub parents: Option<Vec<String>>,
522 #[serde(flatten)]
523 other: serde_json::Value,
524}
525
526impl CityObject {
527 pub fn get_type(&self) -> String {
528 self.thetype.clone()
529 }
530 fn is_toplevel(&self) -> bool {
531 match &self.parents {
532 Some(x) => {
533 if x.is_empty() {
534 return true;
535 } else {
536 return false;
537 }
538 }
539 None => return true,
540 }
541 }
542 fn get_children_keys(&self) -> Vec<String> {
543 let mut re: Vec<String> = Vec::new();
544 match &self.children {
545 Some(x) => {
546 for each in x {
547 re.push(each.to_string());
548 }
549 }
550 None => (),
551 }
552 re
553 }
554}
555
556#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
557pub enum GeometryType {
558 MultiPoint,
559 MultiLineString,
560 MultiSurface,
561 CompositeSurface,
562 Solid,
563 MultiSolid,
564 CompositeSolid,
565 GeometryInstance,
566}
567
568#[derive(Serialize, Deserialize, Debug, Clone)]
569pub struct Geometry {
570 #[serde(rename = "type")]
571 pub thetype: GeometryType,
572 #[serde(skip_serializing_if = "Option::is_none")]
573 pub lod: Option<String>,
574 pub boundaries: Value,
575 #[serde(skip_serializing_if = "Option::is_none")]
576 pub semantics: Option<Value>,
577 #[serde(skip_serializing_if = "Option::is_none")]
578 pub material: Option<HashMap<String, Material>>,
579 #[serde(skip_serializing_if = "Option::is_none")]
580 pub texture: Option<HashMap<String, Texture>>,
581 #[serde(skip_serializing_if = "Option::is_none")]
582 pub template: Option<usize>,
583 #[serde(rename = "transformationMatrix")]
584 #[serde(skip_serializing_if = "Option::is_none")]
585 pub transformation_matrix: Option<Value>,
586}
587impl Geometry {
588 fn update_geometry_boundaries(&mut self, violdnew: &mut HashMap<usize, usize>) {
589 match self.thetype {
590 GeometryType::MultiPoint => {
591 let a: Vec<usize> = serde_json::from_value(self.boundaries.clone()).unwrap();
592 let mut a2 = a.clone();
593 for (i, x) in a.iter().enumerate() {
594 let kk = violdnew.get(&x);
595 if kk.is_none() {
596 let l = violdnew.len();
597 violdnew.insert(*x, l);
598 a2[i] = l;
599 } else {
600 let kk = kk.unwrap();
601 a2[i] = *kk;
602 }
603 }
604 self.boundaries = serde_json::to_value(&a2).unwrap();
605 }
606 GeometryType::MultiLineString => {
607 let a: Vec<Vec<usize>> = serde_json::from_value(self.boundaries.take()).unwrap();
608 let mut a2 = a.clone();
609 for (i, x) in a.iter().enumerate() {
610 for (j, y) in x.iter().enumerate() {
611 let kk = violdnew.get(&y);
613 if kk.is_none() {
614 let l = violdnew.len();
615 violdnew.insert(*y, l);
616 a2[i][j] = l;
617 } else {
618 let kk = kk.unwrap();
619 a2[i][j] = *kk;
620 }
621 }
622 }
623 self.boundaries = serde_json::to_value(&a2).unwrap();
624 }
625 GeometryType::MultiSurface | GeometryType::CompositeSurface => {
626 let a: Vec<Vec<Vec<usize>>> =
627 serde_json::from_value(self.boundaries.take()).unwrap();
628 let mut a2 = a.clone();
629 for (i, x) in a.iter().enumerate() {
630 for (j, y) in x.iter().enumerate() {
631 for (k, z) in y.iter().enumerate() {
632 let kk = violdnew.get(&z);
633 if kk.is_none() {
634 let l = violdnew.len();
635 violdnew.insert(*z, l);
636 a2[i][j][k] = l;
637 } else {
638 let kk = kk.unwrap();
639 a2[i][j][k] = *kk;
640 }
641 }
642 }
643 }
644 self.boundaries = serde_json::to_value(&a2).unwrap();
645 }
646 GeometryType::Solid => {
647 let a: Vec<Vec<Vec<Vec<usize>>>> =
648 serde_json::from_value(self.boundaries.take()).unwrap();
649 let mut a2 = a.clone();
650 for (i, x) in a.iter().enumerate() {
651 for (j, y) in x.iter().enumerate() {
652 for (k, z) in y.iter().enumerate() {
653 for (l, zz) in z.iter().enumerate() {
654 let kk = violdnew.get(&zz);
655 if kk.is_none() {
656 let l2 = violdnew.len();
657 violdnew.insert(*zz, l2);
658 a2[i][j][k][l] = l2;
659 } else {
660 let kk = kk.unwrap();
661 a2[i][j][k][l] = *kk;
662 }
663 }
664 }
665 }
666 }
667 self.boundaries = serde_json::to_value(&a2).unwrap();
668 }
669 GeometryType::MultiSolid | GeometryType::CompositeSolid => {
670 let a: Vec<Vec<Vec<Vec<Vec<usize>>>>> =
671 serde_json::from_value(self.boundaries.take()).unwrap();
672 let mut a2 = a.clone();
673 for (i, x) in a.iter().enumerate() {
674 for (j, y) in x.iter().enumerate() {
675 for (k, z) in y.iter().enumerate() {
676 for (l, zz) in z.iter().enumerate() {
677 for (m, zzz) in zz.iter().enumerate() {
678 let kk = violdnew.get(&zzz);
679 if kk.is_none() {
680 let l2 = violdnew.len();
681 violdnew.insert(*zzz, l2);
682 a2[i][j][k][l][m] = l2;
683 } else {
684 let kk = kk.unwrap();
685 a2[i][j][k][l][m] = *kk;
686 }
687 }
688 }
689 }
690 }
691 }
692 self.boundaries = serde_json::to_value(&a2).unwrap();
693 }
694 GeometryType::GeometryInstance => {
695 let a: Vec<usize> = serde_json::from_value(self.boundaries.clone()).unwrap();
696 let mut a2 = a.clone();
697 for (i, x) in a.iter().enumerate() {
698 let kk = violdnew.get(&x);
699 if kk.is_none() {
700 let l = violdnew.len();
701 violdnew.insert(*x, l);
702 a2[i] = l;
703 } else {
704 let kk = kk.unwrap();
705 a2[i] = *kk;
706 }
707 }
708 self.boundaries = serde_json::to_value(&a2).unwrap();
709 }
710 }
711 }
712
713 fn offset_geometry_boundaries(&mut self, offset: usize) {
714 match self.thetype {
715 GeometryType::MultiPoint => {
716 let a: Vec<usize> = serde_json::from_value(self.boundaries.clone()).unwrap();
717 let mut a2 = a.clone();
718 for (i, x) in a.iter().enumerate() {
719 a2[i] = *x + offset;
720 }
721 self.boundaries = serde_json::to_value(&a2).unwrap();
722 }
723 GeometryType::MultiLineString => {
724 let a: Vec<Vec<usize>> = serde_json::from_value(self.boundaries.take()).unwrap();
725 let mut a2 = a.clone();
726 for (i, x) in a.iter().enumerate() {
727 for (j, y) in x.iter().enumerate() {
728 a2[i][j] = *y + offset;
730 }
731 }
732 self.boundaries = serde_json::to_value(&a2).unwrap();
733 }
734 GeometryType::MultiSurface | GeometryType::CompositeSurface => {
735 let a: Vec<Vec<Vec<usize>>> =
736 serde_json::from_value(self.boundaries.take()).unwrap();
737 let mut a2 = a.clone();
738 for (i, x) in a.iter().enumerate() {
739 for (j, y) in x.iter().enumerate() {
740 for (k, z) in y.iter().enumerate() {
741 a2[i][j][k] = *z + offset;
742 }
743 }
744 }
745 self.boundaries = serde_json::to_value(&a2).unwrap();
746 }
747 GeometryType::Solid => {
748 let a: Vec<Vec<Vec<Vec<usize>>>> =
749 serde_json::from_value(self.boundaries.take()).unwrap();
750 let mut a2 = a.clone();
751 for (i, x) in a.iter().enumerate() {
752 for (j, y) in x.iter().enumerate() {
753 for (k, z) in y.iter().enumerate() {
754 for (l, zz) in z.iter().enumerate() {
755 a2[i][j][k][l] = *zz + offset;
756 }
757 }
758 }
759 }
760 self.boundaries = serde_json::to_value(&a2).unwrap();
761 }
762 GeometryType::MultiSolid | GeometryType::CompositeSolid => {
763 let a: Vec<Vec<Vec<Vec<Vec<usize>>>>> =
764 serde_json::from_value(self.boundaries.take()).unwrap();
765 let mut a2 = a.clone();
766 for (i, x) in a.iter().enumerate() {
767 for (j, y) in x.iter().enumerate() {
768 for (k, z) in y.iter().enumerate() {
769 for (l, zz) in z.iter().enumerate() {
770 for (m, zzz) in zz.iter().enumerate() {
771 a2[i][j][k][l][m] = *zzz + offset;
772 }
773 }
774 }
775 }
776 }
777 self.boundaries = serde_json::to_value(&a2).unwrap();
778 }
779 GeometryType::GeometryInstance => {
780 let a: Vec<usize> = serde_json::from_value(self.boundaries.clone()).unwrap();
781 let mut a2 = a.clone();
782 for (i, x) in a.iter().enumerate() {
783 a2[i] = *x + offset;
784 }
785 self.boundaries = serde_json::to_value(&a2).unwrap();
786 }
787 }
788 }
789
790 fn update_material(&mut self, m_oldnew: &mut HashMap<usize, usize>) {
791 match &mut self.material {
792 Some(x) => {
793 for (_key, mat) in &mut *x {
794 if mat.value.is_some() {
796 let thevalue: usize = mat.value.unwrap();
797 let r = m_oldnew.get(&thevalue);
798 if r.is_none() {
799 let l = m_oldnew.len();
800 m_oldnew.insert(thevalue, l);
801 mat.value = Some(l);
802 } else {
803 let r2 = r.unwrap();
804 mat.value = Some(*r2);
805 }
806 continue;
807 }
808 match self.thetype {
810 GeometryType::MultiPoint | GeometryType::MultiLineString => (),
811 GeometryType::MultiSurface | GeometryType::CompositeSurface => {
812 if mat.values.is_some() {
813 let a: Vec<Option<usize>> =
814 serde_json::from_value(mat.values.take().into()).unwrap();
815 let mut a2 = a.clone();
816 for (i, x) in a.iter().enumerate() {
817 if x.is_some() {
818 let y2 = m_oldnew.get(&x.unwrap());
819 if y2.is_none() {
820 let l = m_oldnew.len();
821 m_oldnew.insert(x.unwrap(), l);
822 a2[i] = Some(l);
823 } else {
824 let y2 = y2.unwrap();
825 a2[i] = Some(*y2);
826 }
827 }
828 }
829 mat.values = Some(serde_json::to_value(&a2).unwrap());
830 }
831 }
832 GeometryType::Solid => {
833 if mat.values.is_some() {
834 let a: Vec<Vec<Option<usize>>> =
835 serde_json::from_value(mat.values.take().into()).unwrap();
836 let mut a2 = a.clone();
837 for (i, x) in a.iter().enumerate() {
838 for (j, y) in x.iter().enumerate() {
839 if y.is_some() {
840 let y2 = m_oldnew.get(&y.unwrap());
841 if y2.is_none() {
842 let l = m_oldnew.len();
843 m_oldnew.insert(y.unwrap(), l);
844 a2[i][j] = Some(l);
845 } else {
846 let y2 = y2.unwrap();
847 a2[i][j] = Some(*y2);
848 }
849 }
850 }
851 }
852 mat.values = Some(serde_json::to_value(&a2).unwrap());
853 }
854 }
855 GeometryType::MultiSolid | GeometryType::CompositeSolid => {
856 if mat.values.is_some() {
857 let a: Vec<Vec<Vec<Option<usize>>>> =
858 serde_json::from_value(mat.values.take().into()).unwrap();
859 let mut a2 = a.clone();
860 for (i, x) in a.iter().enumerate() {
861 for (j, y) in x.iter().enumerate() {
862 for (k, z) in y.iter().enumerate() {
863 if z.is_some() {
864 let y2 = m_oldnew.get(&z.unwrap());
865 if y2.is_none() {
866 let l = m_oldnew.len();
867 m_oldnew.insert(z.unwrap(), l);
868 a2[i][j][k] = Some(l);
869 } else {
870 let y2 = y2.unwrap();
871 a2[i][j][k] = Some(*y2);
872 }
873 }
874 }
875 }
876 }
877 mat.values = Some(serde_json::to_value(&a2).unwrap());
878 }
879 }
880 GeometryType::GeometryInstance => todo!(),
881 }
882 }
883 self.material = Some(x.clone());
884 }
885 None => (),
886 }
887 }
888 fn update_texture(
889 &mut self,
890 t_oldnew: &mut HashMap<usize, usize>,
891 t_v_oldnew: &mut HashMap<usize, usize>,
892 offset: usize,
893 ) {
894 match &mut self.texture {
895 Some(x) => {
896 for (_key, tex) in &mut *x {
897 match self.thetype {
898 GeometryType::MultiSurface | GeometryType::CompositeSurface => {
899 let a: Vec<Vec<Vec<Option<usize>>>> =
900 serde_json::from_value(tex.values.take().into()).unwrap();
901 let mut a2 = a.clone();
902 for (i, x) in a.iter().enumerate() {
903 for (j, y) in x.iter().enumerate() {
904 for (k, z) in y.iter().enumerate() {
905 if z.is_some() {
906 let thevalue: usize = z.unwrap();
907 if k == 0 {
908 let y2 = t_oldnew.get(&thevalue);
909 if y2.is_none() {
910 let l = t_oldnew.len();
911 t_oldnew.insert(thevalue, l);
912 a2[i][j][k] = Some(l);
913 } else {
914 let y2 = y2.unwrap();
915 a2[i][j][k] = Some(*y2);
916 }
917 } else {
918 let y2 = t_v_oldnew.get(&thevalue);
919 if y2.is_none() {
920 let l = t_v_oldnew.len();
921 t_v_oldnew.insert(thevalue, l + offset);
922 a2[i][j][k] = Some(l);
923 } else {
924 let y2 = y2.unwrap();
925 a2[i][j][k] = Some(*y2);
926 }
927 }
928 }
929 }
930 }
931 }
932 tex.values = Some(serde_json::to_value(&a2).unwrap());
933 }
934 GeometryType::Solid => {
935 let a: Vec<Vec<Vec<Vec<Option<usize>>>>> =
936 serde_json::from_value(tex.values.take().into()).unwrap();
937 let mut a2 = a.clone();
938 for (i, x) in a.iter().enumerate() {
939 for (j, y) in x.iter().enumerate() {
940 for (k, z) in y.iter().enumerate() {
941 for (l, zz) in z.iter().enumerate() {
942 if zz.is_some() {
943 let thevalue: usize = zz.unwrap();
944 if l == 0 {
945 let y2 = t_oldnew.get(&thevalue);
946 if y2.is_none() {
947 let l2 = t_oldnew.len();
948 t_oldnew.insert(thevalue, l2);
949 a2[i][j][k][l] = Some(l2);
950 } else {
951 let y2 = y2.unwrap();
952 a2[i][j][k][l] = Some(*y2);
953 }
954 } else {
955 let y2 = t_v_oldnew.get(&thevalue);
956 if y2.is_none() {
957 let l2 = t_v_oldnew.len();
958 t_v_oldnew.insert(thevalue, l2 + offset);
959 a2[i][j][k][l] = Some(l2);
960 } else {
961 let y2 = y2.unwrap();
962 a2[i][j][k][l] = Some(*y2);
963 }
964 }
965 }
966 }
967 }
968 }
969 }
970 tex.values = Some(serde_json::to_value(&a2).unwrap());
971 }
972 _ => todo!(),
973 }
974 }
975 }
976 None => (),
977 }
978 }
979}
980
981#[derive(Serialize, Deserialize, Debug)]
982struct Vertex {
983 x: i64,
984 y: i64,
985 z: i64,
986}
987
988#[derive(Serialize, Deserialize, Debug, Clone)]
989pub struct Transform {
990 pub scale: Vec<f64>,
991 pub translate: Vec<f64>,
992}
993impl Transform {
994 fn new() -> Self {
995 Transform {
996 scale: vec![1.0, 1.0, 1.0],
997 translate: vec![0., 0., 0.],
998 }
999 }
1000}
1001
1002pub type GeographicalExtent = [f64; 6];
1003
1004#[derive(Serialize, Deserialize, Debug, Clone)]
1005pub struct Address {
1006 #[serde(rename = "thoroughfareNumber")]
1007 pub thoroughfare_number: i64,
1008 #[serde(rename = "thoroughfareName")]
1009 pub thoroughfare_name: String,
1010 pub locality: String,
1011 #[serde(rename = "postalCode")]
1012 pub postal_code: String,
1013 pub country: String,
1014}
1015
1016#[derive(Serialize, Deserialize, Debug, Clone)]
1017pub struct PointOfContact {
1018 #[serde(rename = "contactName")]
1019 pub contact_name: String,
1020 #[serde(rename = "contactType")]
1021 #[serde(skip_serializing_if = "Option::is_none")]
1022 pub contact_type: Option<String>,
1023 #[serde(rename = "role")]
1024 #[serde(skip_serializing_if = "Option::is_none")]
1025 pub role: Option<String>,
1026 #[serde(skip_serializing_if = "Option::is_none")]
1027 pub phone: Option<String>,
1028 #[serde(rename = "emailAddress")]
1029 pub email_address: String,
1030 #[serde(skip_serializing_if = "Option::is_none")]
1031 pub website: Option<String>,
1032 #[serde(skip_serializing_if = "Option::is_none")]
1033 pub address: Option<Address>,
1034}
1035
1036#[derive(Debug, Clone)]
1046pub struct ReferenceSystem {
1047 pub base_url: String,
1048 pub authority: String,
1049 pub version: String,
1050 pub code: String,
1051}
1052
1053impl ReferenceSystem {
1054 pub fn new(base_url: Option<String>, authority: String, version: String, code: String) -> Self {
1055 let base_url = base_url.unwrap_or(DEFAULT_CRS_BASE_URL.to_string());
1056 ReferenceSystem {
1057 base_url,
1058 authority,
1059 version,
1060 code,
1061 }
1062 }
1063
1064 pub fn to_url(&self) -> String {
1065 format!(
1066 "{}/{}/{}/{}",
1067 self.base_url, self.authority, self.version, self.code
1068 )
1069 }
1070
1071 pub fn from_url(url: &str) -> Result<Self, &'static str> {
1075 if !url.contains("//www.opengis.net/def/crs") {
1076 return Err("Invalid reference system URL");
1077 }
1078
1079 let i = url.find("crs").unwrap();
1080 let s = &url[i + 4..];
1081
1082 let parts: Vec<&str> = s.split("/").collect();
1083 if parts.len() != 3 {
1084 return Err("Invalid reference system URL");
1085 }
1086
1087 Ok(ReferenceSystem {
1088 base_url: url[..i + 3].to_string(),
1089 authority: parts[0].to_string(),
1090 version: parts[1].to_string(),
1091 code: parts[2].to_string(),
1092 })
1093 }
1094}
1095
1096impl Serialize for ReferenceSystem {
1097 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1098 where
1099 S: serde::Serializer,
1100 {
1101 self.to_url().serialize(serializer)
1102 }
1103}
1104
1105impl<'de> Deserialize<'de> for ReferenceSystem {
1106 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1107 where
1108 D: serde::Deserializer<'de>,
1109 {
1110 let url = String::deserialize(deserializer)?;
1111 ReferenceSystem::from_url(&url).map_err(serde::de::Error::custom)
1112 }
1113}
1114
1115#[derive(Serialize, Deserialize, Debug, Clone)]
1116pub struct Metadata {
1117 #[serde(rename = "geographicalExtent")]
1118 #[serde(skip_serializing_if = "Option::is_none")]
1119 pub geographical_extent: Option<GeographicalExtent>,
1120 #[serde(skip_serializing_if = "Option::is_none")]
1121 pub identifier: Option<String>,
1122 #[serde(rename = "pointOfContact")]
1123 #[serde(skip_serializing_if = "Option::is_none")]
1124 pub point_of_contact: Option<PointOfContact>,
1125 #[serde(rename = "referenceDate")]
1126 #[serde(skip_serializing_if = "Option::is_none")]
1127 pub reference_date: Option<String>,
1128 #[serde(rename = "referenceSystem")]
1129 #[serde(skip_serializing_if = "Option::is_none")]
1130 pub reference_system: Option<ReferenceSystem>,
1131 #[serde(skip_serializing_if = "Option::is_none")]
1132 pub title: Option<String>,
1133}
1134
1135#[derive(Serialize, Deserialize, Debug, Clone)]
1136pub struct GeometryTemplates {
1137 pub templates: Vec<Geometry>,
1138 #[serde(rename = "vertices-templates")]
1139 pub vertices_templates: Value,
1140}
1141
1142#[derive(Serialize, Deserialize, Debug, Clone)]
1143pub struct Material {
1144 #[serde(skip_serializing_if = "Option::is_none")]
1145 pub values: Option<Value>,
1146 #[serde(skip_serializing_if = "Option::is_none")]
1147 pub value: Option<usize>,
1148}
1149
1150#[derive(Serialize, Deserialize, Debug, Clone)]
1151pub struct Texture {
1152 #[serde(skip_serializing_if = "Option::is_none")]
1153 pub values: Option<Value>,
1154}
1155
1156#[derive(Serialize, Deserialize, Debug, Clone)]
1157pub struct Appearance {
1158 #[serde(skip_serializing_if = "Option::is_none")]
1159 pub materials: Option<Vec<Value>>,
1160 #[serde(skip_serializing_if = "Option::is_none")]
1161 pub textures: Option<Vec<Value>>,
1162 #[serde(rename = "vertices-texture")]
1163 #[serde(skip_serializing_if = "Option::is_none")]
1164 pub vertices_texture: Option<Vec<Vec<f64>>>,
1165 #[serde(rename = "default-theme-texture")]
1166 #[serde(skip_serializing_if = "Option::is_none")]
1167 pub default_theme_texture: Option<String>,
1168 #[serde(rename = "default-theme-material")]
1169 #[serde(skip_serializing_if = "Option::is_none")]
1170 pub default_theme_material: Option<String>,
1171}
1172impl Appearance {
1173 fn new() -> Self {
1174 Appearance {
1175 materials: None,
1176 textures: None,
1177 vertices_texture: None,
1178 default_theme_texture: None,
1179 default_theme_material: None,
1180 }
1181 }
1182 fn add_material(&mut self, jm: Value) -> usize {
1183 let re = match &mut self.materials {
1184 Some(x) => match x.iter().position(|e| *e == jm) {
1185 Some(y) => y,
1186 None => {
1187 x.push(jm);
1188 x.len() - 1
1189 }
1190 },
1191 None => {
1192 let mut ls: Vec<Value> = Vec::new();
1193 ls.push(jm);
1194 self.materials = Some(ls);
1195 0
1196 }
1197 };
1198 re
1199 }
1200 fn add_texture(&mut self, jm: Value) -> usize {
1201 let re = match &mut self.textures {
1202 Some(x) => match x.iter().position(|e| *e == jm) {
1203 Some(y) => y,
1204 None => {
1205 x.push(jm);
1206 x.len() - 1
1207 }
1208 },
1209 None => {
1210 let mut ls: Vec<Value> = Vec::new();
1211 ls.push(jm);
1212 self.textures = Some(ls);
1213 0
1214 }
1215 };
1216 re
1217 }
1218 fn add_vertices_texture(&mut self, mut vs: Vec<Vec<f64>>) {
1219 match &mut self.vertices_texture {
1220 Some(x) => {
1221 x.append(&mut vs);
1222 }
1223 None => {
1224 let mut ls: Vec<Vec<f64>> = Vec::new();
1225 ls.append(&mut vs);
1226 self.vertices_texture = Some(ls);
1227 }
1228 };
1229 }
1230}
1231
1232pub fn cjseq_to_cj(mut base_cj: CityJSON, features: Vec<CityJSONFeature>) -> CityJSON {
1235 for mut feature in features {
1236 base_cj.add_cjfeature(&mut feature);
1237 }
1238
1239 base_cj.remove_duplicate_vertices();
1240 base_cj.update_transform();
1241 base_cj.update_geographicalextent();
1242
1243 base_cj
1244}
1245
1246#[cfg(target_arch = "wasm32")]
1248pub mod wasm;
1249
1250#[cfg(target_arch = "wasm32")]
1252pub use wasm::*;