Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to convert position into Area ID #197

Merged
merged 8 commits into from
Apr 1, 2024
66 changes: 56 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ struct Cli {

/// Receiver latitude to report, in degrees
#[arg(long, default_value_t = 37.77101999622968, allow_hyphen_values = true)]
lat: f64,
lat: f32,

/// Receiver longitude to report, in degrees
#[arg(long, default_value_t = -122.40315159140708, allow_hyphen_values = true)]
lon: f64,
lon: f32,

/// Receiver height to report, in meters
#[arg(long, default_value_t = -5.549358852471994, allow_hyphen_values = true)]
height: f64,
height: f32,

/// Client ID
#[arg(
Expand Down Expand Up @@ -93,6 +93,10 @@ struct Cli {
#[arg(long)]
area_id: Option<u32>,

/// Convert the given position into an Area ID and use that to send CRA messages instead of typical GGA messages
#[arg(long, default_value_t = false)]
pos_to_area_id: bool,

/// Field specifying which types of corrections are to be received
#[arg(long)]
corrections_mask: Option<u16>,
Expand Down Expand Up @@ -149,9 +153,9 @@ fn checksum(buf: &[u8]) -> u8 {
#[serde(rename_all = "lowercase")]
enum Message {
Gga {
lat: f64,
lon: f64,
height: f64,
lat: f32,
lon: f32,
height: f32,
},
Cra {
request_counter: Option<u8>,
Expand All @@ -173,8 +177,8 @@ impl Message {
let lat_deg = latn as u16;
let lon_deg = lonn as u16;

let lat_min = (latn - (lat_deg as f64)) * 60.0;
let lon_min = (lonn - (lon_deg as f64)) * 60.0;
let lat_min = (latn - (lat_deg as f32)) * 60.0;
let lon_min = (lonn - (lon_deg as f32)) * 60.0;

let lat_dir = if lat < 0.0 { 'S' } else { 'N' };
let lon_dir = if lon < 0.0 { 'W' } else { 'E' };
Expand Down Expand Up @@ -219,7 +223,11 @@ fn build_cra(opt: &Cli) -> Command {
crc: None,
message: Message::Cra {
request_counter: opt.request_counter,
area_id: opt.area_id,
area_id: if opt.pos_to_area_id {
Some(area_id(opt.lat, opt.lon))
} else {
opt.area_id
},
corrections_mask: opt.corrections_mask,
solution_id: opt.solution_id,
},
Expand All @@ -239,6 +247,44 @@ fn build_gga(opt: &Cli) -> Command {
}
}

struct AreaIDParams {
a: f32,
b: f32,
offset: i32,
}

fn get_area_id_parameters(lat: f32) -> AreaIDParams {
if lat > 60.0 && lat <= 75.0 {
AreaIDParams {
a: 0.04,
b: 0.02,
offset: 0,
}
} else if lat > -60.0 && lat <= 60.0 {
AreaIDParams {
a: 0.02,
b: 0.02,
offset: -6750000,
}
} else if lat > -75.0 && lat <= -60.0 {
AreaIDParams {
a: 0.04,
b: 0.02,
offset: 54000000,
}
} else {
unimplemented!("Invalid latitude {lat}")
}
}

fn area_id(lat: f32, lon: f32) -> u32 {
let params = get_area_id_parameters(lat);

((360.0 / params.a) * (75.0 - lat) / params.b) as u32
+ ((lon + 180.0) / params.a) as u32
+ params.offset as u32
pcrumley marked this conversation as resolved.
Show resolved Hide resolved
}

fn get_commands(opt: Cli) -> Result<Box<dyn Iterator<Item = Command> + Send>> {
if let Some(path) = opt.input {
let file = std::fs::File::open(path)?;
Expand All @@ -250,7 +296,7 @@ fn get_commands(opt: Cli) -> Result<Box<dyn Iterator<Item = Command> + Send>> {
return Ok(Box::new(iter::empty()));
}

if opt.area_id.is_some() {
if opt.area_id.is_some() || opt.pos_to_area_id {
let first = build_cra(&opt);
let it = iter::successors(Some(first), move |prev| {
let mut next = *prev;
Expand Down
Loading