Spatial Metadata¶
As stated, a raster’s spatial metadata consists of a coordinate reference system (CRS), and an affine transformation matrix. The transform converts pixel indices to spatial coordinates, and the CRS specifies the location of these coordinates on the Earth’s surface. Another commonly used piece of spatial metadata is the raster’s bounding box. The bounding box is the rectangle that bounds the raster, and it reports the spatial coodinates of the edges of the raster’s data grid.
When the shape of a raster’s data grid is known (as is the case for all Raster objects), you can implement a complete spatial reference system using either (1) a CRS and a transform, or (2) a CRS and a bounding box. The transform and bounding box provide the same information, albeit formatted for different purposes. The transform is typically more useful for examining pixel resolution and locations, whereas a bounding box is more useful for locating the edges or center of the overall raster dataset.
The remainder of this page describes some common commands for examining a Raster object’s CRS, transform, and bounding box metadata. Note that this page is only an introduction; you can find additional commands and more advanced use cases in the spatial metadata tutorial.
CRS¶
You can use the crs
property to return a Raster object’s CRS. This will return a pyproj.CRS object with detailed information about the CRS. For example:
>>> raster.crs
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
Missing CRS¶
If a Raster does not have a CRS, then the crs
property will return None
.
>>> # Raster lacking a CRS
>>> print(raster.crs)
None
When this is the case, you can use the property to specify a CRS for the raster. You can use any input accepted by pyproj to initialize the CRS, or alternatively another Raster object. Some common options include:
An EPSG code,
A CRS name,
A Raster with the desired CRS, or
A PROJ4 string
# Common options to initialize a CRS
raster.crs = 4326 # An EPSG code
raster.crs = "NAD83 / UTM zone 11N" # By name
raster.crs = other_raster # Another Raster object
raster.crs = "+proj=latlon" # A PROJ4 string
Note
You cannot set the crs
property if a Raster already has a CRS. Instead, use the reproject method to reproject a Raster to a different CRS.
Transform¶
You can use the transform
property to return a Transform object for a Raster. A Transform object includes information on a raster’s resolution, as well as the locations of the left and top edges:
>>> raster.transform
Transform(dx=8.9e-05, dy=-9e-05, left=-121, top=0, crs="WGS 84")
Here, dx
is the change in spatial coordinate when moving one pixel right, and dy
is the change in spatial coordinate when moving one pixel down. Alternatively, you can use the affine
property to return the transform as an affine.Affine object, which can be used for coordinate mathematics:
>>> raster.affine
Affine(8.9e-05, 0.0, -121.0,
0.0, -9e-05, 0.0)
You can also use the resolution
method to return the raster’s resolution. By default, resolution is reported in meters, but you can use the units
option to report resolution in a different unit instead:
>>> # Default is meters
>>> raster.resolution()
(9.896348471216168, 10.007543398010286)
>>> # But you can use other units
>>> raster.resolution("feet")
(32.46833488, 32.83314763)
>>> # Report in the base units of the CRS
>>> # (in this case, units are degrees)
>>> raster.resolution(units="base")
(8.9e-05, 9e-05)
Note that resolution is strictly positive. Equivalently, resolution is the absolute value of dx
and dy
.
Tip
Read the spatial metadata tutorial for more advanced use of transform commands.
Missing Transform¶
If a Raster does not have a transform, then the transform
property will return None
:
>>> # Raster without a transform
>>> print(raster.transform)
None
When this is the case, you can use the property to initialize a Transform for the raster. You can use a variety of inputs to initialize a transform. Some common options include:
A dict,
A
(dx, dy, left, top)
list or tupleA Transform object,
An affine.Affine object, or
A Raster object with the desired transform
# Common options to initialize transform
raster.transform = (10, -10, -121, 5) # dx, dy, left, top
raster.transform = {'dx': 10, 'dy': -10, 'left': -121, 'top': 5}
raster.transform = other_raster
raster.transform = Transform(10, -10, -121, 5)
raster.transform = Affine(10, 0, -121, 0, -10, 5)
Since the transform and bounding box represent the same information, initializing the transform will also initialize the bounding box.
Note
You cannot set the transform
property if a Raster already has a transform. Instead, use the reproject method to reproject a Raster to a different transform.
Bounding Box¶
You can use the bounds
property to return a BoundingBox object for a Raster. This reports the spatial coordinates raster’s edges:
>>> raster.bounds
BoundingBox(left=736399, bottom=4876354, right=846259, top=4990804, crs="NAD83 / UTM zone 11N")
You can also use the center
property to return the coordinate at the center of the BoundingBox:
>>> raster.center
(791329.0, 4933579.0)
And the utm_zone
property returns the CRS of the UTM zone that overlaps this center coordinate:
>>> raster.utm_zone
<Projected CRS: EPSG:32612>
Name: WGS 84 / UTM zone 12N
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: Between 114°W and 108°W, northern hemisphere between equator and 84°N, onshore and offshore. Canada - Alberta; Northwest Territories (NWT); Nunavut; Saskatchewan. Mexico. United States (USA).
- bounds: (-114.0, 0.0, -108.0, 84.0)
Coordinate Operation:
- name: UTM zone 12N
- method: Transverse Mercator
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
Tip
Also read the spatial metadata tutorial for more advanced use of BoundingBox commands.
Missing Bounding Box¶
If a Raster does not have a BoundingBox, then the bounds
property will return None
:
>>> # Raster without bounds
>>> print(raster.bounds)
None
When this is the case, you can use the property to initialize the bounding box. You can use a variety of inputs to initialize a bounding box. These include:
A
(left, bottom, right, top)
tuple/list,A dict,
A Raster with the same bounds, or
A BoundingBox object
# Common options to initialize bounds
raster.bounds = (0, 5, 10, 100) # left, bottom, right, top
raster.bounds = {'left': 0, 'bottom': 5, 'right': 10, 'top': 100}
raster.bounds = other_raster
raster.bounds = BoundingBox(0, 5, 10, 100)
Since the bounding box and transform represent the same information, initializing the bounding box will also initialize the transform.
Note
You cannot set the bounds
property if a Raster already has a bounding box. Instead, use the clip method to clip a Raster to different bounds.