Giter VIP home page Giter VIP logo

geofun's Introduction

GeoFun

Library for doing geographic calculations like distance, azimuth and position determination for geodesics and rhumb lines, orthodromes and loxodromes, respectively.

This version makes use of GeographicLib for doing most of the calculations.

This is a C++ package that uses pybind11 to wrap the C++ version of GeographicLib, which makes it faster (~100x) than the pure python version of geographiclib.

Compare:

In [1]: from geofun import geodesic_inverse

In [2]: %timeit geodesic_inverse(52, 4, 28, -16.6)
1.17 µs ± 37 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: from geographiclib.geodesic import Geodesic

In [4]: %timeit Geodesic.WGS84.Inverse(52, 4, 28, -16.6)
107 µs ± 170 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [5]: geodesic_inverse(52, 4, 28, -16.6)
Out[5]: (-139.28471885516532, 3168557.154495447, -152.90624110350674)

In [6]: Geodesic.WGS84.Inverse(52, 4, 28, -16.6)
Out[6]:
{'lat1': 52,
 'lon1': 4.0,
 'lat2': 28,
 'lon2': -16.6,
 'a12': 28.519118381735783,
 's12': 3168557.1544954455,
 'azi1': -139.28471885516532,
 'azi2': -152.90624110350674}

Installing

pip install pygeofun should work without needing to compile anything on Windows, Linux (x86_64, aarch64) and MacOS 13 (x86_64) for python versions 3.9 - 3.12. For other platforms you might need to build the C++ parts. Wheel contributions for other platforms are very welcome.

Building

  • Get poetry if you don't have it
  • Check out the source code: git clone https://github.com/jrversteegh/geofun.git --recurse-submodules
  • Execute poetry build to build the package or poetry install to get a virtual environment to work in. Both require a working modern C++ compiler. GCC 9.4 and MSVC 14.3 were tested. Others may work.

Examples

Some operator abuse was used to mark the difference between geodesic and mercator based operations. + and - are addition and subtraction in the mercator projection (loxodromes) and * and / are addition and subtraction on geodesics (orthodromes). If you object to this, you’re probably right. Any suggestions for a better way are quite welcome.

from geofun import Position, Vector

# Just off Hoek van Holland
org = Position(52.0, 4.0)
nm95 = 95 * 1852.0

# Go west 95 nm to Felixstowe
rmbv = Vector(270.0, nm95)
pos1 = org + rmbv

# Go to the same point using great circle line
gcv = pos1 / org
pos2 = org * gcv

# We should end up at the same location
assert pos1 == pos2

# How disappointing: we managed to gain just 9m by crossing the
# North sea using a great circle :p
assert nm95 - gcv.length == 9.101067085022805, f'Unexpected: {gcv.length}'

print(f'From {org} to {pos1}')
print(f'Rhumb: {rmbv}')
print(f'Great circle: {gcv}')

# Another verification
assert pos1 - org == rmbv
assert pos1 / org == gcv

Another example. Flying from Kennedy Airport to Amsterdam Schiphol Airport and splitting both a great circle and a rhumbline route into segments:

from geofun import Position, Vector

# Both airports
JFK = Position("40°38′23″N 73°46′44″W")
AMS = Position("52°18′00″N 4°45′54″E")

# Loxodromic route:
loxo = (AMS - JFK).split_loxo(JFK, 10)
# Print list of positions and flight vectors
print("\nLoxodrome JFK -> AMS:")
for p1, p2 in zip(loxo[:-1], loxo[1:]):
  print(f"Position: {p1}, vector: {p2 - p1}")
print(f"Destination: {p2}")

# Orthodromic route:
ortho = (AMS / JFK).split_ortho(JFK, 10)
# Print list of positions and flight vectors
print("\nOrthodrome JFK -> AMS:")
for p1, p2 in zip(ortho[:-1], ortho[1:]):
  print(f"Position: {p1}, vector: {p2 / p1}")
print(f"Destination: {p2}")

Classes

Position
  • latitude
  • longitude

Position(latitude: int, longitude: int) -> Position Position in arc seconds.

Position(latitude: float, longitude: float) -> Position Position in arc degrees.

Position(position: str) -> Position Position parsed from string.

Vector
  • azimuth
  • length

Vector(azimuth: float, length: float) -> Vector Polar vector in arc degrees and meters.

Point
  • x
  • y

Point(x: float, y: float) -> Point Point on locally flat coordinate system, x pointing north, y pointing east.

Many operators will work on classes like:

  • Point + Point, adds x and y coordinates of points
  • Point + Vector, offsets point by vector
  • Position + Vector, offsets position by vector along loxodrome
  • Position * Vector, offsets position by vector along orthodrome
  • Position - Position, get loxodromic vector from position to position
  • Position / Position, get orthodromic vector from position to position

Functions

get_version() -> str

Get the library version

geodesic_direct(latitude: float, longitude: float, azimuth: float, distance: float) -> tuple

Get position and final azimuth after moving distance along great circle with starting azimuth

geodesic_inverse(latitude1: float, longitude1: float, latitude2: float, longitude2: float) -> tuple

Get starting azimuth, distance and ending azimuth of great circle between positions

rhumb_direct(latitude: float, longitude: float, azimuth: float, distance: float) -> tuple

Get position and final azimuth after moving distance from starting position at fixed azimuth/along rhumb line

rhumb_inverse(latitude1: float, longitude1: float, latitude2: float, longitude2: float) -> tuple

Get rhumb line azimuth, distance and final azimuth between positions

angle_diff(arg0: numpy.ndarray[numpy.float64], arg1: numpy.ndarray[numpy.float64]) -> object

Signed difference between to angles

angle_mod(arg0: numpy.ndarray[numpy.float64]) -> object

Return angle bound to [0.0, 360.0>

angle_mod_signed(arg0: numpy.ndarray[numpy.float64]) -> object

Return angle bound to [-180.0, 180.0>

geofun's People

Contributors

aljevandam avatar jrversteegh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

geofun's Issues

Is there a way to choose `ellipsoid` when do caculating?

Sometimes I want to use other ellipsoids(such as GRS80), but the current geofun only support WGS84. It can't change the ellipsoid's parameters.

I don't know whether this new feature is hard to be developed.
I will be very happy if any developer reply me : )

More convenient way to use `pygeofun` with `pip`

pip install pygeofun can't run well because this command seems leading to lack of .so or .pyd files.

Pygeofun needs to be built from source(especially geographiclib C++ source code) when implement it in a new machine everytime. Or download pygeofun's Built Distributions from .whl file according to the machine's OS and python's version.
For now, the built distribution list lacks of macOS support and python3.11

I wonder if there will be a more convenient way to use pygeofun. I hope it will become out-of-the-box when pip installed.
Maybe it could automatically build everything in the installing process?

(This Issue's idea came up from OSGeo/PROJ#3855)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.