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

Issue with Oblique Mercator Projection Transformation for Oregon CRS in Rust #123

Open
pbroboto opened this issue Dec 31, 2024 · 0 comments

Comments

@pbroboto
Copy link

pbroboto commented Dec 31, 2024

HI, I am working with the Oblique Mercator (OMERC) projection using the parameters for the Oregon Coordinate Reference System: Columbia River West Zone, as specified in the OCRS Handbook User Guide (OCRS-Handbook-User-Guide.pdf). Despite following the documentation, I encountered incorrect results when transforming grid coordinates to geographic coordinates.
Projection Parameters:

  • Latitude of local origin: 45° 55’ 00" N
  • Longitude of local origin: 123° 00’ 00" W
  • False northing: -3000000.000 m
  • False easting: 7000000.000 m
  • Projection skew axis scale: 1.000000
  • Skew axis azimuth at origin: -65° 00’ 00"

To verify my implementation, I compared the output with the example grid coordinates provided in the handbook. Below are the reference points:
Point Name | Latitude (N) | Longitude (W) | Northing (m) | Easting (m)
Columbia River West 1 | 46°12'17.57866" | 123°57'21.88345" | 218152.78553 | 94514.71992
Columbia River West 2 | 45°46'15.02108" | 122°51'37.48609" | 169474.85476 | 179157.87759
Columbia River West 3 | 46°10'24.21823" | 123°49'55.47899" | 214545.28450 | 104047.54956

I used the following Rust projection definition:

let def = "geo:in | omerc lonc=-123 latc=45:55:0 k_0=1.0 alpha=-65 gamma_c=-65 x_0=7000000 y_0=-3000000 ellps=GRS80 variant";
let ldp = context.op(def)?;

Test Details:
Input Grid Coordinates:

 [
    Coor2D([94514.71992, 218152.78553]),
    Coor2D([179157.87759, 169474.85476]),
    Coor2D([104047.54956, 214545.28450]),
]

Expected Geographic Coordinates:

 [
    Coor2D([46.20488296111112, -123.95607873611111]),
    Coor2D([45.770839188888885, -122.86041280277777]),
    Coor2D([46.17339395277777, -123.83207749722222]),
]

Result Geographic Coordinates from Calculation:

[
    Coor2D([32.552006942375, -213.36616765486355]),
    Coor2D([33.04360308577579, -212.50135304668396]),
    Coor2D([32.61507445368379, -213.2872011967366]),
]

Completed code:

use geodesy::prelude::*;

fn dms2degree(d: f64, m: f64, s: f64) -> f64 {
    d + m / 60.0 + s / 3600.0
}

fn main() -> Result<(), Box<Error>> {
    println!("Oregon Coordinate Reference System : Columbia River West Zone");
    let mut context = Minimal::new();
    let def = "geo:in | omerc lonc=-123 latc=43:50:0 k_0=1.0 alpha=295 gamma_c=295 x_0=7000000 y_0=-3000000 ellps=GRS80 variant";
    let ldp = context.op(def)?;

    //matched geographic coordinates (degree) from the document, for comparison
    let geo1 = Coor2D::raw(
        dms2degree(46.0, 12.0, 17.57866),
        -1.0 * dms2degree(123.0, 57.0, 21.88345),
    );
    let geo2 = Coor2D::raw(
        dms2degree(45.0, 46.0, 15.02108),
        -1.0 * dms2degree(122.0, 51.0, 37.48609),
    );
    let geo3 = Coor2D::raw(
        dms2degree(46.0, 10.0, 24.21823),
        -1.0 * dms2degree(123.0, 49.0, 55.47899),
    );
    let geo_coor = [geo1, geo2, geo3];
    println!("Matched geographic coordinates (from document): {:#?}", geo_coor);

    //matched grid coordinates from the document, for comparison
    let grid1 = Coor2D::raw(94514.71992, 218152.78553);
    let grid2 = Coor2D::raw(179157.87759, 169474.85476);
    let grid3 = Coor2D::raw(104047.54956, 214545.28450);
    let grid_coor = [grid1, grid2, grid3];

    let mut result_coor = grid_coor.clone();
    context.apply(ldp, Inv, &mut result_coor)?;

    println!("Input Grid Coordinates (from grid coordinates): {:#?}", grid_coor);
    println!("Result Geographic Coordinates: {:#?}", result_coor);

    // Round the trip back.
    context.apply(ldp, Fwd, &mut result_coor)?;
    println!("Round The Trip Back Coordinates: {:#?}", result_coor);
    Ok(())
}

Issue:
The resulting geographic coordinates differ significantly from the expected values, with both latitude and longitude being completely off.
Could you please advise if there are any issues with the projection definition or parameter usage in
the "geo:in | omerc" string?

Thank you for your assistance!

Best regards,
Prajuab Riabroy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant