This repository has been archived by the owner on Nov 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
scalar.rs
102 lines (82 loc) · 2.86 KB
/
scalar.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::algorithm::bounding_rect::bounding_rect_multipolygon;
use crate::geo_traits::MultiPolygonTrait;
use crate::Polygon;
use arrow2::buffer::Buffer;
use arrow2::offset::OffsetsBuffer;
use rstar::{RTreeObject, AABB};
use super::iterator::MultiPolygonIterator;
/// An Arrow equivalent of a Polygon
#[derive(Debug, Clone)]
pub struct MultiPolygon<'a> {
/// Buffer of x coordinates
pub x: &'a Buffer<f64>,
/// Buffer of y coordinates
pub y: &'a Buffer<f64>,
/// Offsets into the polygon array where each geometry starts
pub geom_offsets: &'a OffsetsBuffer<i64>,
/// Offsets into the ring array where each polygon starts
pub polygon_offsets: &'a OffsetsBuffer<i64>,
/// Offsets into the coordinate array where each ring starts
pub ring_offsets: &'a OffsetsBuffer<i64>,
pub geom_index: usize,
}
impl<'a> MultiPolygonTrait<'a> for MultiPolygon<'a> {
type ItemType = Polygon<'a>;
type Iter = MultiPolygonIterator<'a>;
fn polygons(&'a self) -> Self::Iter {
MultiPolygonIterator::new(self)
}
fn num_polygons(&'a self) -> usize {
let (start, end) = self.geom_offsets.start_end(self.geom_index);
end - start
}
fn polygon(&'a self, i: usize) -> Option<Self::ItemType> {
let (start, end) = self.geom_offsets.start_end(self.geom_index);
if i > (end - start) {
return None;
}
// TODO: double check offsets is correct
Some(Polygon {
x: self.x,
y: self.y,
geom_offsets: self.polygon_offsets,
ring_offsets: self.ring_offsets,
geom_index: start + i,
})
}
}
impl From<MultiPolygon<'_>> for geo::MultiPolygon {
fn from(value: MultiPolygon<'_>) -> Self {
(&value).into()
}
}
impl From<&MultiPolygon<'_>> for geo::MultiPolygon {
fn from(value: &MultiPolygon<'_>) -> Self {
// Start and end indices into the polygon_offsets buffer
let (start_geom_idx, end_geom_idx) = value.geom_offsets.start_end(value.geom_index);
let mut polygons: Vec<geo::Polygon> = Vec::with_capacity(end_geom_idx - start_geom_idx);
for geom_idx in start_geom_idx..end_geom_idx {
let poly = crate::polygon::util::parse_polygon(
value.x,
value.y,
value.polygon_offsets,
value.ring_offsets,
geom_idx,
);
polygons.push(poly);
}
geo::MultiPolygon::new(polygons)
}
}
impl From<MultiPolygon<'_>> for geo::Geometry {
fn from(value: MultiPolygon<'_>) -> Self {
geo::Geometry::MultiPolygon(value.into())
}
}
impl RTreeObject for MultiPolygon<'_> {
type Envelope = AABB<[f64; 2]>;
fn envelope(&self) -> Self::Envelope {
let (lower, upper) = bounding_rect_multipolygon(self);
AABB::from_corners(lower, upper)
}
}