convertbng
Fast, accurate WGS84 ⬅️➡️ OSGB36 (OSTN15) conversion, using Python and Rust
Science Score: 67.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
✓DOI references
Found 3 DOI reference(s) in README -
✓Academic publication links
Links to: zenodo.org -
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (14.7%) to scientific vocabulary
Keywords
Keywords from Contributors
Repository
Fast, accurate WGS84 ⬅️➡️ OSGB36 (OSTN15) conversion, using Python and Rust
Basic Info
- Host: GitHub
- Owner: urschrei
- License: other
- Language: Python
- Default Branch: master
- Homepage: https://pypi.python.org/pypi/convertbng
- Size: 108 MB
Statistics
- Stars: 39
- Watchers: 3
- Forks: 7
- Open Issues: 3
- Releases: 59
Topics
Metadata Files
README.md
Description
A 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.
Installation
pip install convertbng
Please use an up-to-date version of pip (8.1.2 as of June 2016)
Supported Python Versions
Simplification supports all currently supported Python versions.
Supported Platforms
- Linux (
manylinux-compatible) x86_64 and aarch64 - macOS Darwin x86_64 and arm64
- Windows 64-bit
Windows Binaries
The 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.
Usage
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.
```python from convertbng.util import convertbng, convertlonlat
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] reslist = convertbng(lons, lats)
convert lists of BNG Eastings and Northings to longitude, latitude
eastings = [easting1, easting2, easting3] northings = [northing1, northing2, northing3] reslisten = convert_lonlat(eastings, northings)
assumes numpy imported as np
lonsnp = np.array(lons) latsnp = np.array(lats) reslistnp = convertbng(lonsnp, lats_np) ```
Cython Module
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.
But I Have a List of Coordinate Pairs
```python 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)
```
But I have Shapely Geometries
```python from convertbng.util import convertetrs89to_ll from shapely.geometry import LineString from shapely.ops import transform from math import isnan from functools import partial
def transformprotectnan(f, xs, ys): # This function protects Shapely against NaN values in the output of the # transform, which would otherwise case a segfault. xst, yst = f(xs, ys) assert not any([isnan(x) for x in xst]), "Transformed xs contains NaNs" assert not any([isnan(y) for y in yst]), "Transformed ys contains NaNs" return xst, yst
convertetrs89tolonlatprotectnan = partial(transformprotectnan, convertetrs89toll)
line = LineString([[651307.003, 313255.686], [651307.004, 313255.687]])
newline = transform(convertetrs89tolonlatprotectnan, line) ```
Available Conversions (AKA I Want To…)
- transform longitudes and latitudes to OSGB36 Eastings and Northings very accurately:
- use
convert_bng()
- use
- transform OSGB36 Eastings and Northings to longitude and latitude, very accurately:
- use
convert_lonlat()
- use
- transform longitudes and latitudes to ETRS89 Eastings and Northings, very quickly (without OSTN15 corrections):
- use
convert_to_etrs89()
- use
- transform ETRS89 Eastings and Northings to ETRS89 longitude and latitude, very quickly (the transformation does not use OSTN15):
- use
convert_etrs89_to_lonlat()
- use
- convert ETRS89 Eastings and Northings to their most accurate real-world representation, using the OSTN15 corrections:
- use
convert_etrs89_to_osgb36()
- use
Provided for completeness:
- transform accurate OSGB36 Eastings and Northings to less-accurate ETRS89 Eastings and Northings:
- use
convert_osgb36_to_etrs89()
- use
Relationship between ETRS89 and WGS84
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.
What CRS Are My Data In
- if you have latitude and longitude coordinates:
- They're probably WGS84. Everything's fine!
- if you got your coordinates from a smartphone or a consumer GPS:
- They're probably WGS84. Everything's fine!
- if you have x and y coordinates, or you got your coordinates from Google Maps or Bing Maps and they look something like
(-626172.1357121646, 6887893.4928337997), or the phrase "Spherical Mercator" is mentioned anywhere:- they're probably in Web Mercator. You must convert them to WGS84 first. Use
convert_epsg3857_to_wgs84([x_coordinates], [y_coordinates])to do so.
- they're probably in Web Mercator. You must convert them to WGS84 first. Use
Accuracy
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
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:
Accuracy of Your Data
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.
Accuracy of the OSTN15 transformation used in this library
- ETRS89 longitude and latitude / Eastings and Northings to OSGB36 conversion agrees with the provided Ordnance Survey test data in 39 of the 40 test coordinates (excluding two coordinates designed to return no data; these correctly fail).
- The only discrepancy – in point
TP31– is 1mm. - OSGB36 to ETRS89 longitude and latitude conversion is accurate to within 8 decimal places, or 1.1mm.
A Note on Ellipsoids
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.
Implementation
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.
Building the binary for local development
- ensure you have Rust 1.x and Cargo installed
- download the Rust extension for your platform from github
- copy the binary into the
convertbngdirectory - run
python setup.py build_ext --inplace
Tests
- install
pytest - run
pytest
License
Citing Convertbng
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}
}
Owner
- Name: Stephan Hügel
- Login: urschrei
- Kind: user
- Location: Dublin
- Company: Trinity College Dublin
- Website: https://scholar.google.com/citations?hl=en&user=usNnd3IAAAAJ&view_op=list_works&sortby=pubdate
- Twitter: urschrei
- Repositories: 55
- Profile: https://github.com/urschrei
Marie Curie research fellow at TCD: smart cities and climate change. Prev: @casa-ucl. I also work on high-performance computational geometry libraries @georust
Citation (CITATION.cff)
cff-version: 1.1.0
message: "If you use this software, please cite it using these metadata."
abstract: "Convertbng: convert WGS84 latitude and longitude to and from ETRS89 and OSGB36 coordinates using the OSTN15 transform"
authors:
-
family-names: "Hügel"
given-names: Stephan
orcid: "https://orcid.org/0000-0003-4379-2450"
title: "Convertbng"
date-released: 2021-12-12
doi: "10.5281/zenodo.5774931"
keywords:
- geo
- gis
- polyline
license: BlueOak-1.0.0
repository-code: "https://github.com/urschrei/convertbng"
version: "0.2.72"
GitHub Events
Total
- Watch event: 1
- Delete event: 13
- Push event: 19
- Pull request event: 29
- Create event: 15
Last Year
- Watch event: 1
- Delete event: 13
- Push event: 19
- Pull request event: 29
- Create event: 15
Committers
Last synced: 9 months ago
Top Committers
| Name | Commits | |
|---|---|---|
| Stephan Hügel | u****i@g****m | 658 |
| dependabot[bot] | 4****] | 68 |
| Joshua Arnott | j****h@s****t | 2 |
| liamato | l****o | 1 |
| Henry Schreiner | H****I@g****m | 1 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 12
- Total pull requests: 86
- Average time to close issues: 5 months
- Average time to close pull requests: 6 days
- Total issue authors: 12
- Total pull request authors: 4
- Average comments per issue: 6.75
- Average comments per pull request: 0.13
- Merged pull requests: 75
- Bot issues: 0
- Bot pull requests: 83
Past Year
- Issues: 0
- Pull requests: 29
- Average time to close issues: N/A
- Average time to close pull requests: about 4 hours
- Issue authors: 0
- Pull request authors: 1
- Average comments per issue: 0
- Average comments per pull request: 0.0
- Merged pull requests: 24
- Bot issues: 0
- Bot pull requests: 29
Top Authors
Issue Authors
- Kostas-Konstantinou (1)
- MichaelClerx (1)
- Yorkshire-Jack (1)
- hawesie (1)
- gremet (1)
- chongyangshi (1)
- snorfalorpagus (1)
- jharrison (1)
- Guymer (1)
- joshuanunn (1)
- ideoma (1)
- EarthSenseOli (1)
Pull Request Authors
- dependabot[bot] (107)
- henryiii (1)
- snorfalorpagus (1)
- liamato (1)
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 1
-
Total downloads:
- pypi 65,335 last-month
- Total docker downloads: 128
- Total dependent packages: 2
- Total dependent repositories: 18
- Total versions: 86
- Total maintainers: 1
pypi.org: convertbng
Fast lon, lat to and from ETRS89 and BNG (OSGB36) using the OS OSTN15 transform via Rust FFI
- Documentation: https://convertbng.readthedocs.io/
- License: # Blue Oak Model License Version 1.0.0 ## Purpose This license gives everyone as much permission to work with this software as possible, while protecting contributors from liability. ## Acceptance In order to receive this license, you must agree to its rules. The rules of this license are both obligations under that agreement and conditions to your license. You must not do anything with this software that triggers a rule that you cannot or will not follow. ## Copyright Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it. ## Notices You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license or a link to <https://blueoakcouncil.org/license/1.0.0>. ## Excuse If anyone notifies you in writing that you have not complied with [Notices](#notices), you can keep your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your license ends immediately. ## Patent Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license. ## Reliability No contributor can revoke this license. ## No Liability ***As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim.***
-
Latest release: 0.7.5
published over 1 year ago
Rankings
Maintainers (1)
Dependencies
- cython * development
- nose * development
- numpy * development
- requests * development
- setuptools * development
- wheel * development
- actions/checkout v2 composite
- actions/download-artifact v2 composite
- actions/upload-artifact v2 composite
- ncipollo/release-action v1 composite
- oprypin/find-latest-tag v1 composite
- pypa/cibuildwheel v2.11.4 composite
- robinraju/release-downloader v1.7 composite
