GeoContext¶
Datasets in the Descartes Labs catalog have many different resolutions and
projections. In two different images, even covering the same place on Earth,
the pixels (i, j)
usually correspond to two different points on the ground.
GeoContexts are a way to ensure multiple images from different sources are spatially compatible—that is, they all have the same shape (same width and height, in pixels), and the same pixel in each image corresponds to the same area on Earth.
They do this by simply capturing all the spatial parameters that affect how imagery is rasterized—namely output resolution, coordinate reference system, and bounding box—in one object that can be passed into different method calls. In typical use, these contexts are created for you with reasonable defaults, so you only need to understand the different parameters when you need more control.
The different subclasses of GeoContext implement different functionality.
 AOI clips to arbitrary geometry, and lets you specify any output resolution and projection.
 DLTile helps you split large regions up into a grid of any spacing and resolution, and represents a single tile in that grid, in UTM projection.
Tutorial¶
Often, you don’t have to create GeoContexts yourself—an AOI with default parameters is created for you by scenes.search <scenes._search.search> and Scene.from_id.
In [1]: import descarteslabs as dl
In [2]: scene, default_ctx = dl.scenes.Scene.from_id('landsat:LC08:PRE:TOAR:meta_LC80260322013188_v1')
In [3]: default_ctx
Out[3]:
AOI(geometry=None,
resolution=15.0,
crs=u'EPSG:32615',
align_pixels=False,
bounds=(347692.5, 4345807.5, 580732.5, 4582807.5),
bounds_crs=u'EPSG:32615',
shape=None)
GeoContexts are immutable; instead, create copies with new values using AOI.assign. (Assigning new values to DLTiles is not yet supported.)
# let's use a lower resolution to load images faster
In [4]: lowres = default_ctx.assign(resolution=75)
In [5]: lowres_arr = scene.ndarray("red green blue", lowres)
In [6]: dl.scenes.display(lowres_arr, size=4, title="Default GeoContext, 75meter resolution")
You can also create GeoContexts explicitly:
In [7]: import shapely.affinity
# make a new polygon half the size of the scene's full extent
In [8]: new_cutline = shapely.affinity.scale(scene.geometry, xfact=0.5, yfact=0.5)
In [9]: webmerc_cutline_aoi = dl.scenes.AOI(
...: geometry=new_cutline,
...: resolution=75,
...: crs="EPSG:3857" # "EPSG:3857" is the code for the Web Mercator
...: ) # coordinate reference system, see http://epsg.io/3857
...:
In [10]: webmerc_cutline_arr = scene.ndarray("red green blue", webmerc_cutline_aoi)
In [11]: dl.scenes.display(webmerc_cutline_arr, size=4, title="Same scene, with cutline and Web Mercator")
Let’s assign our new cutline to the default GeoContext to see the difference between the coordinate reference systems:
In [12]: with_cutline = lowres.assign(geometry=new_cutline)
In [13]: with_cutline_arr = scene.ndarray("red green blue", with_cutline)
In [14]: dl.scenes.display(with_cutline_arr, size=4, title="Original GeoContext with new cutline")
Why is there all that empty space around the sides?
We assigned a new geometry, but we didn’t change the bounds.
Bounds determine the xy extent that’s rasterized; geometry just clips within that.
You can pass bounds="update"
to compute new bounds when assinging a new geometry.
In [15]: cutline_bounds = lowres.assign(geometry=new_cutline, bounds="update")
In [16]: cutline_bounds_arr = scene.ndarray("red green blue", cutline_bounds)
In [17]: dl.scenes.display(cutline_bounds_arr, size=4, title="Original GeoContext, new cutline and bounds")
Bounds can be expressed in any coordinate reference system, set in bounds_crs
.
They’re typically either in the native CRS of the Scene, or in WGS84 when clipping to a geometry.
Note that when computing bounds from a geometry, bounds_crs
is automatically set to
"EPSG:4326"
(short for WGS84 latlon coordinates), since that’s the CRS in which
the geometry is also defined.
You can also use DLTiles to split up regions along a grid:
In [1]: tiles = dl.scenes.DLTile.from_shape(
...: new_cutline, resolution=75, tilesize=256, pad=16
...: )
...:
In [2]: len(tiles)
Out[2]: 38
In [3]: tile0_arr = scene.ndarray("red green blue", tiles[0])
In [4]: tile1_arr = scene.ndarray("red green blue", tiles[1])
In [5]: dl.scenes.display(tile0_arr, tile1_arr, title=[tiles[0].key, tiles[1].key], size=3)

class
AOI
(geometry=None, resolution=None, crs=None, align_pixels=True, bounds=None, bounds_crs='EPSG:4326', shape=None)[source]¶ A GeoContext that clips scenes to a geometry, and/or to square bounds, with any output resolution and CRS.
Examples
cutline_aoi = dl.scenes.AOI(my_geometry, resolution=40) aoi_with_cutline_disabled = cutline_aoi.assign(geometry=None) no_cutline_aoi = dl.scenes.AOI(geometry=None, resolution=15, bounds=(40, 35, 39, 36)) aoi_without_auto_bounds = dl.scenes.AOI(geometry=my_geometry, resolution=15, bounds=(40, 35, 39, 36)) aoi_with_specific_pixel_dimensions = dl.scenes.AOI(geometry=my_geometry, shape=(200, 400))
Parameters:  geometry (GeoJSONlike dict, object with
__geo_interface__
; optional) – Clip scenes to this geometry. Coordinates must be WGS84 (latlon). If None, scenes will just be clipped tobounds
.  resolution (float, optional) – Distance, in units of the CRS, that the edge of each pixel
represents on the ground.
Can only specify one of
resolution
andshape
.  crs (str, optional) – Coordinate Reference System into which scenes will be projected,
expressed as an EPSG code (like
"EPSG:4326"
), a PROJ.4 definition, or an OGC CRS WellKnown Text string  align_pixels (bool, optional, default True) –
If True, this ensures that, in different Scenes rasterized with this same AOI GeoContext, pixels
(i, j)
correspond to the same area in space. This is accomplished by snapping the coordinates of the origin (topleft corner of topleft pixel) to a nonfractional interval ofresolution
.If
align_pixels
is False, when using scenes with different native resolutions and/or projections, pixels at the same indicies can be misaligned by a fraction ofresolution
(i.e. correspond to slighly different coordinates in space).However, this requires warping of the original image, which can be undesireable when you want to work with the original data in its native resolution and projection.
 bounds (4tuple, optional) – Clip scenes to these
(min_x, min_y, max_x, max_y)
bounds, expressed inbounds_crs
(which defaults to WGS84 latlon).bounds
are automatically computed fromgeometry
if not specified. Otherwise,bounds
are required.  bounds_crs (str, optional, default "EPSG:4326") – The Coordinate Reference System of the
bounds
, given as an EPSG code (like"EPSG:4326"
), a PROJ.4 definition, or an OGC CRS WellKnown Text string.  shape (2tuple, optional) –
(rows, columns)
, in pixels, the output raster should fit within; the longer side of the raster will be min(shape). Can only specify one ofresolution
andshape
.

assign
(geometry='unchanged', resolution='unchanged', crs='unchanged', align_pixels='unchanged', bounds='unchanged', bounds_crs='unchanged', shape='unchanged')[source]¶ Return a copy of the AOI with the given values assigned.
Note
If you are assigning a new geometry and want bounds to updated as well, use
bounds="update"
. This will also changebounds_crs
to"EPSG:4326"
, since the geometry’s coordinates are in WGS84 decimal degrees, so the new bounds determined from those coordinates must be in that CRS as well.If you assign
geometry
without changingbounds
, the new AOI GeoContext will produce rasters with the same shape and covering the same spatial area as the old one, just with pixels masked out that fall outside your new geometry.Returns: new Return type: AOI

align_pixels
¶ If True, this ensures that, in different Scenes rasterized with this same AOI GeoContext, pixels
(i, j)
correspond to the same area in space. This is accomplished by snapping the coordinates of the origin (topleft corner of topleft pixel) to a nonfractional interval ofresolution
.If
align_pixels
is False, when using scenes with different native resolutions and/or projections, pixels at the same indicies can be misaligned by a fraction ofresolution
(i.e. correspond to slighly different coordinates in space).However, this requires warping of the original image, which can be undesireable when you want to work with the original data in its native resolution and projection.
Type: bool

bounds
¶ Clip scenes to these
(min_x, min_y, max_x, max_y)
bounds, expressed in the coordinate reference system inbounds_crs
.Type: tuple

bounds_crs
¶ The coordinate reference system of the
bounds
, given as an EPSG code (like"EPSG:4326"
), a PROJ.4 definition, or an OGC CRS WellKnown Text string.Type: str

crs
¶ Coordinate reference system into which scenes will be projected, expressed as an EPSG code (like
"EPSG:4326"
), a PROJ.4 definition, or an OGC CRS WellKnown Text stringType: str

geometry
¶ Clip scenes to this geometry Coordinates must be WGS84 (latlon) If None, scenes will just be clipped to
bounds
Type: shapely geometry

raster_params
¶ The properties of this AOI, as keyword arguments to use for
Raster.ndarray
orRaster.raster
.Raises ValueError if
self.bounds
,self.crs
,self.bounds_crs
,self.resolution
, orself.align_pixels
is None.Type: dict

resolution
¶ Distance, in units of the CRS, that the edge of each pixel represents on the ground.
Type: float

shape
¶ (rows, columns)
, in pixels, the output raster should fit within; the longer side of the raster will be min(shape).Type: tuple
 geometry (GeoJSONlike dict, object with

class
DLTile
(dltile_dict)[source]¶ A GeoContext that clips and projects Scenes to a single DLTile.
DLTiles allow you to define a grid of arbitrary spacing, resolution, and overlap that can cover the globe. DLTiles are always in a UTM projection.
__init__
instantiates a DLTile from a dict returned by Raster.dltile.It’s preferred to use the DLTile.from_latlon, DLTile.from_shape, or DLTile.from_key class methods to construct a DLTile GeoContext.

classmethod
from_key
(dltile_key, raster_client=None)[source]¶ Return a DLTile GeoContext from a DLTile key.
Parameters:  dltile_key (str) – DLTile key, e.g. ‘128:16:960.0:15:1:37’
 raster_client (descarteslabs.client.services.Raster, optional, default None) – Unneeded in general use; lets you use a specific client instance with nondefault auth and parameters.
Returns: tile
Return type:

classmethod
from_latlon
(lat, lon, resolution, tilesize, pad, raster_client=None)[source]¶ Return a DLTile GeoContext that covers a latitude/longitude
Where the point falls within the tile will vary, depending on the point and tiling parameters.
Parameters:  lat (float) – Latitude (WGS84)
 lon (float) – Longitude (WGS84)
 resolution (float) – Distance, in meters, that the edge of each pixel represents on the ground
 tilesize (int) – Length of each side of the tile, in pixels
 pad (int) – Number of extra pixels by which each side of the tile is buffered. This determines the number of pixels by which two tiles overlap.
 raster_client (descarteslabs.client.services.Raster, optional, default None) – Unneeded in general use; lets you use a specific client instance with nondefault auth and parameters.
Returns: tile
Return type:

classmethod
from_shape
(shape, resolution, tilesize, pad, raster_client=None)[source]¶ Return a list of DLTiles that intersect the given geometry
Parameters:  shape (GeoJSONlike) – A GeoJSON dict, or object with a __geo_interface__. Must be in EPSG:4326 (WGS84 latlon) projection.
 resolution (float) – Distance, in meters, that the edge of each pixel represents on the ground
 tilesize (int) – Length of each side of the tile, in pixels
 pad (int) – Number of extra pixels by which each side of the tile is buffered. This determines the number of pixels by which two tiles overlap.
 raster_client (descarteslabs.client.services.Raster, optional, default None) – Unneeded in general use; lets you use a specific client instance with nondefault auth and parameters.
Returns: tiles
Return type: List[DLTile]

bounds
¶ The
(min_x, min_y, max_x, max_y)
of the area covered by this DLTile, in the UTM coordinate reference system given inbounds_crs
.Type: tuple

bounds_crs
¶ The coordinate reference system of the
bounds
, given as an EPSG code (like"EPSG:32615"
). A DLTile’s CRS is always UTM.Type: str

crs
¶ Coordinate reference system into which scenes will be projected. For DLTiles, this is always a UTM projection, given as an EPSG code.
Type: str

geometry
¶ The polygon covered by this DLTile in WGS84 (latlon) coordinates
Type: shapely.geometry.Polygon

geotrans
¶ The 6tuple GDAL geotrans for this DLTile in the shape
(a, b, c, d, e, f)
where a is the top left pixel’s xcoordinate b is the westeast pixel resolution c is the row rotation, always 0 for DLTiles d is the top left pixel’s ycoordinate e is the column rotation, always 0 for DLTiles f is the northsouth pixel resolution, always a negative valueType: tuple

key
¶ The DLTile’s key, which encodes the tiling parameters, and which number in the grid this tile is.
Type: str

pad
¶ Number of extra pixels by which each side of the tile is buffered. This determines the number of pixels by which two tiles overlap.
Type: int

proj4
¶ PROJ.4 definition for this DLTile’s coordinate reference system
Type: str

raster_params
¶ The properties of this DLTile, as keyword arguments to use for Raster.ndarray or Raster.raster.
Type: dict

resolution
¶ Distance, in meters, that the edge of each pixel represents on the ground
Type: float

ti
¶ The yindex of this tile in its grid
Type: int

tilesize
¶ Length of each side of the tile, in pixels. Note that the total number of pixels along each side of an image is
tile_size + 2*padding
Type: int

tj
¶ The xindex of this tile in its grid
Type: int

wkt
¶ OGC WellKnown Text definition for this DLTile’s coordinate reference system
Type: str

zone
¶ The UTM zone of this tile
Type: int

classmethod

class
GeoContext
[source]¶ Specifies spatial parameters to use when loading a raster from the Descartes Labs catalog.
Two Scenes loaded with the same GeoContext will result in images with the same shape (in pixels), covering the same spatial extent, regardless of the dimensions or projection of the original data.
Specifically, a fullydefined GeoContext specifies:
 geometry to use as a cutline (WGS84), and/or bounds
 resolution (m)
 EPSG code of the output coordinate reference system
 whether to align pixels to the output CRS (see docstring for AOI.align_pixels for more information)
GeoContexts are immutable.

raster_params
¶ The properties of this GeoContext, as keyword arguments to use for Raster.ndarray or Raster.raster.
Type: dict

class
XYZTile
(x, y, z)[source]¶ A GeoContext for XYZ tiles, such as those used in web maps.
The tiles are always 256x256 pixels, in the spherical Mercator or “Web Mercator” coordinate reference system (EPSG:3857).
Requires the optional
mercantile
package.Parameters:  x (int) – Xindex of the tile (increases going east)
 y (int) – Yindex of the tile (increases going south)
 z (int) – Zoom level of the tile

bounds
¶ The
(min_x, min_y, max_x, max_y)
of the area covered by this XYZTile, in spherical Mercator coordinates (EPSG:3857).Type: tuple

bounds_crs
¶ The coordinate reference system of the
bounds
. Always"EPSG:3857"
(spherical Mercator, aka “Web Mercator”)Type: str

crs
¶ Coordinate reference system into which scenes will be projected. Always
"EPSG:3857"
(spherical Mercator, aka “Web Mercator”)Type: str

geometry
¶ The polygon covered by this XYZTile in WGS84 (latlon) coordinates
Type: shapely.geometry.Polygon

raster_params
¶ The properties of this XYZTile, as keyword arguments to use for Raster.ndarray or Raster.raster.
Type: dict

tilesize
¶ Length of each side of the tile, in pixels. Always 256.
Type: int

x
¶ Xindex of the tile (increases going east)
Type: int

y
¶ Yindex of the tile (increases going south)
Type: int

z
¶ Zoom level of the tile
Type: int