CRS Creator Internals#
This page documents the internals of WISER’s CRS Creator (the “Reference System Creator”) — the spatial tool that lets a user define a custom coordinate reference system (CRS) by hand, without an EPSG / authority code. It is a companion to the Georeferencer Internals page; custom CRSs created here become selectable as the output CRS when georeferencing.
Overview#
A user describes a CRS in geodetic terms — a datum shape (sphere or ellipsoid), a prime
meridian, and a map projection with its parameters — and the tool assembles those into a
PROJ4 string, converts it to an osr.SpatialReference, and stores it by name in
ApplicationState. From then on it behaves like any other CRS in WISER.
flowchart LR
U["User fills dialog fields"] --> S["ReferenceCreatorDialog<br/>(validated state)"]
S --> P["_create_crs():<br/>build PROJ4 string"]
P --> Y["pyproj.CRS.from_proj4 → WKT"]
Y --> O["osr.SpatialReference<br/>(ImportFromWkt)"]
O --> A["ApplicationState.add_user_created_crs(name, srs, state)"]
A --> G["Georeferencer output-CRS chooser<br/>(as UserGeneratedCRS)"]
Core files:
File |
Responsibility |
|---|---|
|
|
|
Qt Designer UI ( |
|
|
The dialog is launched lazily from App.show_reference_creator_dialog
(src/wiser/gui/app.py).
Class & State#
classDiagram
class QDialog["QDialog (Qt)"]
class ReferenceCreatorDialog {
reference_creator_dialog.py
+_create_crs()
+_export_creator_state()
-_new_crs : osr.SpatialReference
}
class CrsCreatorState {
<<immutable snapshot>>
+proj_type
+shape_type
+semi_major_value
+axis_ingest_type / value
+lon_meridian
+center_lon / latitude
+latitude_choice
+polar_stereo_scale / sign
}
QDialog <|-- ReferenceCreatorDialog
ReferenceCreatorDialog --> CrsCreatorState : exports / reloads
ReferenceCreatorDialog owns the UI and the build logic. A family of _init_*
methods wire each field group with validators (e.g. latitude clamped to ±90, longitude
to ±180, the CRS name restricted to alphanumeric + underscore).
CrsCreatorState is an immutable snapshot of every field. After a successful build
it is stored alongside the resulting osr.SpatialReference, which is what lets a saved
custom CRS be re-selected and have its parameters reloaded into the dialog for editing.
The dialog’s behavior is driven by several enums:
Enum |
Values |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
UI / Workflow#
The form is organized into the groups a CRS definition needs:
Datum shape —
SPHEROID(a single radius) orELLIPSOID(semi-major axis plus either the semi-minor axis or the inverse flattening, selected viaEllipsoidAxisType).Prime meridian — the longitude offset applied to the datum (
+pm).Projection — one of
EQUI_CYLINDRICAL,POLAR_STEREO, orNO_PROJECTION.Projection parameters — central meridian (
center_lon), a latitude value, and aLatitudeTypeschoice of whether that latitude is the central latitude or the latitude of true scale. Polar Stereographic additionally needs either a scale factor (central-latitude mode) or a pole sign (true-scale mode).Name — the key the CRS is stored and displayed under.
A reset button clears the fields; the create/accept button runs _create_crs().
CRS Construction (_create_crs)#
_create_crs() validates the fields, builds a PROJ4 string, and converts it to an OSR
spatial reference.
The PROJ4 fragments assembled per choice:
Choice |
PROJ4 fragment |
|---|---|
Sphere |
|
Ellipsoid |
|
Base (always) |
|
No Projection |
|
Equidistance Cylindrical, central lat |
|
Equidistance Cylindrical, true-scale lat |
|
Polar Stereographic, central lat |
|
Polar Stereographic, true-scale lat |
|
The conversion goes PROJ4 → pyproj.CRS → WKT → osr.SpatialReference
(ImportFromWkt), and the axis mapping is forced to OAMS_TRADITIONAL_GIS_ORDER — the
same convention the georeferencer applies — so coordinate order is consistent everywhere
the CRS is used.
Integration#
add_user_created_crs(name, crs, state) stores the pair in ApplicationState:
self._user_created_crs: Dict[str, Tuple[osr.SpatialReference, CrsCreatorState]] = {}
(keyed by name, with a confirmation prompt before overwriting an existing name). The
Georeferencer reads this map in _update_output_srs_cbox_items and wraps each entry in a
UserGeneratedCRS so it appears in the output-CRS chooser. The stored CrsCreatorState
is what lets the CRS Creator reload a previously created CRS back into its fields for
editing. See Georeferencer Internals for how the resulting
CRS feeds the warp.