An attempt at speeding up the conversion between decimal longitude and latitude and British National Grid (epsg:27700) coordinates, using an external Rust binary and Python FFI.
Python is relatively slow; this type of conversion is usually carried out in bulk, so an order-of-magnitude improvement could save precious minutes
Add the following to your Cargo.toml
(You'll have to look up the latest version on crates.io)
lonlat_bng = "0.1.8"
Full library documentation is available here
The native functions exposed by the library are:
lonlat_bng::convert_bng(&f32, &f32) -> (i32, i32)
lonlat_bng::convert_lonlat(&i21 &i32) -> (f32, f32)
lonlat_bng::convert_to_bng_threaded_vec(Vec<(&f32, &f32)>) -> Vec<(i32, i32)>
lonlat_bng::convert_to_lonlat_threaded_vec(Vec<(&i32, &i32)>) -> Vec<(f32, f32)>
The FFI C-compatible functions exposed by the library are:
convert_to_bng_threaded(Array, Array) -> Array
convert_to_bng_threaded(Array, Array) -> Array
The Array
s must contain 32-bit Float
s and 32-bit Int
s, respectively. For examples, see the Array
struct and tests in lib.rs, and the _BNG_FFIArray
class in convertbng
convert_bng
is available from PyPI for OSX and *nix:
pip install convertbng
More information is available in its repository
An IPython (sorry, Jupyter) notebook with some benchmarks is here
cargo build --release
from the repo rootipython notebook
, and open rust_BNG
.Python: 10000 loops, best of 10: 31 µs per loop
Rust: 100000 loops, best of 10: 2.04 µs per loop* 💅
Pyproj: 100000 loops, best of 10: 11.8 µs per loop†
*Test warns that intermediate results may have been cached
Convert 10,000000 sets of random coordinates
Python: 1 loops, best of 10: 804 ms per loop
Rust: 1 loops, best of 10: 204 ms per loop
Pyproj: 10 loops, best of 10: 99.5 ms per loop 💅
Rust (threaded): 10 loops, best of 10: 162.5 ms per loop
Using multithreading, we can get much closer (pyproj is now only 65% faster). Not bad, considering the relative youth of Rust as a language (let alone this library), and the maturity of the PROJ.4 project.
The Helmert transform used is accurate to within 7 metres on average, so this library is not suitable for calculations used in e.g. surveying. If higher accuracy is required, please use a product which incorporates the OSTN02 calculations, which adjust for local variation within the Terrestrial Reference Frame. See here for more information.
MIT