A Rust Crate which provides fast lookup of OSTN15 adjustments, for the conversion of ETRS89 grid coordinates to OSGB36, natively or via FFI.
This library only provides the adjustment values. For a complete solution, see the lonlat_bng crate, which provides the OSTN15 transform via FFI, and / or the convertbng Python package.
use ostn15_phf::ostn15_lookup;
// Caister Tower Eastings and Northings: 651307.003, 313255.686
let e_grid = (651307.003 / 1000.) as i32;
let n_grid = (313255.686 / 1000.) as i32;
let key = e_grid + (n_grid * 701) + 1
// key is 220065
// don't use unwrap() in production
let result = ostn15_lookup(&key).unwrap();
// result should be (102.787, -78.242, 44.236)
assert_eq!(result, (102.787, -78.242, 44.236));import sys, ctypes
from ctypes import c_int32, c_double, Structure
class GridRefs(Structure):
_fields_ = [("eastings", c_int32),
("northings", c_int32)]
def __str__(self):
return "({}, {})".format(self.eastings, self.northings)
class Shifts(Structure):
_fields_ = [("x_shift", c_double),
("y_shift", c_double),
("z_shift", c_double)]
def __str__(self):
return "({}, {}, {})".format(self.x_shift, self.y_shift, self.z_shift)
prefix = {'win32': ''}.get(sys.platform, 'lib')
extension = {'darwin': '.dylib', 'win32': '.dll'}.get(sys.platform, '.so')
lib = ctypes.cdll.LoadLibrary(prefix + "ostn15_phf" + extension)
lib.get_shifts_ffi.argtypes = (GridRefs,)
lib.get_shifts_ffi.restype = Shifts
result = GridRefs(651, 313)
print(lib.get_shifts_ffi(result))// compile with e.g. `clang -lostn15_phf -L target/release -o ostn15_shifts src/ostn15.c` from project root
// run with `LD_LIBRARY_PATH=target/release ./ostn15_shifts` from project root
#include <stdio.h>
#include <stdint.h>
#include <math.h>
typedef struct {
int32_t easting;
int32_t northing;
} gridrefs;
typedef struct {
double x_shift;
double y_shift;
double z_shift;
} adjustment;
extern adjustment get_shifts_ffi(gridrefs);
int main(void) {
// Caister Tower example: 651307.003, 313255.686
// Convert to grid coordinates by dividing by 1000
gridrefs initial = { .easting = 651, .northing = 313 };
adjustment adj = get_shifts_ffi(initial);
// Check if the lookup was successful (NAN indicates failure)
if (isnan(adj.x_shift) || isnan(adj.y_shift) || isnan(adj.z_shift)) {
fprintf(stderr, "Error: Grid reference lookup failed\n");
return 1;
}
// Print the adjustment values
// Expected result: (102.787, -78.242, 44.236)
printf("Adjustment shifts: (%.3f, %.3f, %.3f)\n",
adj.x_shift, adj.y_shift, adj.z_shift);
return 0;
}- Ensure that Rust is installed
- Clone this repo
- In the repo root, run
cargo build --release - The dylib or DLL will be available as
target/release/libostn15_phf.{dylib, dll} - If you need to build a
.sofor Linux:ar -x target/release/libostn15_phf.agcc -shared *.o -o target/release/libostn15_phf.so
This software makes use of OSTN15 data, which is © Crown copyright, Ordnance Survey and the Ministry of Defence (MOD) 2016. All rights reserved. Provided under the BSD 2-clause license.
