nav.ui
- class ManualNavDialog(*args: Any, **kwargs: Any)[source]
Bases:
QDialogManual navigation dialog for overlaying image and combined model.
The viewport uses false color (image in red/blue, blend in green). Separate Image Stretch and Model Stretch groups each provide black/white/gamma and a display toggle. Model transparency and an optional binary mask overlay sit under model stretch.
nav.ui.mosaic_viewer
Projection math for alternate 2-D display modes and the 3-D sphere view.
All projection functions operate in normalized display units. The conversion between normalized units and viewport pixels uses the linear transform:
viewport_x = normalized_x * scale + cx
viewport_y = normalized_y * scale + cy
where (cx, cy) is the projection centre in viewport pixels and scale
is pixels per normalized unit. ProjectionParams carries these values.
Normalized-unit conventions per kind
RECT – 1 unit = 1 degree. x = longitude [0, 360), y = -latitude. This projection is rendered by the existing body-sphere canvas path; these functions are used only for graticule overlays.
POLAR_N – 1 unit = stereographic equatorial radius. r = 0 is the north pole, r = 1 is the equator. 0 deg longitude appears at the top (screen-y direction).
POLAR_S – same as POLAR_N with latitude sign-flipped. r = 0 is the south pole, r = 1 is the equator.
MOLLWEIDE – 1 unit = sqrt(2). The full-globe ellipse spans x in [-2*sqrt(2), 2*sqrt(2)] and y in [-sqrt(2), sqrt(2)].
SPHERE_3D – 1 unit = sphere radius. The visible disk has r <= 1. The camera views from the +X direction; yaw/pitch define which geographic point faces the camera.
Coordinate system
Screen y increases downward (PyQt6 convention). Normalized y also increases
downward to match, so vy = yn * scale + cy with no sign flip needed in
the viewport transform.
- class ProjectionKind(*values)[source]
Bases:
EnumAvailable projection modes for the body mosaic viewer.
- MOLLWEIDE = 'mollweide'
- POLAR_N = 'polar_n'
- POLAR_S = 'polar_s'
- RECT = 'rect'
- SPHERE_3D = 'sphere_3d'
- class ProjectionParams(kind: ProjectionKind, cx: float, cy: float, scale: float, yaw_deg: float = 0.0, pitch_deg: float = 0.0)[source]
Bases:
objectViewport geometry for a single projection frame.
- Parameters:
kind – Which projection to use.
cx – Viewport X coordinate of the projection centre (pixels from left).
cy – Viewport Y coordinate of the projection centre (pixels from top).
scale – Pixels per normalized unit (see module docstring).
yaw_deg – SPHERE_3D only – longitude at the centre of the view (deg).
pitch_deg – SPHERE_3D only – latitude at the centre of the view (deg).
- kind: ProjectionKind
- display_to_lonlat(vx: ndarray, vy: ndarray, params: ProjectionParams) → tuple[ndarray, ndarray, ndarray][source]
Map viewport pixel positions to geographic coordinates.
- Parameters:
vx – Viewport X pixel array.
vy – Viewport Y pixel array.
params – Current projection parameters.
- Returns:
Tuple
(lon_deg, lat_deg, valid)wherevalidis a bool mask (False for pixels outside the valid domain of the projection).- Raises:
ValueError – If
params.kindis unknown orparams.scaleis zero / non-finite.
- fit_scale(kind: ProjectionKind, vw: int, vh: int) → float[source]
Return a scale (pixels per normalized unit) that fits the projection.
The result leaves a margin
_FIT_SCALE_MARGIN(10 % inset) around the projection so it does not touch the viewport edge at the initial zoom level.- Parameters:
kind – Projection kind.
vw – Viewport width in pixels.
vh – Viewport height in pixels.
- Returns:
Scale in pixels per normalized unit.
- Raises:
ValueError – If
vworvhis not strictly positive.
- lonlat_to_display(lon_deg: ndarray, lat_deg: ndarray, params: ProjectionParams) → tuple[ndarray, ndarray, ndarray][source]
Map geographic coordinates to viewport pixel positions.
- Parameters:
lon_deg – Longitude array (deg), any range.
lat_deg – Latitude array (deg), values in [-90, 90].
params – Current projection parameters.
- Returns:
Tuple
(vx, vy, visible)wherevxandvyare float64 arrays of viewport pixel coordinates andvisibleis a bool array (False for points not representable in this projection atparams).- Raises:
ValueError – If
params.kindis unknown orparams.scaleis zero / non-finite.
- sphere_pixel_to_lonlat(vx: ndarray, vy: ndarray, params: ProjectionParams) → tuple[ndarray, ndarray, ndarray][source]
Ray-cast orthographic sphere: viewport pixels to (lon_deg, lat_deg, hit).
Points outside the sphere disk or on the back hemisphere return
hit=False.- Parameters:
vx – Viewport X pixel array.
vy – Viewport Y pixel array.
params – Projection parameters;
kindmust beSPHERE_3D.
- Returns:
Tuple
(lon_deg, lat_deg, hit).- Raises:
ValueError – If
params.kindis notSPHERE_3Dorparams.scaleis zero / non-finite.
Software renderer for non-rectangular body-mosaic projections.
render_to_image() converts a (lon_deg, lat_deg, valid) coordinate grid
– produced by projections – into a
QImage (Format_RGB888) using nearest-neighbour texture lookup, the same
contrast-stretch pipeline as the existing rectangular render path, and optional
per-pixel metadata tinting.
The function is intentionally stateless and side-effect-free so it can be called from any paint method without lock concerns.
- render_to_image(image_ma: MaskedArray, *, lon_deg: ndarray, lat_deg: ndarray, valid: ndarray, lon_min_deg: float, lat_min_deg: float, d_lon_deg: float, d_lat_deg: float, lon_bin_to_dc: ndarray, n_full_lon: int, n_data_rows: int, n_data_cols: int, black: float, white: float, gamma: float, color_tint: ndarray | None) → QImage[source]
Render a mosaic texture onto an arbitrary projection grid.
- Parameters:
image_ma – 2-D masked array (n_data_rows, n_data_cols) with the photometrically-corrected mosaic data.
lon_deg – 2-D float64 array of longitudes (deg) for every output pixel, in [0, 360). After binning to
k, any pixel withlon_bin_to_dc[k] == -1has no data column and is off-grid (no-data whenvalidis True).lat_deg – 2-D float64 array of latitudes (deg), in [-90, 90]. Latitudes outside
[lat_min_deg, lat_min_deg + n_data_rows * d_lat_deg)map todroutside[0, n_data_rows)and are off-grid (no-data whenvalidis True).valid – 2-D bool array; False pixels are painted black (off-projection background). True pixels with no usable data (outside the file’s lat/lon extent or explicitly masked) are painted dark red.
lon_min_deg – Geographic minimum longitude of the data grid (deg).
lat_min_deg – Geographic minimum latitude of the data grid (deg).
d_lon_deg – Longitude resolution of the data grid (deg/column).
d_lat_deg – Latitude resolution of the data grid (deg/row).
lon_bin_to_dc – 1-D int32 array mapping full-circle longitude bin index to data column index (-1 = absent).
n_full_lon – Length of
lon_bin_to_dc.n_data_rows – Number of rows in
image_ma.n_data_cols – Number of columns in
image_ma.black – Stretch black point.
white – Stretch white point.
gamma – Stretch gamma (applied as power).
color_tint – Optional per-pixel RGB tint, shape (n_data_rows, n_data_cols, 3), float32 in [0, 1]. None = greyscale.
- Returns:
A QImage in Format_RGB888 matching the shape of
lon_deg/lat_deg.- Raises:
ValueError – If
d_lon_degord_lat_degis zero, ifgammais not positive, iflen(lon_bin_to_dc) != n_full_lon, or iflon_deg,lat_deg, andvaliddo not share the same shape.
Lat/lon graticule polylines for non-rectangular body-mosaic projections.
graticule_polylines() samples parallels and meridians in geographic
coordinates, projects them through the current ProjectionParams, and
returns screen-space polyline segments ready for QPainter.drawPolyline.
Polylines are split wherever consecutive samples jump discontinuously (e.g. at the limb of a sphere or a map seam), so each returned segment is a continuous visible arc.
- graticule_label_anchors(params: ProjectionParams, *, lat_step_deg: float, lon_step_deg: float) → tuple[list[tuple[float, float, str]], list[tuple[float, float, str]]][source]
Return label anchor positions for visible graticule lines.
Finds the best visible point along each parallel and meridian at which to draw a tick label. For parallels the anchor is the point closest to the screen centre along the line; for meridians similarly.
- Parameters:
params – Current projection parameters.
lat_step_deg – Spacing of parallels (deg).
lon_step_deg – Spacing of meridians (deg).
- Returns:
Tuple
(parallel_anchors, meridian_anchors). Each anchor is(vx, vy, label_text).- Raises:
TypeError – If
paramsisNone.ValueError – If
lat_step_degorlon_step_degis negative.
- graticule_polylines(params: ProjectionParams, *, lat_step_deg: float, lon_step_deg: float, samples_per_line: int = 181, show_parallels: bool = True, show_meridians: bool = True) → tuple[list[list[tuple[float, float]]], list[list[tuple[float, float]]]][source]
Compute graticule screen-space polylines for the given projection.
Each “line” in the returned lists is a list of (vx, vy) tuples that can be drawn as a connected polyline. Lines are pre-split at discontinuities (sphere limb, map seam) so callers do not need to check for jumps.
- Parameters:
params – Current projection parameters. For RECT mode the caller should use the existing straight-line overlay path instead.
lat_step_deg – Spacing of parallels (deg). Pass 0 to disable.
lon_step_deg – Spacing of meridians (deg). Pass 0 to disable.
samples_per_line – Number of sample points along each graticule line.
show_parallels – Include parallel (constant-latitude) lines.
show_meridians – Include meridian (constant-longitude) lines.
- Returns:
Tuple
(parallel_lines, meridian_lines)where each element is a list of polyline segments. A segment is a list of(vx, vy)float tuples.- Raises:
TypeError – If
paramsisNone.ValueError – If
lat_step_degorlon_step_degis negative, or ifsamples_per_lineis less than 2.