Rasters

Overview

Several methods compute values on a regular grid of square cells and return the grid as points:

Function

Points returned with

Columns and the value of a cell

objectnat.get_insolation()

always

sun_hours, min_sun_hours, max_continuous_hours: direct sun at the receiver, hours per day

objectnat.simulate_noise_grid()

output="receivers" or "both"

noise_level: sound level at the receiver, dB

objectnat.get_visibility_catchment(), objectnat.get_viewshed_catchment()

always

count: the number of observers that see the cell (weight: the sum of their weights)

objectnat.get_isovist_grid()

always

isovist metrics of an observer standing in the cell: visible_share (share of the view disc), compactness, occlusivity (m), drift (m), …

For noise, output="receivers" skips the level bands, which is faster when only the values are needed.

objectnat.rasterize() turns one column of such points into a objectnat.Raster: a 2-D array with an affine transform and a CRS. A raster shows a continuous quantity cell by cell, without the class bounds of the zone polygons, and it can be drawn with matplotlib, written to a GeoTIFF file or shown on a folium web map.

Method

The grid methods record their grid in the attrs of the returned points: the local metric CRS of the calculation (a UTM zone), the cell size and the position of one cell centre. objectnat.rasterize() reprojects the points to that CRS, assigns every point to its cell and fills cells without a point (buildings, cells below target_noise_db, cells seen by nobody) with NaN. The raster reproduces the calculation grid exactly, in whatever CRS the points were returned, and also after rows were filtered. Points without the record, for example read from a file, require cell_size; they are then placed in their own projected CRS or in an estimated UTM zone.

objectnat.Raster is the tuple (values, transform, crs). values has the northern row first; transform contains the affine coefficients (a, b, c, d, e, f) in the order of rasterio and GDAL. It is also the format of terrain arguments, so a raster can be passed back as terrain.

  • plot(ax, **imshow_kwargs) draws it with imshow in the raster CRS. Other layers on the same axes must be reprojected to raster.crs.

  • to_geotiff(path) writes a float32 GeoTIFF (requires rasterio).

  • to_folium(cmap=..., vmin=..., vmax=..., opacity=...) returns a folium.raster_layers.ImageOverlay. Web maps draw images in Web Mercator, so the grid is resampled to a Mercator grid with about the same number of cells (nearest cell) and coloured with a matplotlib colormap; cells without a value are transparent. The overlay can be added to any folium map, including the maps of GeoDataFrame.explore() (requires folium and matplotlib).

  • explore(m=None, cmap=..., vmin=..., vmax=..., name=...) does the same on a new map (or on m) and adds a colour bar, like GeoDataFrame.explore().

from objectnat import get_insolation, rasterize

receivers = get_insolation(buildings, "2026-03-21", area=area)
sun = rasterize(receivers, "sun_hours")

image = sun.plot(cmap="inferno", vmin=0, vmax=14)          # matplotlib
sun.to_geotiff("sun_hours_2026-03-21.tif")                 # GIS
sun.explore(cmap="inferno", vmin=0, vmax=14, name="sun hours")   # web map with a colour bar
m = buildings.explore(color="grey")                               # or on top of another map
sun.explore(m, cmap="inferno", vmin=0, vmax=14, name="sun hours")
objectnat.rasterize(points, column, *, cell_size=None)[source]

Turn grid points with values into a Raster, one cell per point.

Grid points are what the grid methods return: receivers of get_insolation() and of simulate_noise_grid() (output="receivers" or "both"), the cells of get_visibility_catchment() and get_viewshed_catchment() and the points of get_isovist_grid(). Their attrs record the grid (CRS, cell size, position), so the raster reproduces it exactly in the local metric CRS of the calculation, whatever CRS the points were returned in, and also after filtering rows.

Points without that record (for example, read from a file) require cell_size; they are then placed in their own CRS if it is projected, or in an estimated UTM zone, with the first point as a cell centre.

Parameters:
  • points (GeoDataFrame) – Point GeoDataFrame on a regular grid.

  • column (str) – Numeric (or boolean) column to put into the cells.

  • cell_size (float | None) – Cell side in metres, for points without grid attrs.

Return type:

Raster

Returns:

Raster covering the points; cells without a point are NaN.

Examples

>>> receivers = get_insolation(buildings, "2026-03-21")
>>> raster = rasterize(receivers, "sun_hours")
>>> raster.plot(cmap="inferno", vmin=0, vmax=14)
>>> raster.explore(cmap="inferno", vmin=0, vmax=14, name="sun hours")
>>> raster.to_geotiff("sun_hours.tif")
class objectnat.Raster(values, transform, crs)[source]

Values on a north-up grid of square cells, as returned by rasterize().

It is the tuple (values, transform, crs) that terrain arguments accept, so it can be passed back as terrain, written with rasterio, or drawn with matplotlib.

Parameters:
values

(rows, cols) float array; row 0 is the northern edge, NaN marks cells without a value.

transform

Affine coefficients (a, b, c, d, e, f) as in rasterio and GDAL: the upper-left corner of cell (row, col) is x = c + a * col, y = f + e * row (b = d = 0, e = -a).

crs

Projected CRS of the grid (metres).

property cell_size: float

Cell side in metres.

property bounds: tuple[float, float, float, float]

(minx, miny, maxx, maxy) of the grid.

property extent: tuple[float, float, float, float]

(left, right, bottom, top), the extent argument of matplotlib.pyplot.imshow.

plot(ax=None, **kwargs)[source]

Draw the raster with ax.imshow in the CRS of the grid (cells without a value stay transparent).

Keyword arguments go to imshow (cmap, vmin, vmax, alpha, …). Layers drawn on the same axes must be in crs, e.g. buildings.to_crs(raster.crs).plot(ax=ax). Requires matplotlib.

Returns:

The AxesImage, e.g. for fig.colorbar.

to_geotiff(path, *, nodata=nan)[source]

Write a single-band float32 GeoTIFF; cells without a value get nodata. Requires rasterio.

Return type:

None

Parameters:

nodata (float)

to_folium(*, cmap='viridis', vmin=None, vmax=None, opacity=0.75, name=None, **kwargs)[source]

Colour the raster and return it as a folium.raster_layers.ImageOverlay for a web map.

Web maps show images in Web Mercator, so the grid is resampled (nearest cell) to a Mercator grid with about the same number of cells before colouring; the overlay then lines up with the base map. Add it with .add_to(m), e.g. to a map from GeoDataFrame.explore(). Requires folium and matplotlib.

Parameters:
  • cmap – Matplotlib colormap or its name.

  • vmin (float | None) – Colour scale limits (default: minimum and maximum of the values).

  • vmax (float | None) – Colour scale limits (default: minimum and maximum of the values).

  • opacity (float) – Opacity of the overlay, 0-1. Cells without a value are transparent.

  • name (str | None) – Layer name in folium.LayerControl.

  • **kwargs – Passed to ImageOverlay.

explore(m=None, *, cmap='viridis', vmin=None, vmax=None, opacity=0.75, name=None, legend=True, caption=None, tiles=None, **kwargs)[source]

Show the raster on an interactive folium map, like GeoDataFrame.explore().

Parameters:
  • m – Existing folium.Map to add the layer to, e.g. buildings.explore(); a new map centred on the raster when None.

  • cmap – As in to_folium().

  • vmin (float | None) – As in to_folium().

  • vmax (float | None) – As in to_folium().

  • opacity (float) – As in to_folium().

  • name (str | None) – As in to_folium().

  • legend (bool) – Add a colour bar.

  • caption (str | None) – Colour bar caption (default name).

  • tiles – Base map of a new map: a name or URL as in folium.Map, or a folium.TileLayer. Defaults to a light grey map (Esri World Light Gray Canvas), whose tiles end at zoom 16 and are stretched beyond.

  • **kwargs – Passed to folium.Map when a new map is created.

Returns:

The folium.Map. Requires folium and matplotlib.

Limitations

  • A raster has the resolution of the calculation grid; finer rasters require a smaller grid_step or cell_size in the calculation itself.

  • to_folium embeds the image in the map as a PNG, so very large rasters produce large HTML files; for large areas, write a GeoTIFF and serve it as tiles.

  • Points without grid attrs must lie on a regular grid of the given cell_size.

Example notebooks

Insolation: sun hours on the ground and on facades (sun hours as rasters and on a web map), Noise simulation (receiver levels), 2D visibility: visibility polygons, isovist metrics and catchment (isovist field, 2D catchment raster) and 2.5D visibility: viewsheds and viewshed catchment (2.5D catchment raster).