1use super::constant::INVALID;
2use super::types::Grid;
3use super::util::bilinear;
4use serde::{Deserialize, Serialize};
5#[derive(Serialize, Deserialize, Debug)]
7pub struct Grid2D {
8 pub epsg: i32, pub start_x: f64, pub start_y: f64,
11 end_x: f64,
12 end_y: f64,
13 pub res_x: f64,
14 pub res_y: f64,
15 pub width: usize,
16 pub height: usize,
17 pub datas: Vec<f64>,
18}
19impl Grid for Grid2D {
20 fn get_end_x(&self) -> f64 {
21 self.end_x
22 }
23 fn get_end_y(&self) -> f64 {
24 self.end_y
25 }
26}
27impl Grid2D {
28 pub fn new(
29 start_x: f64,
30 start_y: f64,
31 epsg: i32,
32 res_x: f64,
33 res_y: f64,
34 width: usize,
35 height: usize,
36 datas: Vec<f64>,
37 ) -> Grid2D {
38 if datas.len() != width * height {
40 panic!("2D格网datas长度与元数据的width*height不匹配!");
41 }
42 let end_x = start_x + res_x * (width as f64);
43 let end_y = start_y + res_y * (height as f64);
44 Grid2D {
45 epsg,
46 start_x,
47 start_y,
48 end_x,
49 end_y,
50 res_x,
51 res_y,
52 width,
53 height,
54 datas,
55 }
56 }
57 pub fn get_val(&self, x: f64, y: f64) -> f64 {
60 let _min_y = self.start_y.min(self.get_end_y());
61 let _max_y = self.start_y.max(self.get_end_y());
62 if x < self.start_x || x > self.get_end_x() || y < _min_y || y > _max_y {
63 INVALID
64 } else {
65 let float_row = (y - self.start_y) / self.res_y;
68 let float_column = (x - self.start_x) / self.res_x;
69 let start_row = float_row.floor() as usize;
70 let start_column = float_column.floor() as usize;
71 let left_scale_factor = float_column.fract();
72 let top_scale_factor = float_row.fract();
73
74 let mut end_row = start_row + 1;
75 let mut end_column = start_column + 1;
76 if end_row >= self.height {
77 end_row = start_row;
78 }
79 if end_column >= self.width {
80 end_column = start_column;
81 }
82 let lt_index = start_row * self.width + start_column;
83 let rt_index = start_row * self.width + end_column;
84 let lb_index = end_row * self.width + start_column;
85 let rb_index = end_row * self.width + end_column;
86 let lt_wal = self.datas[lt_index];
87 let rt_val = self.datas[rt_index];
88 let lb_val = self.datas[lb_index];
89 let rb_val = self.datas[rb_index];
90 let val = bilinear(
91 lt_wal,
92 rt_val,
93 lb_val,
94 rb_val,
95 left_scale_factor,
96 top_scale_factor,
97 );
98 val
99 }
100 }
101}