use super::*;
use crate::utils::meshcode::to_meshcode;
use ndarray::Array1;
pub fn to_envelope(meshcode_sw: u64, meshcode_ne: u64) -> Result<Array1<u64>> {
let level_sw = to_meshlevel(&Array1::from_vec(vec![meshcode_sw]))?[0];
let level_ne = to_meshlevel(&Array1::from_vec(vec![meshcode_ne]))?[0];
if level_sw != level_ne {
return Err(JismeshError::MismatchedMeshLevels(level_sw, level_ne));
}
let margin_lat = 0.5;
let margin_lon = 0.5;
let sw_points = to_meshpoint(
Array1::from_vec(vec![meshcode_sw]),
Array1::from_vec(vec![margin_lat]),
Array1::from_vec(vec![margin_lon]),
)?;
let ne_points = to_meshpoint(
Array1::from_vec(vec![meshcode_ne]),
Array1::from_vec(vec![1.0]),
Array1::from_vec(vec![1.0]),
)?;
let lat_s = sw_points[[0, 0]];
let lon_w = sw_points[[1, 0]];
let lat_n = ne_points[[0, 0]];
let lon_e = ne_points[[1, 0]];
make_envelope(lat_s, lon_w, lat_n, lon_e, level_sw)
}
pub fn to_intersects(meshcode: u64, to_level: MeshLevel) -> Result<Array1<u64>> {
let from_level = to_meshlevel(&Array1::from_vec(vec![meshcode]))?[0];
let from_unit_lat = unit_lat(from_level);
let from_unit_lon = unit_lon(from_level);
let to_unit_lat = unit_lat(to_level);
let to_unit_lon = unit_lon(to_level);
let margin_lat = if to_unit_lat <= from_unit_lat {
(to_unit_lat / from_unit_lat) / 2.0
} else {
0.5
};
let margin_lon = if to_unit_lon <= from_unit_lon {
(to_unit_lon / from_unit_lon) / 2.0
} else {
0.5
};
let from_points_sw = to_meshpoint(
Array1::from_vec(vec![meshcode]),
Array1::from_vec(vec![margin_lat]),
Array1::from_vec(vec![margin_lon]),
)?;
let from_points_ne = to_meshpoint(
Array1::from_vec(vec![meshcode]),
Array1::from_vec(vec![1.0]),
Array1::from_vec(vec![1.0]),
)?;
let from_lat_s = from_points_sw[[0, 0]];
let from_lon_w = from_points_sw[[1, 0]];
let from_lat_n = from_points_ne[[0, 0]];
let from_lon_e = from_points_ne[[1, 0]];
make_envelope(from_lat_s, from_lon_w, from_lat_n, from_lon_e, to_level)
}
fn make_envelope(
lat_s: f64,
lon_w: f64,
lat_n: f64,
lon_e: f64,
level: MeshLevel,
) -> Result<Array1<u64>> {
let to_unit_lat = unit_lat(level);
let to_unit_lon = unit_lon(level);
let lat_count = ((lat_n - lat_s) / to_unit_lat).ceil() as usize;
let lon_count = ((lon_e - lon_w) / to_unit_lon).ceil() as usize;
let point_count = lat_count * lon_count;
let mut lats = Vec::with_capacity(point_count);
let mut lons = Vec::with_capacity(point_count);
for i in 0..lat_count {
let to_lat = lat_s + (i as f64 * to_unit_lat);
for j in 0..lon_count {
let to_lon = lon_w + (j as f64 * to_unit_lon);
lats.push(to_lat);
lons.push(to_lon);
}
}
to_meshcode(&Array1::from_vec(lats), &Array1::from_vec(lons), level)
}
#[cfg(test)]
mod tests {
use super::*;
use ndarray::array;
#[test]
fn test_to_envelope() {
let meshcode_sw = 5339; let meshcode_ne = 5339;
let result = to_envelope(meshcode_sw, meshcode_ne).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0], 5339);
let meshcode_sw = 533900; let meshcode_ne = 533901;
let result = to_envelope(meshcode_sw, meshcode_ne).unwrap();
assert!(result.len() > 1);
assert!(result.iter().any(|&x| x == 533900));
assert!(result.iter().any(|&x| x == 533901));
}
#[test]
fn test_to_intersects() {
let meshcode = 5339; let to_level = MeshLevel::Lv2;
let result = to_intersects(meshcode, to_level).unwrap();
assert!(result.len() > 0);
for code in result.iter() {
let level = to_meshlevel(&array![*code]).unwrap();
assert_eq!(level[0], MeshLevel::Lv2);
}
let meshcode = 533900; let to_level = MeshLevel::Lv3;
let result = to_intersects(meshcode, to_level).unwrap();
assert!(result.len() > 0);
for code in result.iter() {
let level = to_meshlevel(&array![*code]).unwrap();
assert_eq!(level[0], MeshLevel::Lv3);
}
}
#[test]
fn test_error_mismatched_levels() {
let meshcode_sw = 5339; let meshcode_ne = 533900;
let result = to_envelope(meshcode_sw, meshcode_ne);
assert!(result.is_err());
}
}