Start implementing version 0

This commit is contained in:
Austen Adler 2023-02-16 00:11:36 -05:00
parent 9a6a68d2a7
commit d990e98de9
5 changed files with 109 additions and 6 deletions

View File

@ -10,6 +10,10 @@
= Algorithm
The goal of this document is to define the algorithm.
If you want to see the steps to get to this definition, go to link:DESIGN.html[DESIGN].
== Data format
[source,title='this_algorithm and S2 CellID Format']
@ -21,9 +25,9 @@ WORD0 (13 bits) : | | |vvvvvv vvvvvvv
0000 (10 bits) : | | | |vvvvvvvvv v
Not represented : | | | | |
: | | | | |
Bit : 64 52 48 39 32 26 16 1
: | | | | | | | |
: 0100101110101000 1011100010010011 1001001100100l00 1100000000000000
Bit : 63 51 48 38 32 25 16| 0
: | | | | | | | | |
: 0100101110101000 1011100010010011 1001001100100100 1100000000000000
=== S2 CellID Format === | | || |
Face number : ^^^ || |
Data bits : ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^| |

View File

@ -12,6 +12,8 @@
The goal of this document is to walk through how the design was chosen.
If you want to see the algorithm definition, go to link:ALGORITHM.html[ALGORITHM].
== 10,000 meter view
This project allows anyone to address ~1 square meter of land by bringing together:
@ -423,7 +425,7 @@ data_bits = level * 2 = 23 * 2 = 46
Bit : 64 48 32 16 1
: | | | | |
: 01001011101010001011100010010011 1001001100100l001100000000000000
: 01001011101010001011100010010011 10010011001001001100000000000000
Face number : ^^^
Data bits : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
Bit after data bits (1) : ^
@ -486,7 +488,7 @@ Data bits : vvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvv
Face number : vvv
Bit : 64 48 32 16 1
: | | | | |
: 01001011101010001011100010010011 1001001100100l001100000000000000
: 01001011101010001011100010010011 10010011001001001100000000000000
Not represented : ^^^^^^^^^^^^^^^
0000 (10 bits) : ^^^^^^^^^^
WORD0 (13 bits) : ^^^^^^ ^^^^^^^

View File

@ -0,0 +1,34 @@
use std::ops::RangeInclusive;
use s2::{cellid::CellID, latlng::LatLng};
pub fn lat_lon_to_cellid(lat: f64, lon: f64) -> CellID {
Into::<CellID>::into(LatLng::from_degrees(lat, lon))
}
pub(crate) fn extract_binary(number: u64, range: RangeInclusive<usize>) -> u64 {
(number >> range.start()) & (u64::MAX >> (63 - (range.end() - range.start())))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_binary() {
assert_eq!(extract_binary(0b0, 0..=0), 0b0);
assert_eq!(extract_binary(0b11_1111_11, 2..=5), 0b1111);
assert_eq!(extract_binary(0b11_0101_11, 2..=5), 0b0101);
assert_eq!(extract_binary(0b11_1100_11, 2..=5), 0b1100);
assert_eq!(extract_binary(0b111_10011_, 0..=4), 0b10011);
assert_eq!(extract_binary(0b111100_1_1, 1..=1), 0b1);
assert_eq!(extract_binary(0b111100_0_1, 1..=1), 0b0);
// A full test from the docs
let cell_id = 0b0100101110101000_1011100010010011_1001001100100100_1100000000000000_u64;
assert_eq!(extract_binary(cell_id, 15..=24), 0b10_01001001);
assert_eq!(extract_binary(cell_id, 25..=37), 0b01001_11001001);
assert_eq!(extract_binary(cell_id, 38..=50), 0b00010_11100010);
assert_eq!(extract_binary(cell_id, 51..=63), 0b01001_01110101);
}
}

View File

@ -2,14 +2,18 @@
#![allow(clippy::cast_possible_truncation, clippy::multiple_crate_versions)]
#![allow(unused_imports)]
pub mod v0;
use conversions::lat_lon_to_cellid;
pub use s2::s1::angle::Angle;
use std::{
fmt::Display,
ops::{Add, AddAssign},
str::FromStr,
};
mod conversions;
use thiserror::Error;
use s2::cellid::CellID;
use s2::{cellid::CellID, latlng::LatLng, s1::Deg};
use words::Word;
pub type Number = u32;
@ -92,6 +96,24 @@ impl FromStr for Address<'_> {
}
impl Address<'_> {
pub fn from_lat_lon(lat: f64, lon: f64) -> Self {
let cellid = conversions::lat_lon_to_cellid(lat, lon);
v0::UnpackedCellID::from(cellid).into()
// Self::cellid_to_v0(&cellid)
}
// fn cellid_to_v0(cell_id: &CellID) -> Self {
// // The raw binary representation of the cellid
// let raw_cellid = cell_id.0;
// // Self {
// // number,
// // words: words.into_inner().unwrap(),
// // }
// }
fn parse_v0(number: Number, word_components: Vec<&str>) -> Result<Self, Error> {
if !(V0_MIN_NUMBER..=V0_MAX_NUMBER).contains(&number) {
return Err(Error::NumberOutOfRange(number));

41
this_algorithm/src/v0.rs Normal file
View File

@ -0,0 +1,41 @@
use crate::{conversions, Address};
use std::ops::RangeInclusive;
use s2::{cell::Cell, cellid::CellID};
pub struct UnpackedCellID {
pub number_bits: u16,
pub word0_bits: u16,
pub word1_bits: u16,
pub word2_bits: u16,
}
impl From<CellID> for UnpackedCellID {
fn from(cell_id: CellID) -> Self {
Self::from(cell_id.0)
}
}
impl From<u64> for UnpackedCellID {
fn from(cell_id: u64) -> Self {
Self {
number_bits: conversions::extract_binary(cell_id, 15..=24) as u16,
word0_bits: conversions::extract_binary(cell_id, 25..=37) as u16,
word1_bits: conversions::extract_binary(cell_id, 38..=50) as u16,
word2_bits: conversions::extract_binary(cell_id, 51..=63) as u16,
}
}
}
impl From<UnpackedCellID> for Address<'_> {
fn from(unpacked_cell_id: UnpackedCellID) -> Self {
let word0 = words::NUMBER_TO_WORDS[unpacked_cell_id.word0_bits as usize][0];
let word1 = words::NUMBER_TO_WORDS[unpacked_cell_id.word1_bits as usize][0];
let word2 = words::NUMBER_TO_WORDS[unpacked_cell_id.word2_bits as usize][0];
Self {
number: unpacked_cell_id.number_bits as u32,
words: [word0, word1, word2],
}
}
}