### Conda-forge Build Setup Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt Commands to set up a conda build environment. This includes creating and activating a new conda environment, installing build tools, and preparing the feedstock. ```bash conda remove -y -n build --all conda create -y -n build conda activate build conda install -y conda-build conda-verify conda-forge-pinning ``` -------------------------------- ### Install GeographicLib from Source Archive Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/package.md Install the GeographicLib Python package by downloading and installing a source archive using pip. ```sh pip install geographiclib-2.0.tar.gz ``` -------------------------------- ### Install Build Tools Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt Install necessary tools for building and uploading Python packages. These commands ensure you have the latest versions of build, twine, sphinx, and setuptools. ```bash python -m pip install --upgrade build python -m pip install --upgrade twine python -m pip install --upgrade sphinx python -m pip install --upgrade sdist python -m pip install --upgrade setuptools ``` -------------------------------- ### Test Conda Package Installation Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt Install the newly built conda package into a test environment and verify its installation by checking the version of GeoConvert. ```bash conda deactivate conda remove -y -n geog-test --all conda create -y -n geog-test ~/miniconda3/envs/build/conda-bld/linux-64/geographiclib-$VERSION-*.tar.bz2 conda activate geog-test type GeoConvert GeoConvert --version ``` -------------------------------- ### Install GeographicLib Python Package Source: https://github.com/geographiclib/geographiclib-python/blob/main/distrib-Python/00README.md Use this command to install the GeographicLib Python package from a local wheel file. Ensure you have the wheel file downloaded. ```bash python -m pip install [WHEEL-FILE] ``` -------------------------------- ### Get position along GeodesicLine by metric distance Source: https://context7.com/geographiclib/geographiclib-python/llms.txt This example demonstrates how to find a point along a geodesic line at a specific metric distance from the origin using the Position method. It calculates and prints the latitude and longitude of points at 0, 500, 1000, 2000, and 5000 km along a line starting in London heading east. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 line = geod.Line(51.5, -0.1, 90) # London, heading due East for km in [0, 500, 1000, 2000, 5000]: g = line.Position(km * 1e3, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) print(f"{km:5d} km → ({g['lat2']:.5f}°, {g['lon2']:.5f}°)") ``` -------------------------------- ### Install GeographicLib Python Package Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/package.md Use this command to install the GeographicLib Python package using pip. ```sh pip install geographiclib ``` -------------------------------- ### Run GeographicLib Unit Tests Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/package.md Execute the unit tests for the GeographicLib Python package to verify a successful installation. ```sh python -m unittest geographiclib.test.test_geodesic ``` -------------------------------- ### Get position along GeodesicLine by arc length Source: https://context7.com/geographiclib/geographiclib-python/llms.txt This example shows how to use ArcPosition to find points along a geodesic line based on arc length. It calculates points at equal 1-degree arc intervals between two endpoints and prints their latitude and longitude. ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 line = geod.InverseLine(40.1, 116.6, 37.6, -122.4, Geodesic.LATITUDE | Geodesic.LONGITUDE) da = 1.0 # 1° arc steps ≈ 60 NM n = int(math.ceil(line.a13 / da)) da = line.a13 / n # exact equal subdivision print("latitude longitude") for i in range(n + 1): g = line.ArcPosition(da * i, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) print(f"{g['lat2']:9.5f} {g['lon2']:10.5f}") ``` -------------------------------- ### Create GeodesicLine from two endpoints Source: https://context7.com/geographiclib/geographiclib-python/llms.txt This example demonstrates creating a GeodesicLine from two known endpoints (latitude and longitude). It then calculates and prints waypoints every 1000 km along the geodesic path, including distance, latitude, longitude, and azimuth. ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 # Waypoints every 1000 km: Beijing Airport → San Francisco Airport line = geod.InverseLine(40.1, 116.6, 37.6, -122.4) ds = 1_000e3 n = int(math.ceil(line.s13 / ds)) print(f"{ 'dist (km)':>10} {'lat':>9} {'lon':>10} {'azi':>9}") for i in range(n + 1): s = min(ds * i, line.s13) g = line.Position(s, Geodesic.STANDARD | Geodesic.LONG_UNROLL) print(f"{g['s12']/1e3:10.0f} {g['lat2']:9.5f} {g['lon2']:10.5f} {g['azi2']:9.5f}") ``` -------------------------------- ### GeodesicLine Constructor: Create a Line Object Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Initializes a GeodesicLine object from a starting point (lat1, lon1) and an initial azimuth (azi1). The 'caps' bitmask determines which quantities are pre-computed for efficient querying of points along the geodesic. ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 # Geodesic from JFK (40.6N, 73.8W) toward LHR (51.6N, 0.5W) line = geod.Line(40.6, -73.8, geod.Inverse(40.6, -73.8, 51.6, -0.5)['azi1']) ``` -------------------------------- ### Initialize Geodesic Object (WGS84) Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Defines the WGS84 ellipsoid for geodesic calculations. This is a common starting point for most geodesic operations. ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 # define the WGS84 ellipsoid ``` -------------------------------- ### Add vertices to a PolygonArea object by coordinates Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Use AddPoint to append vertices to a polygon. The first call sets the starting point. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 p = geod.Polygon() # A roughly square patch around the North Sea for lat, lon in [(55, 0), (55, 10), (60, 10), (60, 0)]: p.AddPoint(lat, lon) num, perim, area = p.Compute() print(f"Perimeter: {perim/1e3:.1f} km") print(f"Area : {area/1e6:.1f} km²") ``` -------------------------------- ### Add vertices to a PolygonArea object Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Use AddPoint to append vertices to a polygon. The first call sets the starting point. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 p = geod.Polygon() antarctica = [ (-63.1, -58), (-72.9, -74), (-71.9, -102), (-74.9, -102), (-74.3, -131), (-77.5, -163), (-77.4, 163), (-71.7, 172), (-65.9, 140), (-65.7, 113), (-66.6, 88), (-66.9, 59), (-69.8, 25), (-70.0, -4), (-71.0, -14), (-77.3, -33), (-77.9, -46), (-74.7, -61), ] for lat, lon in antarctica: p.AddPoint(lat, lon) num, perim, area = p.Compute() print(f"Vertices : {num}") print(f"Perimeter: {perim:.3f} m") # ~16 831 067.893 m print(f"Area : {area:.1f} m²") # ~13 662 703 680 020.1 m² ``` -------------------------------- ### Create GeodesicLine with DirectLine Source: https://context7.com/geographiclib/geographiclib-python/llms.txt This snippet shows how to create a GeodesicLine using DirectLine, which defines the line by a starting point, an initial azimuth, and a distance. It then prints the total arc length and metric distance to the endpoint, and the coordinates of the midpoint. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Line starting at equator heading northeast, endpoint 5000 km away line = geod.DirectLine(0, 0, 45, 5_000e3) print(f"a13={line.a13:.6f}° s13={line.s13/1e3:.3f} km") # Midpoint mid = line.Position(line.s13 / 2, Geodesic.STANDARD) print(f"Midpoint: ({mid['lat2']:.6f}°, {mid['lon2']:.6f}°)") ``` -------------------------------- ### PolygonArea.AddPoint Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Appends a vertex to the polygon accumulator using latitude and longitude coordinates. The first call initializes the polygon's starting point. ```APIDOC ## PolygonArea.AddPoint — add a vertex by coordinates `AddPoint(lat, lon)` appends a vertex to the accumulator. The first call seeds both the starting point and the running point; subsequent calls measure the geodesic edge from the previous vertex. ``` -------------------------------- ### Geodesic Direct: Calculate Destination Point and Azimuths Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Solves the direct geodesic problem, calculating the destination point (lat2, lon2) and forward azimuth (azi2) given a starting point, initial azimuth, and distance. Can also return reduced length (m12) and geodesic scale (M12). ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Point 20 000 km SW of Perth, Australia g = geod.Direct(-32.06, 115.74, 225, 20_000e3) print(f"Destination: ({g['lat2']:.8f}°, {g['lon2']:.8f}°)") # Destination: (32.11195529°, -63.95925278°) # Request reduced length and geodesic scale in addition to STANDARD g = geod.Direct(0, 0, 45, 1_000_000, Geodesic.STANDARD | Geodesic.REDUCEDLENGTH | Geodesic.GEODESICSCALE) print(f"lat2={g['lat2']:.6f} lon2={g['lon2']:.6f}") print(f"m12={g['m12']:.3f} m M12={g['M12']:.9f}") ``` -------------------------------- ### Set GeodesicLine endpoint by distance or arc Source: https://context7.com/geographiclib/geographiclib-python/llms.txt This example demonstrates how to set the reference endpoint of a GeodesicLine after its creation using SetDistance or SetArc. It shows how to set the endpoint by a metric distance and then by an arc length, printing the corresponding values. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 line = geod.Line(0, 0, 60) # equator heading NE, no endpoint yet line.SetDistance(10_000e3) # set endpoint 10 000 km away print(f"arc to endpoint: {line.a13:.6f}°") # Alternatively use arc length directly line.SetArc(90) # 90° of arc print(f"metric distance to endpoint: {line.s13/1e3:.3f} km") ``` -------------------------------- ### Direct Geodesic Calculation Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Determines the position of a second point given a starting point, an initial azimuth, and a distance along the geodesic. Useful for navigation and pathfinding. ```python g = geod.Direct(-32.06, 115.74, 225, 20000e3) print("The position is ({:.8f}, {:.8f}).".format(g['lat2'],g['lon2'])) ``` -------------------------------- ### Get Ellipsoid Parameters Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Retrieves the semi-major axis (a) and the inverse of the flattening (1/f) for a defined ellipsoid. Useful for understanding ellipsoid properties. ```python geod.a, 1/geod.f ``` -------------------------------- ### Geodesic.Direct Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Solves the direct geodesic problem. Starting from a point (lat1, lon1) with an initial azimuth (azi1) and traveling a specified distance (s12), it computes the destination point (lat2, lon2) and the forward azimuth (azi2). Additional quantities like reduced length and geodesic scale can be requested via the 'outmask' parameter. ```APIDOC ## Geodesic.Direct — solve the direct geodesic problem `Direct(lat1, lon1, azi1, s12, outmask=STANDARD)` starts at `(lat1, lon1)`, travels along azimuth `azi1` for `s12` meters, and returns the destination point together with the forward azimuth `azi2` and arc length `a12`. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Point 20 000 km SW of Perth, Australia g = geod.Direct(-32.06, 115.74, 225, 20_000e3) print(f"Destination: ({g['lat2']:.8f}°, {g['lon2']:.8f}°)") # Destination: (32.11195529°, -63.95925278°) # Request reduced length and geodesic scale in addition to STANDARD g = geod.Direct(0, 0, 45, 1_000_000, Geodesic.STANDARD | Geodesic.REDUCEDLENGTH | Geodesic.GEODESICSCALE) print(f"lat2={g['lat2']:.6f} lon2={g['lon2']:.6f}") print(f"m12={g['m12']:.3f} m M12={g['M12']:.9f}") ``` ``` -------------------------------- ### Geodesic.DirectLine Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Creates a GeodesicLine whose reference point is set by a starting point, an initial azimuth, and a distance. It pre-populates the line's total distance (s13) and arc length (a13) to the endpoint. ```APIDOC ## Geodesic.DirectLine — GeodesicLine with endpoint set by distance `DirectLine(lat1, lon1, azi1, s12, caps=STANDARD|DISTANCE_IN)` creates a `GeodesicLine` whose reference point 3 is set to the point at metric distance `s12` from the start, pre-populating `line.s13` and `line.a13`. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Line starting at equator heading northeast, endpoint 5000 km away line = geod.DirectLine(0, 0, 45, 5_000e3) print(f"a13={line.a13:.6f}° s13={line.s13/1e3:.3f} km") # Midpoint mid = line.Position(line.s13 / 2, Geodesic.STANDARD) print(f"Midpoint: ({mid['lat2']:.6f}°, {mid['lon2']:.6f}°)") ``` ``` -------------------------------- ### Compute polygon perimeter and area Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Call Compute to finalize the polygon and get its perimeter and area. Additional points can be added after Compute is called. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 p = geod.Polygon() for lat, lon in [(0, 0), (0, 1), (1, 1), (1, 0)]: p.AddPoint(lat, lon) num, perim, area = p.Compute(reverse=False, sign=True) print(f"{num} pts perim={perim/1e3:.3f} km area={area/1e6:.3f} km²") # Clockwise traversal returns negative area with sign=True p.Clear() for lat, lon in [(0, 0), (1, 0), (1, 1), (0, 1)]: # reversed order p.AddPoint(lat, lon) num, perim, area_cw = p.Compute(reverse=False, sign=True) print(f"Clockwise area: {area_cw/1e6:.3f} km²") # negative ``` -------------------------------- ### Geodesic.Line Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Creates a GeodesicLine object for efficient computation of multiple points along a geodesic. It takes a starting point (lat1, lon1) and an initial azimuth (azi1). The 'caps' bitmask determines which quantities are pre-computed and available for querying. ```APIDOC ## Geodesic.Line — create a GeodesicLine from a start point and azimuth `Line(lat1, lon1, azi1, caps=STANDARD|DISTANCE_IN)` creates a `GeodesicLine` that can be queried for any number of points along the geodesic starting at `(lat1, lon1)` with initial azimuth `azi1`. The `caps` bitmask controls which quantities are pre-computed and can be returned. ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 # Geodesic from JFK (40.6N, 73.8W) toward LHR (51.6N, 0.5W) line = geod.Line(40.6, -73.8, geod.Inverse(40.6, -73.8, 51.6, -0.5)['azi1']) ``` -------------------------------- ### Inverse Geodesic Calculation Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Calculates the distance and other geodesic parameters between two points using their latitude and longitude. Requires defining the start and end points. ```python g = geod.Inverse(-41.32, 174.81, 40.96, -5.50) print("The distance is {:.3f} m.".format(g['s12'])) ``` -------------------------------- ### Build and Deploy Package Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt Commands to build the package using 'make package' and deploy it to PyPI using 'make deploy-package'. Twine is used for the deployment. ```bash make package make deploy-package ``` -------------------------------- ### Geodesic Constructor: WGS84 and Custom Ellipsoids Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Demonstrates how to instantiate the Geodesic class using the pre-built WGS84 singleton or by defining a custom ellipsoid with its semi-major axis (a) and flattening (f). ```python from geographiclib.geodesic import Geodesic # Use the standard WGS84 ellipsoid geod = Geodesic.WGS84 print(geod.a, 1 / geod.f) # 6378137.0 298.257223563 # Custom ellipsoid: the International (Hayford 1924) ellipsoid intl = Geodesic(6_378_388, 1 / 297.0) print(intl.a, 1 / intl.f) # 6378388 297.0 ``` -------------------------------- ### Push Release Branch and Commit Changes Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt Create a new git branch for the release, commit changes, push the branch, and commit the rerendered feedstock changes. ```bash git checkout -b v$VERSION commit changes git push --set-upstream cffk v$VERSION conda deactivate conda activate build conda smithy rerender commit changes with git commit -m "MNT: Re-rendered with conda-build... git push --set-upstream cffk v$VERSION ``` -------------------------------- ### Preview polygon changes with TestPoint and TestEdge Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Use TestPoint and TestEdge to preview the perimeter and area if a vertex or edge were added, without modifying the polygon. The polygon remains unchanged until AddPoint or AddEdge is called. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 p = geod.Polygon() p.AddPoint(0, 0) p.AddPoint(0, 1) p.AddPoint(1, 1) # Preview area if we add (1, 0) as the closing vertex num, perim, area = p.TestPoint(1, 0) print(f"Preview: {num} pts area={area/1e6:.3f} km²") # The polygon is unchanged — add the point for real p.AddPoint(1, 0) num, perim, area = p.Compute() print(f"Final : {num} pts area={area/1e6:.3f} km²") ``` -------------------------------- ### Configure Python Files Source: https://github.com/geographiclib/geographiclib-python/blob/main/geographiclib/CMakeLists.txt Copies Python source and test files using CMake's configure_file command. This ensures that the correct versions of these files are used during the build process. ```cmake configure_file (__init__.py.in __init__.py @ONLY) foreach (f ${PYTHON_FILES} ${TEST_FILES}) configure_file (${f} ${f} COPYONLY) endforeach () ``` -------------------------------- ### Initialize Geodesic Object (Custom Ellipsoid) Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Constructs a Geodesic object for a custom ellipsoid using its semi-major axis and flattening. Use when WGS84 or other predefined ellipsoids are not suitable. ```python geod = Geodesic(6378388, 1/297.0) # the international ellipsoid ``` -------------------------------- ### Build Package with Conda Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt Build the geographiclib package using conda-build within the prepared build environment. The package will be located in the conda-build directory. ```bash conda build recipe --variant-config-file $CONDA_PREFIX/conda_build_config.yaml ``` -------------------------------- ### Sample GeodesicLine every 500 km Source: https://context7.com/geographiclib/geographiclib-python/llms.txt This snippet shows how to sample points along a geodesic line at a fixed interval of 500 km. It iterates through a predefined number of intervals and prints the distance, latitude, and longitude of each sampled point. ```python ds = 500e3 for i in range(13): g = line.Position(ds * i, Geodesic.STANDARD | Geodesic.LONG_UNROLL) print(f"{g['s12']/1e3:8.0f} km " f"lat={g['lat2']:7.4f}° lon={g['lon2']:9.4f}°") ``` -------------------------------- ### Rerender Conda Feedstock Source: https://github.com/geographiclib/geographiclib-python/blob/main/HOWTO-RELEASE.txt After creating a new release branch, rerender the conda feedstock using conda-smithy to update it with the latest build configurations. ```bash conda deactivate conda activate build conda install -y -c conda-forge conda-smithy conda smithy rerender ``` -------------------------------- ### Geodesic Constructor Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Constructs an ellipsoid with specified equatorial radius 'a' and flattening 'f'. The Geodesic.WGS84 singleton is pre-built for the standard GPS reference ellipsoid. Raises ValueError for non-positive or non-finite semi-axes. ```APIDOC ## Geodesic — constructor `Geodesic(a, f)` constructs an ellipsoid with equatorial radius `a` (meters) and flattening `f`. The convenience singleton `Geodesic.WGS84` is pre-built from `a = 6 378 137 m` and `f = 1/298.257 223 563`. Raises `ValueError` if either semi-axis is non-positive or non-finite. ```python from geographiclib.geodesic import Geodesic # Use the standard WGS84 ellipsoid geod = Geodesic.WGS84 print(geod.a, 1 / geod.f) # 6378137.0 298.257223563 # Custom ellipsoid: the International (Hayford 1924) ellipsoid intl = Geodesic(6_378_388, 1 / 297.0) print(intl.a, 1 / intl.f) # 6378388 297.0 ``` ``` -------------------------------- ### Add a vertex to a PolygonArea by azimuth and distance Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Use AddEdge to extend the polygon from the current vertex by traveling a specified distance at a given azimuth. The first vertex must be set with AddPoint. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 p = geod.Polygon() # Square of ~100 km sides starting at (45°N, 10°E) p.AddPoint(45, 10) for azi in [0, 90, 180, 270]: # N → E → S → W p.AddEdge(azi, 100e3) num, perim, area = p.Compute() print(f"Vertices : {num}") print(f"Perimeter: {perim/1e3:.3f} km") print(f"Area : {area/1e6:.3f} km²") ``` -------------------------------- ### PolygonArea.TestPoint / TestEdge Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Non-destructively previews the polygon's perimeter and area if a new vertex or edge were added, without modifying the polygon's state. ```APIDOC ## PolygonArea.TestPoint / TestEdge — non-destructive area preview `TestPoint(lat, lon)` and `TestEdge(azi, s)` compute what the polygon's perimeter and area *would be* if the specified vertex/edge were added, without actually modifying the polygon. ``` -------------------------------- ### Geodesic Inverse: Calculate Distance and Azimuths Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Solves the inverse geodesic problem between two points, calculating the shortest path distance (s12) and azimuths (azi1, azi2). Optionally requests geodesic area (S12) or only the distance. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Distance and azimuths: Wellington, NZ → Salamanca, Spain g = geod.Inverse(-41.32, 174.81, 40.96, -5.50) print(f"Distance : {g['s12']:.3f} m") # 19959679.267 m print(f"Azimuth 1: {g['azi1']:.6f}°") # 161.067670° print(f"Azimuth 2: {g['azi2']:.6f}°") # 18.825195° # Also request the geodesic area (area between geodesic and equator) g = geod.Inverse(40.6, -73.8, 51.6, -0.5, Geodesic.STANDARD | Geodesic.AREA) print(f"Area S12 : {g['S12']:.1f} m²") # 40041368848742.5 m² # Request only distance (skip azimuth computation) g = geod.Inverse(-41.32, 174.81, 40.96, -5.50, Geodesic.DISTANCE) print(f"Distance : {g['s12']:.3f} m") # 19959679.267 m ``` -------------------------------- ### Pylint Linting Target Source: https://github.com/geographiclib/geographiclib-python/blob/main/geographiclib/CMakeLists.txt Sets up a custom CMake target named 'lint' that uses Pylint to check Python code quality. Various Pylint options are configured to enforce specific coding standards and identify potential issues. ```cmake find_program (LINT pylint) if (LINT) set (INDENT " ") add_custom_target (lint ${LINT} --max-attributes=36 --max-module-lines=1295 --max-branches=34 --max-args=15 --max-locals=76 --max-statements=175 --max-public-methods=34 --min-public-methods=0 --min-similarity-lines=9 --max-nested-blocks=10 --max-positional-arguments=16 --argument-naming-style=any --attr-naming-style=any --method-naming-style=any --variable-naming-style=any --indent-string=${INDENT} # C0321 multiple statements on one line (needed for brevity) # C0325 unnecessary parens after 'not' keyword (needed for clarity) # C0415 import outside toplevel (needed because of # Geodesic+ GeodesicLine interdependency) # R0124 comparison with self (needed for nan test) # R0401 Cyclic import # W0212 access to a protected member -d C0321,C0325,C0415,R0124,R0401,W0212 __init__.py ${PYTHON_FILES} ${TEST_FILES} COMMENT "Linting with ${LINT}") endif () ``` -------------------------------- ### Area Calculation with Output Mask Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Computes the area of a polygon defined by a geodesic path and the equator. Demonstrates setting the output mask to include area calculations. ```python g = geod.Inverse(40.6, -73.8, 51.6, -0.5, Geodesic.AREA) print("The area is {:.1f} m^2".format(g['S12'])) ``` -------------------------------- ### Compute Geodesic Waypoints (Arc Intervals) Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Computes waypoints along a geodesic parameterized by arc length, useful for plotting smooth geodesic lines. Uses ArcPosition for spacing based on spherical arc length. ```python l = geod.InverseLine(40.1, 116.6, 37.6, -122.4, Geodesic.LATITUDE | Geodesic.LONGITUDE) da = 1; n = int(math.ceil(l.a13 / da)); da = l.a13 / n for i in range(n + 1): if i == 0: print("latitude longitude") a = da * i g = l.ArcPosition(a, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) print("{:.5f} {:.5f}".format(g['lat2'], g['lon2'])) ``` -------------------------------- ### Control output fields with outmask/caps flags Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Use the outmask (or caps) bitmask to specify which fields Geodesic and GeodesicLine methods should calculate and return, optimizing computation. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Request only distance — skip azimuth and arc computations g = geod.Inverse(48.8566, 2.3522, 51.5074, -0.1278, Geodesic.DISTANCE) print(f"Paris → London: {g['s12']/1e3:.3f} km") # ~341.549 km # All available outputs g = geod.Direct(0, 0, 45, 1_000_000, Geodesic.ALL) keys = ['lat2', 'lon2', 'azi2', 's12', 'a12', 'm12', 'M12', 'M21', 'S12'] for k in keys: print(f" {k:4s} = {g[k]}") # GeodesicLine with only lat/lon capability (minimal memory, fast arc stepping) line = geod.InverseLine(0, 0, 10, 10, Geodesic.LATITUDE | Geodesic.LONGITUDE) g = line.ArcPosition(line.a13 / 2, Geodesic.LATITUDE | Geodesic.LONGITUDE) print(f"Midpoint: ({g['lat2']:.5f}°, {g['lon2']:.5f}°)") ``` -------------------------------- ### PolygonArea.AddEdge Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Extends the polygon from the current vertex by traveling a specified distance at a given azimuth. Requires the first vertex to be set using AddPoint. ```APIDOC ## PolygonArea.AddEdge — add a vertex by azimuth and distance `AddEdge(azi, s)` extends the polygon from the current vertex by traveling `s` meters at azimuth `azi`. The first vertex must already have been set via `AddPoint`. ``` -------------------------------- ### Geodesic.Inverse Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Solves the inverse geodesic problem. Given two points (lat1, lon1) and (lat2, lon2) on the ellipsoid, it computes the geodesic connecting them and returns a dictionary with geodesic properties like distance (s12) and azimuths (azi1, azi2). The 'outmask' parameter controls which quantities are computed and returned. ```APIDOC ## Geodesic.Inverse — solve the inverse geodesic problem Given two points on the ellipsoid, `Inverse(lat1, lon1, lat2, lon2, outmask=STANDARD)` computes the geodesic (shortest path) connecting them and returns a dict containing at minimum `lat1`, `lon1`, `azi1`, `lat2`, `lon2`, `azi2`, `s12` (distance in meters), and `a12` (arc length in degrees). ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 # Distance and azimuths: Wellington, NZ → Salamanca, Spain g = geod.Inverse(-41.32, 174.81, 40.96, -5.50) print(f"Distance : {g['s12']:.3f} m") # 19959679.267 m print(f"Azimuth 1: {g['azi1']:.6f}°") # 161.067670° print(f"Azimuth 2: {g['azi2']:.6f}°") # 18.825195° # Also request the geodesic area (area between geodesic and equator) g = geod.Inverse(40.6, -73.8, 51.6, -0.5, Geodesic.STANDARD | Geodesic.AREA) print(f"Area S12 : {g['S12']:.1f} m²") # 40041368848742.5 m² # Request only distance (skip azimuth computation) g = geod.Inverse(-41.32, 174.81, 40.96, -5.50, Geodesic.DISTANCE) print(f"Distance : {g['s12']:.3f} m") # 19959679.267 m ``` ``` -------------------------------- ### Output mask (outmask / caps) flags Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Controls which fields are calculated and returned by Geodesic and GeodesicLine methods. Combining flags with '|' focuses computation on required outputs. ```APIDOC ## Output mask (`outmask` / `caps`) flags All `Geodesic` and `GeodesicLine` methods accept an optional `outmask` (or `caps`) bitmask that controls which fields are calculated and returned. Combining flags with `|` keeps computation focused on only what is needed. ``` -------------------------------- ### Compute Geodesic Waypoints (Distance Intervals) Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Calculates intermediate points (waypoints) along a geodesic at specified distance intervals. Includes handling for longitude wrapping using Geodesic.LONG_UNROLL. ```python l = geod.InverseLine(40.1, 116.6, 37.6, -122.4) ds = 1000e3; n = int(math.ceil(l.s13 / ds)) for i in range(n + 1): if i == 0: print("distance latitude longitude azimuth") s = min(ds * i, l.s13) g = l.Position(s, Geodesic.STANDARD | Geodesic.LONG_UNROLL) print("{:.0f} {:.5f} {:.5f} {:.5f}".format( g['s12'], g['lat2'], g['lon2'], g['azi2'])) ``` -------------------------------- ### PolygonArea.Compute Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Finalizes the polygon by adding the closing edge internally and returns the number of vertices, perimeter in meters, and area in square meters. The polygon can still be modified after calling Compute. ```APIDOC ## PolygonArea.Compute — finalize the polygon `Compute(reverse=False, sign=True)` closes the polygon (adds the closing edge internally), then returns `(num_vertices, perimeter_m, area_m2)`. Additional points can still be added after calling `Compute`. ``` -------------------------------- ### Geodesic.Polygon Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Creates a PolygonArea object associated with the geodesic instance. When initialized with polyline=True, it calculates only the perimeter, returning NaN for the area. ```APIDOC ## Geodesic.Polygon — create a PolygonArea object `Polygon(polyline=False)` returns a `PolygonArea` instance attached to the geodesic. When `polyline=True` only the perimeter is accumulated (area is `nan`). ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 ``` -------------------------------- ### Geodesic.InverseLine Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Creates a GeodesicLine from two endpoints by solving the inverse problem. It pre-sets the total distance (s13) and arc length (a13) to the far endpoint, making it ideal for calculating equally-spaced waypoints. ```APIDOC ## Geodesic.InverseLine — create a GeodesicLine from two endpoints `InverseLine(lat1, lon1, lat2, lon2, caps=STANDARD|DISTANCE_IN)` first solves the inverse problem to determine the azimuth, then returns a `GeodesicLine` with `s13` and `a13` pre-set to the total distance/arc to the far endpoint. Ideal for computing equally-spaced waypoints between two known positions. ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 # Waypoints every 1000 km: Beijing Airport → San Francisco Airport line = geod.InverseLine(40.1, 116.6, 37.6, -122.4) ds = 1_000e3 n = int(math.ceil(line.s13 / ds)) print(f"{'dist (km)':>10} {'lat':>9} {'lon':>10} {'azi':>9}") for i in range(n + 1): s = min(ds * i, line.s13) g = line.Position(s, Geodesic.STANDARD | Geodesic.LONG_UNROLL) print(f"{g['s12']/1e3:10.0f} {g['lat2']:9.5f} {g['lon2']:10.5f} {g['azi2']:9.5f}") # dist (km) lat lon azi # 0 40.10000 116.60000 42.91642 # 1000 46.37321 125.44903 48.99365 # ... # 9514 37.60000 237.60000 138.89027 ``` ``` -------------------------------- ### Geodesic ArcDirect: Direct Problem via Spherical Arc Length Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Solves the direct geodesic problem using spherical arc length (a12) in degrees instead of metric distance. Useful for specifying points along a geodesic path by angular separation. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 g = geod.ArcDirect(0, 0, 90, 45) # 45° of arc eastward along equator print(f"lat2={g['lat2']:.6f} lon2={g['lon2']:.6f}") # lat2=0.000000 lon2=44.876447 (slightly less than 45° because of flattening) print(f"s12={g['s12'] / 1e3:.3f} km") # ~4984.944 km ``` -------------------------------- ### GeodesicLine.ArcPosition Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Calculates the geographic position at a specified arc length along the geodesic line from its origin. This method is faster than Position when arc length spacing is desired, as it avoids distance-to-arc conversions. ```APIDOC ## GeodesicLine.ArcPosition — position along line by arc length `ArcPosition(a12, outmask=STANDARD)` is faster than `Position` because it skips the distance-to-arc conversion. Use when you need evenly-spaced arc steps rather than metric steps (useful for smooth plotting; spacing in distance varies by ~1/*f*). ```python from geographiclib.geodesic import Geodesic import math geod = Geodesic.WGS84 line = geod.InverseLine(40.1, 116.6, 37.6, -122.4, Geodesic.LATITUDE | Geodesic.LONGITUDE) da = 1.0 # 1° arc steps ≈ 60 NM n = int(math.ceil(line.a13 / da)) da = line.a13 / n # exact equal subdivision print("latitude longitude") for i in range(n + 1): g = line.ArcPosition(da * i, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) print(f"{g['lat2']:9.5f} {g['lon2']:10.5f}") ``` ``` -------------------------------- ### Measure Polygon Area Source: https://github.com/geographiclib/geographiclib-python/blob/main/doc/examples.md Calculates the perimeter and area of a polygon defined by a series of points. Uses the PolygonArea class to accumulate points and compute the results. ```python p = geod.Polygon() antarctica = [ [-63.1, -58], [-72.9, -74], [-71.9,-102], [-74.9,-102], [-74.3,-131], [-77.5,-163], [-77.4, 163], [-71.7, 172], [-65.9, 140], [-65.7, 113], [-66.6, 88], [-66.9, 59], [-69.8, 25], [-70.0, -4], [-71.0, -14], [-77.3, -33], [-77.9, -46], [-74.7, -61] ] for pnt in antarctica: p.AddPoint(pnt[0], pnt[1]) num, perim, area = p.Compute() print("Perimeter/area of Antarctica are {:.3f} m / {:.1f} m^2". format(perim, area)) ``` -------------------------------- ### Geodesic.ArcDirect Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Solves the direct geodesic problem using spherical arc length. Similar to `Direct`, but the distance is specified as arc length `a12` in degrees instead of metric distance. ```APIDOC ## Geodesic.ArcDirect — direct problem via spherical arc length `ArcDirect(lat1, lon1, azi1, a12, outmask=STANDARD)` is like `Direct` but the second point is specified by spherical arc length `a12` in degrees rather than metric distance. ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 g = geod.ArcDirect(0, 0, 90, 45) # 45° of arc eastward along equator print(f"lat2={g['lat2']:.6f} lon2={g['lon2']:.6f}") # lat2=0.000000 lon2=44.876447 (slightly less than 45° because of flattening) print(f"s12={g['s12'] / 1e3:.3f} km") # ~4984.944 km ``` ``` -------------------------------- ### GeodesicLine.Position Source: https://context7.com/geographiclib/geographiclib-python/llms.txt Calculates the geographic position at a specified metric distance along the geodesic line from its origin. This method requires the DISTANCE_IN capability, which is enabled by default. ```APIDOC ## GeodesicLine.Position — position along line by metric distance `Position(s12, outmask=STANDARD)` returns the point at distance `s12` meters from the line's origin. Requires the `DISTANCE_IN` capability (included by default). ```python from geographiclib.geodesic import Geodesic geod = Geodesic.WGS84 line = geod.Line(51.5, -0.1, 90) # London, heading due East for km in [0, 500, 1000, 2000, 5000]: g = line.Position(km * 1e3, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) print(f"{km:5d} km → ({g['lat2']:.5f}°, {g['lon2']:.5f}°)") # Output shows latitude drifting south (great-circle path curves away from equator) ``` ```