geovista.geodesic#

Provide geodesic operators for geolocated meshes.

Notes#

Added in version 0.1.0.

Module Contents#

Classes#

BBox

A 3-D bounding-box constructed from geodesic lines or great circles.

EnclosedPreference

Enumeration of mesh geometry enclosed preferences.

Functions#

line(lons, lats[, surface, radius, npts, ellps, ...])

Geodesic line consisting of one or more connected geodesic line segments.

npoints(start_lon, start_lat, end_lon, end_lat[, ...])

Calculate geodesic mid-points between provided start and end points.

npoints_by_idx(lons, lats, start_idx, end_idx[, npts, ...])

Calculate geodesic mid-points between provided start and end indices.

panel(name[, ellps, c, triangulate])

Create boundary-box for specific cubed-sphere panel.

wedge(lon1, lon2[, ellps, c, triangulate])

Create geodesic bounding-box manifold wedge from the north to the south pole.

Attributes#

BBOX_C

The bounding-box face geometry will contain BBOX_C**2 cells.

BBOX_RADIUS_RATIO

Ratio the bounding-box inner and outer faces are offset from the surface mesh.

BBOX_TOLERANCE

The bounding-box tolerance on intersection.

Corners

Type alias for the corners of a bounding-box.

ELLIPSE

Default geodesic ellipse. See pyproj.list.get_ellps_map().

GEODESIC_NPTS

Number of equally spaced geodesic points between/including end-point/s.

N_PANELS

The number of cubed-sphere panels.

PANEL_BBOX_BY_IDX

Cubed-sphere panel bounding-box longitudes and latitudes.

PANEL_IDX_BY_NAME

Lookup table for cubed-sphere panel index by panel name.

PANEL_NAME_BY_IDX

Lookup table for cubed-sphere panel name by panel index.

PREFERENCE

The default bounding-box preference.

class geovista.geodesic.BBox(lons, lats, ellps=ELLIPSE, c=BBOX_C, triangulate=False)[source]#

A 3-D bounding-box constructed from geodesic lines or great circles.

Create 3-D geodesic bounding-box to extract enclosed mesh, lines or point.

The bounding-box region is specified in terms of its four corners, in degrees of longitude and latitude. As the bounding-box is a geodesic, it can only ever at most enclose half of an ellipsoid.

The geometry of the bounding-box may be specified as either an open or closed longitude/latitude geometry i.e., 4 or 5 longitude/latitude values.

Parameters:
lonsArrayLike

The longitudes (degrees) of the bounding-box, in the half-closed interval [-180, 180). Note that, longitudes will be wrapped to this interval.

latsArrayLike

The latitudes (degrees) of the bounding-box, in the closed interval [-90, 90].

ellpsstr, optional

The ellipsoid for geodesic calculations. See pyproj.list.get_ellps_map(). Defaults to ELLIPSE.

cfloat, optional

The bounding-box face geometry will contain c**2 cells. Defaults to BBOX_C.

triangulatebool, optional

Specify whether the bounding-box faces are triangulated. Defaults to False.

Notes

Added in version 0.1.0.

property mesh: pyvista.PolyData#

The manifold bounding-box mesh.

Returns:
PolyData

The bounding-box mesh.

Notes

Added in version 0.1.0.

Examples

Add a C32 bounding-box around the Gulf of Guinea. The geodesic bounding-box is generated by defining 4 longitude-latitude corners. Natural Earth coastlines are also rendered along with a texture mapped Natural Earth base layer.

>>> import geovista
>>> from geovista.geodesic import BBox
>>> plotter = geovista.GeoPlotter()
>>> _ = plotter.add_base_layer(
...     texture=geovista.natural_earth_hypsometric(), style="wireframe"
... )
>>> bbox = BBox(lons=[-15, 20, 25, -15], lats=[-25, -20, 15, 10], c=32)
>>> _ = plotter.add_mesh(bbox.mesh, color="white")
>>> plotter.camera.zoom(1.5)
>>> plotter.show()
../../../../../_images/index-1_00_001.png
boundary(surface=None, radius=None)[source]#

Footprint of bounding-box intersecting on the provided mesh surface.

The region of the bounding-box that intersects on the surface of the mesh that will be enclosed.

Parameters:
surfacePolyData, optional

The pyvista.PolyData mesh that will be enclosed by the bounding-box boundary.

radiusfloat, optional

The radius of the spherical mesh that will be enclosed by the bounding-box boundary. Note that, the radius is only used when the surface is not provided. Defaults to geovista.common.RADIUS.

Returns:
PolyData

The boundary of the bounding-box.

Notes

Added in version 0.1.0.

Examples

Add the boundary of a C32 bounding-box to the plotter for a region around the Gulf of Guinea. The geodesic bounding-box is generated by defining 4 longitude-latitude corners.

The boundary is generated from where the bounding-box intersects with the surface of the C48 Sea Surface Temperature (SST) cubed-sphere mesh.

>>> import geovista
>>> from geovista.geodesic import BBox
>>> from geovista.pantry.meshes import lfric_sst
>>> plotter = geovista.GeoPlotter()
>>> mesh = lfric_sst()
>>> _ = plotter.add_mesh(mesh, cmap="balance")
>>> bbox = BBox(lons=[-15, 20, 25, -15], lats=[-25, -20, 15, 10], c=32)
>>> _ = plotter.add_mesh(bbox.boundary(mesh), color="orange", line_width=3)
>>> plotter.view_yz()
>>> plotter.show()
../../../../../_images/index-2_00_00.png
enclosed(surface, tolerance=BBOX_TOLERANCE, outside=False, preference=None)[source]#

Extract region of the surface contained within the bounding-box.

Note that, points that are on the surface of the bounding-box manifold are not considered within the bounding-box. See the preference and tolerance options.

Parameters:
surfacePolyData

The pyvista.PolyData mesh to be checked for containment.

tolerancefloat, optional

The tolerance on the intersection operation with the surface, expressed as a fraction of the diagonal of the bounding-box. See PyVista’s select_enclosed_points() for more. Defaults to BBOX_TOLERANCE.

outsidebool, optional

By default, select those points of the surface that are inside the bounding-box. Otherwise, select those points that are outside the bounding-box. Defaults to False.

preferencestr or EnclosedPreference, optional

Criteria for defining whether a face of a surface mesh is deemed to be enclosed by the bounding-box. A preference of cell requires all points defining the face to be within the bounding-box. A preference of center requires that only the face cell center is within the bounding-box. A preference of point requires at least one point that defines the face to be within the bounding-box. Defaults to PREFERENCE.

Returns:
PolyData

The pyvista.PolyData representing those parts of the provided surface enclosed by the bounding-box. This behaviour may be inverted with the outside parameter.

Notes

Added in version 0.1.0.

Examples

Add the boundary of a C32 bounding-box to the plotter for a region around the Gulf of Guinea. The geodesic bounding-box is generated by defining 4 longitude-latitude corners.

Add the region enclosed by a C32 bounding-box manifold to the plotter for a region around the 0 meridian. The geodesic bounding-box is generated by defining 4 longitude-latitude corners.

The region is generated from all cells of the C48 Sea Surface Temperature (SST) cubed-sphere mesh that have their cell center enclosed by the bounding-box manifold.

>>> import geovista
>>> from geovista.geodesic import BBox
>>> from geovista.pantry.meshes import lfric_sst
>>> plotter = geovista.GeoPlotter()
>>> _ = plotter.add_base_layer(texture=geovista.natural_earth_hypsometric())
>>> mesh = lfric_sst()
>>> bbox = BBox(lons=[-15, 20, 25, -15], lats=[-25, -20, 15, 10], c=32)
>>> region = bbox.enclosed(mesh)
>>> _ = plotter.add_mesh(region, cmap="balance")
>>> plotter.view_yz()
>>> plotter.show()
../../../../../_images/index-3_00_00.png

The same region is rendered again, but with the land mask cells removed using the pyvista.DataSetFilters.threshold() filter.

>>> plotter = geovista.GeoPlotter()
>>> _ = plotter.add_base_layer(texture=geovista.natural_earth_hypsometric())
>>> _ = plotter.add_mesh(region.threshold(), cmap="balance")
>>> plotter.view_yz()
>>> plotter.show()
../../../../../_images/index-3_01_00.png
class geovista.geodesic.EnclosedPreference(*args, **kwds)[source]#

Bases: geovista.common.MixinStrEnum, enum.Enum

Enumeration of mesh geometry enclosed preferences.

Notes

Added in version 0.3.0.

CELL = 'cell'#
CENTER = 'center'#
POINT = 'point'#
geovista.geodesic.line(lons, lats, surface=None, radius=None, npts=None, ellps=None, close=False, zlevel=None, zscale=None)[source]#

Geodesic line consisting of one or more connected geodesic line segments.

Note that, as a convenience, if a single value is provided for lons and N values are provided for lats, then the longitude value will be automatically repeated N times, and vice versa, providing N >= 2.

Parameters:
lonsArrayLike

The longitudes (degrees) of the geodesic line segments, in the half-closed interval [-180, 180). Note that, longitudes will be wrapped to this interval.

latsArrayLike

The latitudes (degrees) of the geodesic line segments, in the closed interval [-90, 90].

surfacePolyData, optional

The surface that the geodesic line will be rendered over.

radiusfloat, optional

The radius of the spherical surface that the geodesic line will be rendered over. Note that, the radius is only used when the surface is not provided. Defaults to geovista.common.RADIUS.

nptsfloat, optional

The number of equally spaced geodesic points in a line segment, excluding the segment end-point, but including the segment start-point i.e., npts must be at least 2. Defaults to GEODESIC_NPTS.

ellpsstr, optional

The ellipsoid for geodesic calculations. See pyproj.list.get_ellps_map(). Defaults to ELLIPSE.

closebool, optional

Whether to close the geodesic line segments into a loop i.e., the last point is connected to the first point. Defaults to False.

zlevelint, optional

The z-axis level. Used in combination with the zscale to offset the radius by a proportional amount i.e., radius * zlevel * zscale. Defaults to 1.

zscalefloat, optional

The proportional multiplier for z-axis zlevel. Defaults to geovista.common.ZLEVEL_SCALE.

Returns:
PolyData

The geodesic line.

Notes

Added in version 0.1.0.

Examples

Add the anti-meridian great circle to the plotter. A texture mapped Natural Earth base layer is also rendered.

>>> import geovista
>>> from geovista.geodesic import line
>>> plotter = geovista.GeoPlotter()
>>> _ = plotter.add_base_layer(texture=geovista.natural_earth_1())
>>> meridian = line(-180, [90, 0, -90])
>>> _ = plotter.add_mesh(meridian, color="orange", line_width=3)
>>> plotter.view_yz(negative=True)
>>> plotter.show()
../../../../../_images/index-4_00_00.png
geovista.geodesic.npoints(start_lon, start_lat, end_lon, end_lat, npts=GEODESIC_NPTS, radians=False, include_start=False, include_end=False, geod=None)[source]#

Calculate geodesic mid-points between provided start and end points.

Given a single start-point and end-point, calculate the equally spaced intermediate longitude and latitude npts points along the geodesic line that spans between the start and end points.

Note that, longitudes (degrees) will be wrapped to the half-closed interval [-180, 180).

Parameters:
start_lonfloat

The longitude of the start-point for the geodesic line.

start_latfloat

The latitude of the start-point for the geodesic line.

end_lonfloat

The longitude of the end-point for the geodesic line.

end_latfloat

The latitude of the end-point for the geodesic line.

nptsint, optional

The number of points to be returned, which may include the start-point and/or the end-point, if required. Defaults to GEODESIC_NPTS.

radiansbool, optional

If True, the start and end points are assumed to be in radians, otherwise degrees. Defaults to False.

include_startbool, optional

Whether to include the start-point in the geodesic points returned. Defaults to False.

include_endbool, optional

Whether to include the end-point in the geodesic points returned. Defaults to False.

geodGeod, optional

Definition of the ellipsoid for geodesic calculations. Defaults to ELLIPSE.

Returns:
tuple

Tuple of longitude points and latitude points along the geodesic line between the start-point and the end-point.

Notes

Added in version 0.1.0.

Examples

>>> from geovista.geodesic import npoints
>>> import numpy as np
>>> points = npoints(start_lon=-10, start_lat=20, end_lon=10, end_lat=30, npts=5)
>>> print(np.array(points, dtype=np.float16))
[[-6.887 -3.69  -0.41   2.963  6.43 ]
 [21.84  23.62  25.34  26.98  28.53 ]]
geovista.geodesic.npoints_by_idx(lons, lats, start_idx, end_idx, npts=GEODESIC_NPTS, radians=False, include_start=False, include_end=False, geod=None)[source]#

Calculate geodesic mid-points between provided start and end indices.

Given a single start-point index and end-point index, calculate the equally spaced intermediate longitude and latitude npts points along the geodesic line that spans between the start and end points.

Note that, longitudes (degrees) will be wrapped to the half-closed interval [-180, 180).

Parameters:
lonsArrayLike

The longitudes to be sampled by the provided indices.

latsArrayLike

The latitudes to be sampled by the provided indices.

start_idxint

The index of the start-point.

end_idxint

The index of the end-point.

nptsint, optional

The number of points to be returned, which may include the start-point and/or the end-point, if required. Defaults to GEODESIC_NPTS.

radiansbool, optional

If True, the lons and lats are assumed to be in radians, otherwise degrees. Defaults to False.

include_startbool, optional

Whether to include the start-point in the geodesic points returned. Defaults to False.

include_endbool, optional

Whether to include the end-point in the geodesic points returned. Defaults to False.

geodGeod, optional

Definition of the ellipsoid for geodesic calculations. Defaults to ELLIPSE.

Returns:
tuple

Tuple of longitude points and latitude points along the geodesic line between the start-point and the end-point.

Notes

Added in version 0.1.0.

Examples

>>> from geovista.geodesic import npoints_by_idx
>>> import numpy as np
>>> points = npoints_by_idx(
...     lons=[-10, 0, 10], lats=[20, 25, 30], start_idx=0, end_idx=1, npts=5
... )
>>> print(np.array(points, dtype=np.float16))
[[-8.38  -6.746 -5.09  -3.414 -1.718]
 [20.88  21.73  22.58  23.4   24.22 ]]
geovista.geodesic.panel(name, ellps=ELLIPSE, c=BBOX_C, triangulate=False)[source]#

Create boundary-box for specific cubed-sphere panel.

Parameters:
nameint or str

The cubed-sphere index, see PANEL_NAME_BY_IDX, or name, see PANEL_IDX_BY_NAME, which specifies the panel bounding-box, see PANEL_BBOX_BY_IDX.

ellpsstr, optional

The ellipsoid for geodesic calculations. See pyproj.list.get_ellps_map(). Defaults to ELLIPSE.

cfloat, optional

The bounding-box face geometry will contain c**2 cells. Defaults to BBOX_C.

triangulatebool, optional

Specify whether the panel bounding-box faces are triangulated. Defaults to False.

Returns:
BBox

The bounding-box that encloses the required cubed-sphere panel.

Notes

Added in version 0.1.0.

Examples

Add a wireframe bounding-box to the plotter for the americas panel of a cubed-sphere. The geodesic bounding-box is generated from the 4 corners of the cubed-sphere panel located over Americas. A texture mapped Natural Earth base layer is also rendered.

>>> import geovista
>>> from geovista.geodesic import panel
>>> plotter = geovista.GeoPlotter()
>>> _ = plotter.add_base_layer(
...     texture=geovista.natural_earth_hypsometric(), opacity=0.5
... )
>>> bbox = panel("americas", c=8)
>>> _ = plotter.add_mesh(bbox.mesh, color="orange", style="wireframe")
>>> plotter.view_xz()
>>> plotter.show()
../../../../../_images/index-7_00_00.png
geovista.geodesic.wedge(lon1, lon2, ellps=ELLIPSE, c=BBOX_C, triangulate=False)[source]#

Create geodesic bounding-box manifold wedge from the north to the south pole.

Parameters:
lon1float

The first longitude (degrees) defining the geodesic wedge region.

lon2float

The second longitude (degrees) defining the geodesic wedge region.

ellpsstr, optional

The ellipsoid for geodesic calculations. See pyproj.list.get_ellps_map(). Defaults to ELLIPSE.

cfloat, optional

The bounding-box face geometry will contain c**2 cells. Defaults to BBOX_C.

triangulatebool, optional

Specify whether the wedge bounding-box faces are triangulated. Defaults to False.

Returns:
BBox

The bounding-box that encloses the required geodesic wedge.

Notes

Added in version 0.1.0.

Examples

Add a C8 sixty-degree wide wireframe bounding-box wedge to the plotter. A texture mapped NASA Blue Marble base layer is also rendered.

>>> import geovista
>>> from geovista.geodesic import wedge
>>> plotter = geovista.GeoPlotter()
>>> _ = plotter.add_base_layer(texture=geovista.blue_marble(), opacity=0.5)
>>> bbox = wedge(-30, 30, c=8)
>>> _ = plotter.add_mesh(bbox.mesh, color="orange", style="wireframe")
>>> plotter.view_yz()
>>> plotter.show()
../../../../../_images/index-8_00_00.png
geovista.geodesic.BBOX_C: int = 256#

The bounding-box face geometry will contain BBOX_C**2 cells.

geovista.geodesic.BBOX_RADIUS_RATIO = 0.1#

Ratio the bounding-box inner and outer faces are offset from the surface mesh.

geovista.geodesic.BBOX_TOLERANCE = 1e-06#

The bounding-box tolerance on intersection.

geovista.geodesic.Corners: TypeAlias#

Type alias for the corners of a bounding-box.

geovista.geodesic.ELLIPSE: str = 'WGS84'#

Default geodesic ellipse. See pyproj.list.get_ellps_map().

geovista.geodesic.GEODESIC_NPTS: int = 64#

Number of equally spaced geodesic points between/including end-point/s.

geovista.geodesic.N_PANELS: int#

The number of cubed-sphere panels.

geovista.geodesic.PANEL_BBOX_BY_IDX: dict[int, tuple[Corners, Corners]]#

Cubed-sphere panel bounding-box longitudes and latitudes.

geovista.geodesic.PANEL_IDX_BY_NAME: dict[str, int]#

Lookup table for cubed-sphere panel index by panel name.

geovista.geodesic.PANEL_NAME_BY_IDX: dict[int, str]#

Lookup table for cubed-sphere panel name by panel index.

geovista.geodesic.PREFERENCE: str = 'center'#

The default bounding-box preference.