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
cargo build --release
from the repo rootipython notebook
, and open rust_BNG
.An IPython (sorry, Jupyter) notebook with some benchmarks is here
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 4 – 5 metres, 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.
Add the following to your Cargo.toml
:
lonlat_bng = "*"
The functions exposed by the library are:
lonlat_bng::convert_to_bng
lonlat_bng::convert_to_lonlat
Both functions accept two Array
s of lon, lat coordinates or BNG Eastings and Northings, respectively. Converting vectors to Array
is trivial (see the tests for examples).
convert_bng
is available from PyPI:
pip install convertbng
More information is available in its repository
MIT