gisserver.crs module

Helper classes for Coordinate Reference System translations.

This includes the CRS parsing, coordinate transforms and axis orientation.

Default Coordinate Reference Systems

crs.WGS84

Worldwide GPS, latitude/longitude (y/x), see https://epsg.io/4326. Generated output as urn:ogc:def:crs:EPSG::4326.

crs.CRS84

The default for GeoJSON output. This is like WGS84 but with axis as longitude/latitude (x/y). Generates output as urn:ogc:def:crs:OGC::CRS84.

crs.WEB_MERCATOR

The WGS84/pseudo-mercator aka Spherical Mercator projection, see https://epsg.io/3857. This is used by Google Maps, Bing Maps, OpenStreetMap, etc… Generates output as urn:ogc:def:crs:EPSG::3857.

The CRS Class

class gisserver.crs.CRS(domain: str, authority: str, version: str, crsid: str, srid: int, backends: tuple[SpatialReference, SpatialReference] = (None, None), force_xy: bool = False)

Represents a CRS (Coordinate Reference System), which preferably follows the URN format as specified by the OGC consortium.

__init__(domain: str, authority: str, version: str, crsid: str, srid: int, backends: tuple[SpatialReference, SpatialReference] = (None, None), force_xy: bool = False) None
apply_to(geometry: AnyGeometry, clone=False, axis_order: AxisOrder | None = None) AnyGeometry | None

Transform the geometry using this coordinate reference.

Every transformation within this package happens through this method, giving full control over coordinate transformations.

A bit of background: geometries are provided as GEOSGeometry from the database. This is basically a simple C-based storage implementing “OpenGIS Simple Features for SQL”, except it does not store axis orientation. These are assumed to be x/y.

To perform transformations, GeoDjango loads the GEOS-geometry into GDAL/OGR. The transformed geometry is loaded back to GEOS. To avoid this conversion, pass the OGR object directly and continue working on that.

Internally, this method caches the used GDAL CoordTransform object, so repeated transformations of the same coordinate systems are faster.

The axis order can change during the transformation. From a programming perspective, screen coordinates (x/y) were traditionally used. However, various systems and industries have always worked with north/east (y/x). This includes systems with critical safety requirements in aviation and maritime. The CRS authority reflects this practice. What you need depends on the use case:

  • The (GML) output of WFS 2.0 and WMS 1.3 respect the axis ordering of the CRS.

  • GeoJSON always provides coordinates in x/y, to keep web-based clients simple.

  • PostGIS stores the data in x/y.

  • WFS 1.0 used x/y, WFS 1.3 used y/x except for EPSG:4326.

When receiving legacy notations (e.g. EPSG:4326 instead of urn:ogc:def:crs:EPSG::4326), the data is still projected in legacy ordering, unless GISSERVER_FORCE_XY_... is disabled. This reflects the design of GeoServer Axis Ordering to have maximum interoperability with legacy/JavaScript clients.

After GDAL/OGR changed the axis orientation, that information is lost when the return value is loaded back into GEOS. To address this, tag_geometry() is called on the result.

Parameters:
  • geometry – The GEOS Geometry, or GDAL/OGR loaded geometry.

  • clone – Whether the object is changed in-place, or a copy is returned. For GEOS->GDAL->GEOS conversions, this makes no difference in efficiency.

  • axis_order – Which axis ordering to convert the geometry into (depends on the use-case).

authority: str

Either “OGC” or “EPSG”.

property axis_direction: list[str]

Tell what the axis ordering of this coordinate system is.

For example, WGS84 will return ['north', 'east'].

While computer systems typically use X,Y, other systems may use northing/easting. Historically, latitude was easier to measure and given first. In physics, using ‘radial, polar, azimuthal’ is again a different perspective. See: https://wiki.osgeo.org/wiki/Axis_Order_Confusion for a good summary.

backends: tuple[SpatialReference, SpatialReference] = (None, None)

GDAL SpatialReference with PROJ.4 / WKT content to describe the exact transformation.

cache_instance()

Cache a common CRS, no need to re-instantiate the same object again. This also makes sure that requests which use the same URN will get our CRS object version, instead of a fresh new one.

crsid: str

A string representation of the coordinate system reference ID. For OGC, only “CRS84” is supported as crsid. For EPSG, this is the formatted CRSID.

domain: str

Either “ogc” or “opengis”, whereas “ogc” is highly recommended.

force_xy: bool = False

Tell whether the input format used the legacy notation.

classmethod from_srid(srid: int)

Instantiate this class using a numeric spatial reference ID

This is logically identical to calling:

CRS.from_string("urn:ogc:def:crs:EPSG::<SRID>")
classmethod from_string(uri: str | int) CRS

Parse an CRS (Coordinate Reference System) URI, which preferably follows the URN format as specified by the OGC consortium and construct a new CRS instance.

The value can be 3 things:

property is_north_east_order: bool

Tell whether the axis is in north/east ordering.

property legacy

Return a legacy string in the format http://www.opengis.net/gml/srs/epsg.xml#srid.

matches(other, compare_legacy=True) bool

Tell whether this CRS is identical to another one.

origin: str = None

Original input

srid: int

The integer representing the numeric spatial reference ID as used by the EPSG and GIS database backends.

classmethod tag_geometry(geometry: GEOSGeometry, axis_order: AxisOrder)

Associate this object with the geometry.

This informs the apply_to() method that this source geometry already had the correct axis ordering (e.g. it was part of the <fes:BBOX> logic). The srid integer doesn’t communicate that information.

property urn

Return The OGC URN corresponding to this CRS.

version: str

The version of the authorities’ SRS registry, which is empty or contains two or three numeric components separated by dots like “6.9” or “6.11.9”. For WFS 2.0 this is typically empty.