| Vulnerabilities | |||||
|---|---|---|---|---|---|
| Version | Suggest | Low | Medium | High | Critical |
| 0.7.11 | 0 | 0 | 0 | 0 | 0 |
| 0.7.10 | 0 | 0 | 0 | 0 | 0 |
| 0.7.9 | 0 | 0 | 0 | 0 | 0 |
| 0.7.8 | 0 | 0 | 0 | 0 | 0 |
| 0.7.7 | 0 | 0 | 0 | 0 | 0 |
| 0.7.6 | 0 | 0 | 0 | 0 | 0 |
| 0.7.5 | 0 | 0 | 0 | 0 | 0 |
| 0.7.4 | 0 | 0 | 0 | 0 | 0 |
| 0.7.2 | 0 | 0 | 0 | 0 | 0 |
| 0.7.1 | 0 | 0 | 0 | 0 | 0 |
| 0.7.0 | 0 | 0 | 0 | 0 | 0 |
| 0.6.43 | 0 | 0 | 0 | 0 | 0 |
| 0.6.41 | 0 | 0 | 0 | 0 | 0 |
| 0.6.39 | 0 | 0 | 0 | 0 | 0 |
| 0.6.38 | 0 | 0 | 0 | 0 | 0 |
| 0.6.37 | 0 | 0 | 0 | 0 | 0 |
| 0.6.36 | 0 | 0 | 0 | 0 | 0 |
| 0.6.35 | 0 | 0 | 0 | 0 | 0 |
| 0.6.33 | 0 | 0 | 0 | 0 | 0 |
| 0.6.32 | 0 | 0 | 0 | 0 | 0 |
| 0.6.25 | 0 | 0 | 0 | 0 | 0 |
| 0.6.17 | 0 | 0 | 0 | 0 | 0 |
| 0.6.15 | 0 | 0 | 0 | 0 | 0 |
| 0.6.10 | 0 | 0 | 0 | 0 | 0 |
| 0.6.9 | 0 | 0 | 0 | 0 | 0 |
| 0.6.6 | 0 | 0 | 0 | 0 | 0 |
| 0.6.5 | 0 | 0 | 0 | 0 | 0 |
| 0.6.4 | 0 | 0 | 0 | 0 | 0 |
| 0.6.1 | 0 | 0 | 0 | 0 | 0 |
| 0.5.7 | 0 | 0 | 0 | 0 | 0 |
| 0.5.5 | 0 | 0 | 0 | 0 | 0 |
| 0.5.0 | 0 | 0 | 0 | 0 | 0 |
| 0.4.38 | 0 | 0 | 0 | 0 | 0 |
| 0.4.37 | 0 | 0 | 0 | 0 | 0 |
| 0.4.35 | 0 | 0 | 0 | 0 | 0 |
| 0.4.33 | 0 | 0 | 0 | 0 | 0 |
| 0.4.30 | 0 | 0 | 0 | 0 | 0 |
| 0.4.28 | 0 | 0 | 0 | 0 | 0 |
| 0.4.27 | 0 | 0 | 0 | 0 | 0 |
| 0.4.26 | 0 | 0 | 0 | 0 | 0 |
| 0.4.25 | 0 | 0 | 0 | 0 | 0 |
| 0.4.24 | 0 | 0 | 0 | 0 | 0 |
| 0.4.23 | 0 | 0 | 0 | 0 | 0 |
| 0.4.22 | 0 | 0 | 0 | 0 | 0 |
| 0.4.21 | 0 | 0 | 0 | 0 | 0 |
| 0.4.18 | 0 | 0 | 0 | 0 | 0 |
| 0.4.14 | 0 | 0 | 0 | 0 | 0 |
| 0.4.13 | 0 | 0 | 0 | 0 | 0 |
| 0.4.12 | 0 | 0 | 0 | 0 | 0 |
| 0.4.11 | 0 | 0 | 0 | 0 | 0 |
| 0.4.10 | 0 | 0 | 0 | 0 | 0 |
| 0.4.9 | 0 | 0 | 0 | 0 | 0 |
| 0.4.8 | 0 | 0 | 0 | 0 | 0 |
| 0.4.7 | 0 | 0 | 0 | 0 | 0 |
| 0.4.4 | 0 | 0 | 0 | 0 | 0 |
| 0.4.3 | 0 | 0 | 0 | 0 | 0 |
| 0.4.2 | 0 | 0 | 0 | 0 | 0 |
| 0.4.1 | 0 | 0 | 0 | 0 | 0 |
| 0.4.0 | 0 | 0 | 0 | 0 | 0 |
| 0.3.4 | 0 | 0 | 0 | 0 | 0 |
| 0.3.3 | 0 | 0 | 0 | 0 | 0 |
| 0.3.2 | 0 | 0 | 0 | 0 | 0 |
| 0.3.1 | 0 | 0 | 0 | 0 | 0 |
| 0.3.0 | 0 | 0 | 0 | 0 | 0 |
| 0.2.5 | 0 | 0 | 0 | 0 | 0 |
| 0.2.4 | 0 | 0 | 0 | 0 | 0 |
| 0.2.3 | 0 | 0 | 0 | 0 | 0 |
| 0.1.25 | 0 | 0 | 0 | 0 | 0 |
| 0.1.24 | 0 | 0 | 0 | 0 | 0 |
| 0.1.23 | 0 | 0 | 0 | 0 | 0 |
| 0.1.22 | 0 | 0 | 0 | 0 | 0 |
| 0.1.21 | 0 | 0 | 0 | 0 | 0 |
| 0.1.20 | 0 | 0 | 0 | 0 | 0 |
| 0.1.19 | 0 | 0 | 0 | 0 | 0 |
| 0.1.18 | 0 | 0 | 0 | 0 | 0 |
| 0.1.17 | 0 | 0 | 0 | 0 | 0 |
| 0.1.16 | 0 | 0 | 0 | 0 | 0 |
| 0.1.15 | 0 | 0 | 0 | 0 | 0 |
| 0.1.14 | 0 | 0 | 0 | 0 | 0 |
| 0.1.13 | 0 | 0 | 0 | 0 | 0 |
| 0.1.12 | 0 | 0 | 0 | 0 | 0 |
| 0.1.11 | 0 | 0 | 0 | 0 | 0 |
| 0.1.10 | 0 | 0 | 0 | 0 | 0 |
| 0.1.9 | 0 | 0 | 0 | 0 | 0 |
| 0.1.8 | 0 | 0 | 0 | 0 | 0 |
| 0.1.7 | 0 | 0 | 0 | 0 | 0 |
| 0.1.5 | 0 | 0 | 0 | 0 | 0 |
| 0.1.4 | 0 | 0 | 0 | 0 | 0 |
| 0.1.3 | 0 | 0 | 0 | 0 | 0 |
| 0.1.2 | 0 | 0 | 0 | 0 | 0 |
| 0.1.1 | 0 | 0 | 0 | 0 | 0 |
| 0.1 | 0 | 0 | 0 | 0 | 0 |
0.7.11 - This version is safe to use because it has no known security vulnerabilities at this time. Find out if your coding project uses this component and get notified of any reported security vulnerabilities with Meterian-X Open Source Security Platform
Maintain your licence declarations and avoid unwanted licences to protect your IP the way you intended.
BlueOak-1.0.0 - Blue Oak Model License 1.0.0A utility library for converting decimal WGS84 longitude and latitude coordinates into ETRS89 (EPSG:25830) and/or British National Grid (More correctly: OSGB36, or EPSG:27700) Eastings and Northings, and vice versa.
Conversion is handled by a Rust binary using FFI, and is quite fast. Some benchmarks can be found here.
uv add convertbngpip install convertbngliblonlat_bng and header.h from https://github.com/urschrei/lonlat_bng/releases, and it's in the src/convertbng subdiruv sync --dev
pytest .
Changes in pyx and pxd files, and the Rust library and header will bust the cache, triggering a rebuild when uv commands are run.
Simplification supports all currently supported Python versions.
manylinux-compatible) x86_64 and aarch64The Rust DLL and the Cython extension used by this package have been built with an MSVC toolchain. You shouldn't need to install any additional runtimes in order for the wheel to work, but please open an issue if you encounter any errors.
The functions accept either a sequence (such as a list or numpy array) of longitude or easting values and a sequence of latitude or northing values, or a single longitude/easting value and single latitude/northing value. Note the return type:
"returns a list of two lists containing floats, respectively"
NOTE: Coordinate pairs outside the BNG bounding box, or without OSTN15 coverage will return a result of
[[nan], [nan]], which cannot be mapped. Since transformed coordinates are guaranteed to be returned in the same order as the input, it is trivial to check for this value. Alternatively, ensure your data fall within the bounding box before transforming them:
Longitude:
East: 1.7800
West: -7.5600
Latitude:
North: 60.8400
South: 49.9600
All functions try to be liberal about what containers they accept: list, tuple, array.array, numpy.ndarray, and pretty much anything that has the __iter__ attribute should work, including generators.
from convertbng.util import convert_bng, convert_lonlat
# convert a single value
res = convert_bng(lon, lat)
# convert longitude and latitude to OSGB36 Eastings and Northings using OSTN15 corrections
lons = [lon1, lon2, lon3]
lats = [lat1, lat2, lat3]
res_list = convert_bng(lons, lats)
# convert lists of BNG Eastings and Northings to longitude, latitude
eastings = [easting1, easting2, easting3]
northings = [northing1, northing2, northing3]
res_list_en = convert_lonlat(eastings, northings)
# assumes numpy imported as np
lons_np = np.array(lons)
lats_np = np.array(lats)
res_list_np = convert_bng(lons_np, lats_np)The Rust library produces the following results when round-tripping the 40 OSTN15 test points (only differences are shown)
| Test Point | Input OSGB36 E (m) | Input OSGB36 N (m) | Lon diff (°) | Lat diff (°) | E diff (m) | N diff (m) |
|---|---|---|---|---|---|---|
| TP27 | 319188.434 | 670947.534 | — | — | — | +0.001 |
| TP31 | 9587.909 | 899448.996 | +6×10⁻⁸ | -3×10⁻⁸ | +0.003 | -0.004 |
| TP32 | 71713.132 | 938516.404 | +2×10⁻⁸ | -1×10⁻⁸ | +0.001 | -0.002 |
| TP37 | 180862.461 | 1029604.114 | — | — | — | -0.001 |
| TP38 | 421300.525 | 1072147.239 | — | — | — | -0.001 |
If you're comfortable with restricting yourself to NumPy f64 arrays, you may use the Cython functions instead. These are identical to those listed below, but performance on large datasets is better. They are selected by changing the import statement
from convertbng.util import to
from convertbng.cutil import
The conversion functions will accept most sequences which implement __iter__, as above (list, tuple, float, array.array, numpy.ndarray), but will always return NumPy f64 ndarray. In addition, you must ensure that your inputs are float, f64, or d in the case of array.array.
coords = [[1.0, 2.0], [3.0, 4.0]]
a, b = list(zip(*coords))
# a is (1.0, 3.0)
# b is (2.0, 4.0)from convertbng.util import convert_etrs89_to_ll
from shapely.geometry import LineString
from shapely.ops import transform
from math import isnan
from functools import partial
def transform_protect_nan(f, xs, ys):
# This function protects Shapely against NaN values in the output of the
# transform, which would otherwise case a segfault.
xs_t, ys_t = f(xs, ys)
assert not any([isnan(x) for x in xs_t]), "Transformed xs contains NaNs"
assert not any([isnan(y) for y in ys_t]), "Transformed ys contains NaNs"
return xs_t, ys_t
convert_etrs89_to_lonlat_protect_nan = partial(transform_protect_nan, convert_etrs89_to_ll)
line = LineString([[651307.003, 313255.686], [651307.004, 313255.687]])
new_line = transform(convert_etrs89_to_lonlat_protect_nan, line)convert_bng()
convert_lonlat()
convert_to_etrs89()
convert_etrs89_to_lonlat()
convert_etrs89_to_osgb36()
Provided for completeness:
convert_osgb36_to_etrs89()
From Transformations and OSGM02™ User guide, p7. Emphasis mine.
[…] ETRS89 is a precise version of the better known WGS84 reference system optimised for use in Europe; however, for most purposes it can be considered equivalent to WGS84. Specifically, the motion of the European continental plate is not apparent in ETRS89, which allows a fixed relationship to be established between this system and Ordnance Survey mapping coordinate systems. Additional precise versions of WGS84 are currently in use, notably ITRS; these are not equivalent to ETRS89. The difference between ITRS and ETRS89 is in the order of 0.25 m (in 1999), and growing by 0.025 m per year in UK and Ireland. This effect is only relevant in international scientific applications. For all navigation, mapping, GIS, and engineering applications within the tectonically stable parts of Europe (including UK and Ireland), the term ETRS89 should be taken as synonymous with WGS84.
In essence, this means that anywhere you see ETRS89 in this README, you can substitute WGS84.
(-626172.1357121646, 6887893.4928337997), or the phrase "Spherical Mercator" is mentioned anywhere:
convert_epsg3857_to_wgs84([x_coordinates], [y_coordinates]) to do so.convert_bng and convert_lonlat first use the standard seven-step Helmert transform to convert coordinates. This is fast, but not particularly accurate – it can introduce positional error up to approximately 5 metres. For most applications, this is not of particular concern – the input data (especially those originating with smartphone GPS) probably exceed this level of error in any case. In order to adjust for this, the OSTN15 adjustments for the kilometer-grid the ETRS89 point falls in are retrieved, and a linear interpolation to give final, accurate coordinates is carried out. This process happens in reverse for convert_lonlat.
OSTN15 data are used for highly accurate conversions from ETRS89 latitude and longitude, or ETRS89 Eastings and Northings to OSGB36 Eastings and Northings, and vice versa. These data will usually have been recorded using the National GPS Network:
Conversion of your coordinates using OSTN15 transformations will be accurate, but if you're using consumer equipment, or got your data off the web, be aware that you're converting coordinates which probably weren't accurately recorded in the first place. That's because accurate surveying is difficult.
TP31– is 1mm.WGS84 and ETRS89 coordinates use the GRS80 ellipsoid, whereas OSGB36 uses the Airy 1830 ellipsoid, which provides a regional best fit for Britain. Positions for coordinates in Great Britain can differ by over 100m as a result. It is thus inadvisable to attempt calculations using mixed ETRS89 and OSGB36 coordinates.
The main detail of interest is the FFI interface between Python and Rust, the Python side of which can be found in util.py (the ctypes implementation), cutil.pyx (the cython implementation), and the Rust side of which can be found in ffi.rs.
The ctypes library expects C-compatible data structures, which we define in Rust (see above). We then define methods which allow us to receive, safely access, return, and free data across the FFI boundary.
Finally, we link the Rust conversion functions from util.py again. Note the errcheck assignments, which convert the FFI-compatible ctypes data structures to tuple lists.
convertbng directorypython setup.py build_ext --inplace
pytest
pytest
If Convertbng has been significant in your research, and you would like to acknowledge the project in your academic publication, we suggest citing it as follows (example in APA style, 7th edition):
Hügel, S. (2021). Convertbng (Version X.Y.Z) [Computer software]. https://doi.org/10.5281/zenodo.5774931
In Bibtex format:
@software{Hugel_Convertbng_2021,
author = {Hügel, Stephan},
doi = {10.5281/zenodo.5774931},
license = {MIT},
month = {12},
title = {{Convertbng}},
url = {https://github.com/urschrei/convertbng},
version = {X.Y.Z},
year = {2021}
}