pub struct SingleId { /* private fields */ }Expand description
SingleIdは標準的な時空間 ID を表す型。
内部的には下記のような構造体で構成されている。
この型は PartialOrd / Ord を実装していますが、これは主にBTreeSet や BTreeMap などの順序付きコレクションでの格納・探索用であり、実際の空間的な「大小」を意味するものではない。
pub struct SingleId {
z: u8,
f: i32,
x: u32,
y: u32,
temporal_id: TemporalId,
}Implementations§
Source§impl SingleId
impl SingleId
Sourcepub fn new(z: u8, f: i32, x: u32, y: u32) -> Result<SingleId, Error>
pub fn new(z: u8, f: i32, x: u32, y: u32) -> Result<SingleId, Error>
指定された値から SingleId を作成する。このコンストラクタは、与えられた z, f, x, y が 各ズームレベルにおける範囲内にあるかを検証し、範囲外の場合は Error を返す。
§パラメータ
z— ズームレベル(0–MAX_ZOOM_LEVELの範囲が有効)f— Fインデックス(鉛直方向)x— Xインデックス(東西方向)y— Yインデックス(南北方向)
§バリデーション
zがMAX_ZOOM_LEVELを超える場合、SpatialIdError::ZOutOfRangeを返す。fがズームレベルzに対するF_MIN[z]..=F_MAX[z]の範囲外の場合、SpatialIdError::FOutOfRangeを返す。xまたはyが0..=XY_MAX[z]の範囲外の場合、 それぞれSpatialIdError::XOutOfRange、SpatialIdError::YOutOfRangeを返す。
IDの作成:
let id = SingleId::new(5, 3, 2, 10).unwrap();
assert_eq!(id.to_string(), "5/3/2/10".to_string());次元の範囲外の検知:
let id = SingleId::new(3, 3, 2, 10);
assert_eq!(id, Err(SpatialIdError::YOutOfRange{z:3,y:10}.into()));ズームレベルの範囲外の検知:
let id = SingleId::new(68, 3, 2, 10);
assert_eq!(id, Err(SpatialIdError::ZOutOfRange { z:68 }.into()));Sourcepub unsafe fn new_unchecked(z: u8, f: i32, x: u32, y: u32) -> SingleId
pub unsafe fn new_unchecked(z: u8, f: i32, x: u32, y: u32) -> SingleId
検証を行わずに SingleId を作成する。
この関数は SingleId::new と異なり、与えられた z, f, x, y に対して一切の範囲チェックや整合性チェックを行わない。そのため、高速に ID を生成できるが、不正なパラメータを与えた場合の動作は未定義である。
§注意
呼び出し側は、以下をすべて満たすことを保証しなければならない。
zが有効なズームレベル(0–MAX_ZOOM_LEVEL)であることfが与えられたzに応じてF_MIN[z]..=F_MAX[z]の範囲内であることxおよびyが0..=XY_MAX[z]の範囲内であること
これらが保証されない場合、パニック・不正メモリアクセス・未定義動作を引き起こす可能性がある。
// パラメータが妥当であることを呼び出し側が保証する必要がある
let id = unsafe { SingleId::new_unchecked(5, 3, 2, 10) };
assert_eq!(id.z(), 5u8);
assert_eq!(id.f(), 3i32);
assert_eq!(id.x(), 2u32);
assert_eq!(id.y(), 10u32);Source§impl SingleId
impl SingleId
Sourcepub fn random_within(z_range: RangeInclusive<u8>) -> Self
pub fn random_within(z_range: RangeInclusive<u8>) -> Self
特定のズームレベル間において、ランダムなSingleIdを作成する
Sourcepub fn random_using<R: Rng>(rng: &mut R) -> Self
pub fn random_using<R: Rng>(rng: &mut R) -> Self
外部から渡された乱数生成器を使って、全ズーム範囲からランダムな SingleId を生成します。
Sourcepub fn random_at_using<R: Rng>(rng: &mut R, z: u8) -> Self
pub fn random_at_using<R: Rng>(rng: &mut R, z: u8) -> Self
外部から渡された乱数生成器を使って、指定ズームのランダムな SingleId を生成します。
Sourcepub fn random_within_using<R: Rng>(
rng: &mut R,
z_range: RangeInclusive<u8>,
) -> Self
pub fn random_within_using<R: Rng>( rng: &mut R, z_range: RangeInclusive<u8>, ) -> Self
外部から渡された乱数生成器を使って、指定ズーム範囲のランダムな SingleId を生成します。
z_range の終端は MAX_ZOOM_LEVEL でクリップされ、start > end の場合は end を採用します。
Source§impl SingleId
impl SingleId
Sourcepub fn z(&self) -> u8
pub fn z(&self) -> u8
この SingleId が保持しているズームレベル z を返します。
let id = SingleId::new(5, 3, 2, 10).unwrap();
assert_eq!(id.z(), 5u8);Sourcepub fn f(&self) -> i32
pub fn f(&self) -> i32
この SingleId が保持している F インデックス f を返します。
let id = SingleId::new(5, 3, 2, 10).unwrap();
assert_eq!(id.f(), 3i32);Sourcepub fn x(&self) -> u32
pub fn x(&self) -> u32
この SingleId が保持している X インデックス x を返します。
let id = SingleId::new(5, 3, 2, 10).unwrap();
assert_eq!(id.x(), 2u32);Sourcepub fn y(&self) -> u32
pub fn y(&self) -> u32
この SingleId が保持している Y インデックス y を返します。
let id = SingleId::new(5, 3, 2, 10).unwrap();
assert_eq!(id.y(), 10u32);Sourcepub fn set_f(&mut self, value: i32) -> Result<(), Error>
pub fn set_f(&mut self, value: i32) -> Result<(), Error>
F インデックスを更新します。
与えられた value が、現在のズームレベル z に対応する
F_MIN[z]..=F_MAX[z] の範囲内にあるかを検証し、範囲外の場合は Error を返します。
§パラメータ
value— 新しい F インデックス
§バリデーション
valueが許容範囲外の場合、SpatialIdError::FOutOfRangeを返します。
正常な更新:
let mut id = SingleId::new(5, 3, 2, 10).unwrap();
id.set_f(4).unwrap();
assert_eq!(id.f(), 4);範囲外の検知:
let mut id = SingleId::new(3, 3, 2, 7).unwrap();
let result = id.set_f(999);
assert!(matches!(result, Err(Error::SpatialId(SpatialIdError::FOutOfRange { z: 3, f: 999 }))));Sourcepub fn set_x(&mut self, value: u32) -> Result<(), Error>
pub fn set_x(&mut self, value: u32) -> Result<(), Error>
X インデックスを更新します。
与えられた value が、現在のズームレベル z に対応する
0..=XY_MAX[z] の範囲内にあるかを検証し、範囲外の場合は Error を返します。
§パラメータ
value— 新しい X インデックス
§バリデーション
valueが許容範囲外の場合、SpatialIdError::XOutOfRangeを返します。
正常な更新:
let mut id = SingleId::new(5, 3, 2, 10).unwrap();
id.set_x(4).unwrap();
assert_eq!(id.x(), 4);範囲外の検知
let mut id = SingleId::new(3, 3, 2, 7).unwrap();
let result = id.set_x(999);
assert!(matches!(result, Err(Error::SpatialId(SpatialIdError::XOutOfRange { z: 3, x: 999 }))));Sourcepub fn set_y(&mut self, value: u32) -> Result<(), Error>
pub fn set_y(&mut self, value: u32) -> Result<(), Error>
Y インデックスを更新します。
与えられた value が、現在のズームレベル z に対応する
0..=XY_MAX[z] の範囲内にあるかを検証し、範囲外の場合は Error を返します。
§パラメータ
value— 新しい Y インデックス
§バリデーション
valueが許容範囲外の場合、SpatialIdError::YOutOfRangeを返します。
正常な更新
let mut id = SingleId::new(5, 3, 2, 10).unwrap();
id.set_y(8).unwrap();
assert_eq!(id.y(), 8);範囲外の検知
let mut id = SingleId::new(3, 3, 2, 7).unwrap();
let result = id.set_y(999);
assert!(matches!(result, Err(Error::SpatialId(SpatialIdError::YOutOfRange { z: 3, y: 999 }))));Sourcepub fn spatial_children_at_zoom(
&self,
target_z: u8,
) -> Result<impl Iterator<Item = SingleId>, Error>
pub fn spatial_children_at_zoom( &self, target_z: u8, ) -> Result<impl Iterator<Item = SingleId>, Error>
指定したズームレベル target_z に細分化した、この SingleId を含むすべての子 SingleId を生成します。
§パラメータ
target_z— 生成したい子SingleIdのズームレベル
§バリデーション
target_zが現在のズームレベルより浅い場合は、SpatialIdError::ZoomLevelTransitionOutOfRangeを返します。target_zが本クレートで扱える最大ズームレベルを超える場合は、SpatialIdError::ZOutOfRangeを返します。
1段深いズームへの細分化
let id = SingleId::new(3, 3, 2, 7).unwrap();
// target_z = 4 のため F, X, Y はそれぞれ 2 分割される
let children: Vec<_> = id.spatial_children_at_zoom(4).unwrap().collect();
assert_eq!(children.len(), 8); // 2 × 2 × 2
// 最初の要素を確認(f, x, y の下限側)
let first = &children[0];
assert_eq!(first.z(), 4);
assert_eq!(first.f(), 3 * 2); // 2
assert_eq!(first.x(), 2 * 2); // 6
assert_eq!(first.y(), 7 * 2); // 8現在より浅いズームを指定した場合
let id = SingleId::new(3, 3, 2, 7).unwrap();
let result = id.spatial_children_at_zoom(2);
assert!(matches!(result, Err(Error::SpatialId(SpatialIdError::ZoomLevelTransitionOutOfRange { current_z: 3, target_z: 2 }))));Sourcepub fn spatial_parent_at_zoom(&self, target_z: u8) -> Result<SingleId, Error>
pub fn spatial_parent_at_zoom(&self, target_z: u8) -> Result<SingleId, Error>
指定したズームレベル target_z に縮約した、この SingleId の親 SingleId を返します。
§パラメータ
target_z— 取得したい親SingleIdのズームレベル
§バリデーション
target_zが現在のズームレベルより深い場合は、SpatialIdError::ZoomLevelTransitionOutOfRangeを返します。target_zが本クレートで扱える最大ズームレベルを超える場合は、SpatialIdError::ZOutOfRangeを返します。
1段浅いズームへの縮約
let id = SingleId::new(4, 6, 9, 14).unwrap();
let parent = id.spatial_parent_at_zoom(3).unwrap();
assert_eq!(parent.z(), 3u8);
assert_eq!(parent.f(), 3i32);
assert_eq!(parent.x(), 4u32);
assert_eq!(parent.y(), 7u32);Fが負の場合の挙動
let id = SingleId::new(4, -1, 8, 12).unwrap();
let parent = id.spatial_parent_at_zoom(3).unwrap();
assert_eq!(parent.z(), 3u8);
assert_eq!(parent.f(), -1i32);
assert_eq!(parent.x(), 4u32);
assert_eq!(parent.y(), 6u32);現在より深いズームを指定した場合:
let id = SingleId::new(3, 3, 2, 7).unwrap();
let result = id.spatial_parent_at_zoom(4);
assert!(matches!(result, Err(Error::SpatialId(SpatialIdError::ZoomLevelTransitionOutOfRange { current_z: 3, target_z: 4 }))));Trait Implementations§
Source§impl<'de> Deserialize<'de> for SingleId
impl<'de> Deserialize<'de> for SingleId
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for SingleId
Source§impl IntoFlexIds for SingleId
impl IntoFlexIds for SingleId
Source§impl IntoSingleIds for SingleId
impl IntoSingleIds for SingleId
Source§impl IterFlexIds for SingleId
impl IterFlexIds for SingleId
Source§impl IterSingleIds for SingleId
impl IterSingleIds for SingleId
Source§impl Ord for SingleId
impl Ord for SingleId
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for SingleId
impl PartialOrd for SingleId
Source§impl SpatialId for SingleId
impl SpatialId for SingleId
Source§fn move_f(&mut self, by: i32) -> Result<(), Error>
fn move_f(&mut self, by: i32) -> Result<(), Error>
指定したインデックス差 by に基づき、この SingleId を垂直上下方向に動かします。
§パラメータ
by— インデックス差
§バリデーション
- Fインデックスが範囲外になる場合は
SpatialIdError::FOutOfRangeを返します
移動
let mut id = SingleId::new(4, 6, 9, 10).unwrap();
assert_eq!(id.f(), 6);
let _ = id.move_f(-10).unwrap();
assert_eq!(id.f(), -4);範囲外の検知によるエラー
let mut id = SingleId::new(4, 6, 9, 10).unwrap();
assert_eq!(id.f(), 6);
assert_eq!(id.move_f(50), Err(SpatialIdError::FOutOfRange { z: 4, f: 56 }.into()));Source§fn move_x(&mut self, by: i32)
fn move_x(&mut self, by: i32)
指定したインデックス差 by に基づき、この SingleId を東西方向に動かします。WEBメルカトル図法において、東西方向は循環しているためどのような値を指定してもエラーは発生しません。
§パラメータ
by— インデックス差
移動
let mut id = SingleId::new(4, 6, 9, 10).unwrap();
assert_eq!(id.x(), 9);
let _ = id.move_x(-3);
assert_eq!(id.x(), 6);循環による移動
let mut id = SingleId::new(4, 6, 9, 10).unwrap();
assert_eq!(id.x(), 9);
let _ = id.move_x(100);
assert_eq!(id.x(), 13);Source§fn move_y(&mut self, by: i32) -> Result<(), Error>
fn move_y(&mut self, by: i32) -> Result<(), Error>
指定したインデックス差 by に基づき、この SingleId を南北方向に動かします。
§パラメータ
by— インデックス差
§バリデーション
- Yインデックスが範囲外になる場合は
SpatialIdError::YOutOfRangeを返します
移動
let mut id = SingleId::new(4, 6, 9, 10).unwrap();
assert_eq!(id.y(), 10);
let _ = id.move_y(-3).unwrap();
assert_eq!(id.y(), 7);範囲外の検知によるエラー
let mut id = SingleId::new(4, 6, 9, 10).unwrap();
assert_eq!(id.y(), 10);
assert_eq!(id.move_y(-20), Err(SpatialIdError::YOutOfRange { z: 4, y: 0 }.into()));Source§fn spatial_center(&self) -> Coordinate
fn spatial_center(&self) -> Coordinate
SingleId の中心座標をCoordinate型で返します。
中心座標は空間IDの最も外側の頂点の8点の平均座標です。現実空間における空間IDは完全な直方体ではなく、緯度や高度によって歪みが発生していることに注意する必要があります。
let id = SingleId::new(4, 6, 9, 14).unwrap();
let center: Coordinate = id.spatial_center();
println!("{:?}", center);
// Coordinate { latitude: -81.09321385260839, longitude: 33.75, altitude: 13631488.0 }Source§fn spatial_vertices(&self) -> [Coordinate; 8]
fn spatial_vertices(&self) -> [Coordinate; 8]
SingleId の最も外側の頂点の8点の座標をCoordinate型の配列として返します。
現実空間における空間IDは完全な直方体ではなく、緯度や高度によって歪みが発生していることに注意する必要があります。
let id = SingleId::new(4, 6, 9, 14).unwrap();
let vertices: [Coordinate; 8] = id.spatial_vertices();
println!("{:?}", vertices);
//[Coordinate { latitude: -79.17133464081945, longitude: 22.5, altitude: 12582912.0 }, Coordinate { latitude: -79.17133464081945, longitude: 45.0, altitude: 12582912.0 }, Coordinate { latitude: -82.67628497834903, longitude: 22.5, altitude: 12582912.0 }, Coordinate { latitude: -82.67628497834903, longitude: 45.0, altitude: 12582912.0 }, Coordinate { latitude: -79.17133464081945, longitude: 22.5, altitude: 14680064.0 }, Coordinate { latitude: -79.17133464081945, longitude: 45.0, altitude: 14680064.0 }, Coordinate { latitude: -82.67628497834903, longitude: 22.5, altitude: 14680064.0 }, Coordinate { latitude: -82.67628497834903, longitude: 45.0, altitude: 14680064.0 }]Source§fn length_f_meters(&self) -> f64
fn length_f_meters(&self) -> f64
その空間IDのF方向の長さをメートル単位で計算する関数
Source§fn length_x_meters(&self) -> f64
fn length_x_meters(&self) -> f64
その空間IDのX方向の長さをメートル単位で計算する関数
Source§fn length_y_meters(&self) -> f64
fn length_y_meters(&self) -> f64
その空間IDのY方向の長さをメートル単位で計算する関数