gnome.maps.map

GNOME land-water map.

Maps for the GNOME Model – maps are responsible for determining where / when elements impact the shoreline

The module includes a base map that is all water – no land, As well as a few implementations of actual maps

Module Contents

Classes

GnomeMap

The very simplest map for GNOME -- all water

ParamMap

The very simplest map for GNOME -- all water

RasterMap

A land water map implemented as a raster

MapFromBNA

A raster land-water map, created from file with polygons in it.

MapFromUGrid

A raster land-water map, created from netcdf File of a UGrid

Functions

ShiftLon360(points)

ShiftLon180(points)

map_from_rectangular_grid(mask, lon, lat[, refine])

Suitable for a rectangular, but not fully regular, grid

grid_from_nc(filename)

generates a grid_mask and lat lon from a conforming netcdf file

map_from_rectangular_grid_nc_file(filename[, refine])

builds a raster map from a rectangular grid in a netcdf file

refine_axis(old_axis, refine)

refines the axis be interpolating points between each axis points

map_from_regular_grid(grid_mask, lon, lat[, refine, ...])

note: untested -- here to save it in case we need it in the future

class gnome.maps.map.GnomeMap(map_bounds=None, spillable_area=None, land_polys=None, **kwargs)

Bases: gnome.gnomeobject.GnomeId

The very simplest map for GNOME – all water with only a bounding box for the map bounds.

This also serves as a description of the interface and base class for more complex maps

The __init__ will be different for other implementations

Parameters:
  • map_bounds – The polygon bounding the map if any elements are outside the map bounds, they are removed from the simulation.

  • spillable_area (Either a PolygonSet object or a list of lists from which a polygon set can be created. Each element in the list is a list of points defining a polygon.) – The PolygonSet bounding the spillable_area.

  • land_polys (Either a PolygonSet object or a list of lists from which a polygon set can be created. Each element in the list is a list of points defining a polygon.) – The PolygonSet holding the land polygons

Note on ‘map_bounds’:

[(lon, lat), (lon, lat), (lon, lat), .. An NX2 array of points that describe a polygon if no map bounds is provided – the whole world is valid

property map_bounds

Bounds of the map – an NX2 array of float describing a polygon.

[(lon, lat), (lon, lat), …]

property spillable_area

List of polygons defining the region in which it is legal to set spills

property land_polys

Sequence of polygons surrounding land – mostly used for rendering.

_schema
refloat_halflife
_ref_as = 'map'
__add__(other)
get_polygons()
_attr_from_list_to_array(l_)

dict returned as list of tuples to be converted to numpy array Again used to update_from_dict map_bounds and spillable_area

get_map_bounding_box()

return a bounding box of the map

needed because map_bounds can be a polygon

bounding box is a 2x2 tuple:

((left, bottom), (right, top))

on_map(coords)

Determine whether points are on the map or not

Parameters:

coords (NX3 numpy array of floats: (long, lat, depth) or something that can be turned into one.) – location for test.

Returns:

bool array: True if the location is on the map, False otherwise

Note:

coords are 3-d, but the concept of “on the map” is 2-d in this context, so depth is ignored.

on_land(coord)
Parameters:

coord (3-tuple of floats: (long, lat, depth)) – location for test.

Returns:

  • Always returns False– no land in this implementation

in_water(coords)

Determines if the points are in water (rather than on land)

Parameters:

coords (3-tuple of floats: (long, lat, depth) or an Nx3 array) – location for test.

Returns:

  • True if the point is in the water,

  • False if the point is on land (or off map?)

This implementation has no land, so always True in on the map.

allowable_spill_position(coord)
Parameters:

coord (3-tuple of floats: (long, lat, depth)) – location for test.

Returns:

  • True if the point is an allowable spill position

  • False if the point is not an allowable spill position

Note

it could be either off the map, or in a location that spills aren’t allowed

_set_off_map_status(sc)

Determines which elements moved off the map

Called by beach_elements after checking for land-hits

Parameters:

sc (gnome.spill_container.SpillContainer) – current SpillContainer

beach_elements(sc, model_time=None)

Determines which LEs were or weren’t beached or moved off_map. status_code is changed to oil_status.off_maps if off the map.

Called by the model in the main time loop, after all movers have acted.

Parameters:

sc (gnome.spill_container.SpillContainer) – current SpillContainer

This map class has no land, so only the map check and resurface_airborn elements is done: noting else changes.

subclasses that override this probably want to make sure that:

self.resurface_airborne_elements(sc) self._set_off_map_status(sc)

are called.

refloat_elements(spill_container, time_step, model_time=None)

This method performs the re-float logic – changing the element status flag, and moving the element to the last known water position

Parameters:

spill_container (gnome.spill_container.SpillContainer) – current SpillContainer

Note

This map class has no land, and so is a no-op.

resurface_airborne_elements(spill_container)

Takes any elements that are left above the water surface (z < 0.0) and puts them on the surface (z == 0.0)

Parameters:

spill_container (gnome.spill_container.SpillContainer) – current SpillContainer

Note

While this shouldn’t occur according to the physics we’re modeling, some movers may push elements up too high, or multiple movers may add vertical movement that adds up to over the surface. e.g rise velocity.

to_geojson()
class gnome.maps.map.ParamMap(center=(0.0, 0.0), distance=30000, bearing=90, units=None, **kwargs)

Bases: GnomeMap

The very simplest map for GNOME – all water with only a bounding box for the map bounds.

This also serves as a description of the interface and base class for more complex maps

Creates a parameratized map, essentially a straight shoreline set a certain distance and bearing from a location, usually a spill. It is up to the user to put the spill and the map center in the same location.

Required arguments:

Parameters:
  • center – tuple of coordinates describing the center point of the map

  • distance – The distance in meters the closest point on the shoreline is from the center

  • bearing – The bearing the closest point on the shoreline is from the center.

property distance
_schema
_valid_dist_units
build(center, distance, bearing, units)
_check_units(units)

Checks the user provided units are in list of valid volume or mass units

get_map_bounds()
get_land_polygon()
on_map(coord)
Parameters:

coord (3-tuple of floats: (long, lat, depth)) – location for test.

Returns:

bool array: True if the location is on the map, False otherwise

Note:

coord is 3-d, but the concept of “on the map” is 2-d in this context, so depth is ignored.

on_land(coord)
Parameters:

coord (3-tuple of floats: (long, lat, depth) or Nx3 numpy array) – location for test.

Returns:

  • Always returns False– no land in this implementation

in_water(coord)
Parameters:

coord (3-tuple of floats: (long, lat, depth)) – location for test.

Returns:

  • True if the point is in the water,

  • False if the point is on land (or off map?)

This implementation has no land, so always True in on the map.

allowable_spill_position(coord)
Parameters:

coord (3-tuple of floats: (long, lat, depth)) – location for test.

Returns:

  • True if the point is an allowable spill position

  • False if the point is not an allowable spill position

Note

it could be either off the map, or in a location that spills aren’t allowed

find_last_water_pos(starts, ends)
beach_elements(sc, model_time=None)

Determines which LEs were or weren’t beached or moved off_map. status_code is changed to oil_status.off_maps if off the map.

Called by the model in the main time loop, after all movers have acted.

Parameters:

sc (gnome.spill_container.SpillContainer) – current SpillContainer

This map class does not use a raster map for collision detection. Since the land is so simple the collisions are detected via intersection.

refloat_elements(spill_container, time_step, model_time=None)

This method performs the re-float logic – changing the element status flag, and moving the element to the last known water position

Parameters:

spill_container (gnome.spill_container.SpillContainer) – the current spill container

update_from_dict(data)
to_geojson()
class gnome.maps.map.RasterMap(raster=None, projection=None, refloat_halflife=1, **kwargs)

Bases: GnomeMap

A land water map implemented as a raster

This one uses a numpy array of uint8, so there are 8 bits to choose from…

It requires a constant refloat half-life in hours

This will usually be initialized in a sub-class (from a BNA, etc) NOTE: Nothing new added to _state attribute for serialization

create a new RasterMap

Parameters:
  • raster (a (W,H) numpy array of type uint8) – A numpy array that stores the land-water map 0 is water. 1 is land. In theory, other values could be used for other purposes. If the array is not C-contiguous, it will be copied to a C-contiguus array.

  • projection (gnome.map_canvas.Projection) – A Projection object – used to convert from lat-long to pixels in the array

Optional arguments (kwargs)

Parameters:
  • refloat_halflife (float. Units are hours) – The halflife for refloating off land – assumed to be the same for all land. 0.0 means all refloat every time step < 0.0 means never re-float.

  • map_bounds ((N,2) numpy array of floats) – The polygon bounding the map – could be larger or smaller than the land raster

  • spillable_area ((N,2) numpy array of floats) – The polygon bounding the spillable_area

  • id (string) – unique ID of the object. Using UUID as a string. This is only used when loading object from save file.

property ratios
property raster
property refloat_halflife
property approximate_raster_interval
seconds_in_hour
land_flag = 1
build_coarser_rasters()

Builds the list which contains the different resolution raster maps. Scale -> raster example for base map of 1024 x 1024: 0 -> 1/16th raster 64 base cells per cell 1 -> 1/32nd raster 32:1 2 -> 1/64th raster 16:1 3 -> 1/128th raster 8:1 4 -> 1/256th raster 4:1 5 -> 1/512th raster 2:1 6 -> 1/1024th raster (== base map 1:1)

The general idea is that the particle position (an int) can quickly be mapped into any scale and the path can begin from there. For example, if your path begins offshore and ends in a narrow inlet, your scale might begin on the 32:1 map. But as soon as the path crosses into the (32:1) raster cell containing the inlet (which will register as a land cell on that raster), the scale will decrease to 4:1, when the cell is completely water. In the end, if the scale decreases to 1:1 and there’s still a land hit, then land was hit.

save_as_image(filename)

Save the land-water raster as a PNG save_as_image

Parameters:

filename – the name of the file to save to.

_off_raster(coord)

are these pixel coordinates on the raster

We can’t just use an IndexError, as negative indexes can be legal with numpy, but aren’t expected here.

_on_land_pixel(coord)

returns 1 if the point is on land, 0 otherwise

Parameters:

coord (tuple: (row, col)) – pixel coordinates of point of interest

Note

Only used internally or for testing – no need for external API to use pixel coordinates.

on_land(coord)
Parameters:

coord (3-tuple of floats -- (long, lat, depth)) – (long, lat, depth) location – depth is ignored here.

Returns:

  • 1 if point on land

  • 0 if not on land

Note

to_pixel() converts to array of points…

_in_water_pixel(coord)
in_water(coord)
checks if it’s on the map, first.

(depth is ignored in this version)

Parameters:

coord – (lon, lat, depth) coordinate

Returns:

true if the point given by coord is in the water

beach_elements(sc, model_time=None)

Determines which elements were or weren’t beached.

Any that are beached have the beached flag set, and a “last known water position” (lkwp) is computed

This version uses a modified Bresenham algorithm to find out which pixels the LE may have crossed.

Parameters:

sc (gnome.spill_container.SpillContainer It must have the following data arrays: (‘prev_position’, ‘positions’, ‘last_water_pt’, ‘status_code’)) – the current spill container

refloat_elements(spill_container, time_step, model_time=None)

This method performs the re-float logic – changing the element status flag, and moving the element to the last known water position

Parameters:

spill_container (gnome.spill_container.SpillContainer) – the current spill container

_check_land_layers(raster_map_layers, ratios, positions, end_positions, status_codes, last_water_positions)

Do the actual land-checking. This method simply calls a Cython version:

gnome.cy_gnome.cy_land_check.check_land()

The arguments ‘status_codes’, ‘positions’ and ‘last_water_positions’ are altered in place.

allowable_spill_position(coord)

Returns true if the spill position is in the allowable spill area

Note

This may not be the same as in_water!

Parameters:

coord – (lon, lat, depth) coordinate

to_pixel_array(coords)

Projects an array of (lon, lat) tuples onto the raster, and modifies it in place to hold the corresponding projected values.

Parameters:

coords – a numpy array of (lon, lat, depth) points

Returns:

a numpy array of (x, y) pixel values

gnome.maps.map.ShiftLon360(points)
gnome.maps.map.ShiftLon180(points)
class gnome.maps.map.MapFromBNA(filename, raster_size=4096 * 4096, map_bounds=None, spillable_area=None, shift_lons=0, **kwargs)

Bases: RasterMap

A raster land-water map, created from file with polygons in it.

Currently only support BNA, but could be shapefile, or ???

Creates a RasterMap from a data file. It is expected that you will get the spillable area and map bounds from the data file – if they exist

Required arguments:

Parameters:
  • filename – full path to the data file

  • raster_size (integer) – the total number of pixels (bytes) to make the raster – the actual size will match the aspect ratio of the bounding box of the land

  • shiftLons (integer) – shift longitudes to be in -180 to 180 coords or 0 to 360. 180, or 360 are valid inputs

Optional arguments (kwargs):

Parameters:
  • refloat_halflife – the half-life (in hours) for the re-floating.

  • map_bounds – The polygon bounding the map – could be larger or smaller than the land raster

  • spillable_area – The polygon bounding the spillable_area

  • id (string) – unique ID of the object. Using UUID as a string. This is only used when loading object from save file.

property raster_size

Maximum physical size of the raster in bytes

_schema
build_raster(land_polys=None, BB=None)

Build the underlying raster used for the map

This should be called if the resolution or land polygons change

to_geojson()

Output the vector version of the shoreline polygons.

This is what gets drawn in the WebGNOME client, for example

This version directly writes the polygons already stored in the map object – keeping the door open to that data coming from something other than a bna file.

FIXME: Technically, geojson recommends ccw polygons – but putting that

check in was pretty slow, so it’s commented out.

FIXME: This really should export the map_bounds and spillable_area as well.

class gnome.maps.map.MapFromUGrid(filename, raster_size=1024 * 1024, **kwargs)

Bases: RasterMap

A raster land-water map, created from netcdf File of a UGrid

Creates a GnomeMap (specifically a RasterMap) from a netcdf data file with a triangular mesh grid in it. The spillable area and map bounds need to be supplied – there is currently no way to express that in a netcdf file.

Required arguments:

Parameters:
  • filename – full path to the data file

  • refloat_halflife – the half-life (in hours) for the re-floating.

  • raster_size (integer) – the total number of pixels (bytes) to make the raster – the actual size will match the aspect ratio of the bounding box of the land

Optional arguments (kwargs):

Parameters:
  • map_bounds – The polygon bounding the map – could be larger or smaller than the land raster

  • spillable_area – The polygon bounding the spillable_area

  • id (string) – unique ID of the object. Using UUID as a string. This is only used when loading object from save file.

_schema
gnome.maps.map.map_from_rectangular_grid(mask, lon, lat, refine=1, **kwargs)

Suitable for a rectangular, but not fully regular, grid

Such that it can be described by single longitude and latitude vectors

Parameters:
  • mask – the land-water mask as a numpy array

  • lon – longitude array

  • lon – latitude array

  • refine=1 – amount to refine grid – 4 will give 4 times the resolution

  • kwargs – Other keyword arguments are passed on to RasterMap

gnome.maps.map.grid_from_nc(filename)

generates a grid_mask and lat lon from a conforming netcdf file

NOTE: poorly tested, and will only work on a regular grid

gnome.maps.map.map_from_rectangular_grid_nc_file(filename, refine=1, **kwargs)

builds a raster map from a rectangular grid in a netcdf file

only tested with the HYCOM grid

Parameters:
  • filename (string) – the full path or opendap url for the netcdf file

  • refine (integer) – how much to refine the grid. 1 means keep it as it is, otherwise is will scale

  • kwargs – other key word arguemnts – passed on to RasterMap class constructor

gnome.maps.map.refine_axis(old_axis, refine)

refines the axis be interpolating points between each axis points

Parameters:
  • old_axis (1-d numpy array of floats) – the axis values

  • refine (integer) – amount to refine grid – 4 will give 4 times the resolution

gnome.maps.map.map_from_regular_grid(grid_mask, lon, lat, refine=4, refloat_halflife=1, map_bounds=None)

note: untested – here to save it in case we need it in the future

makes a raster map from a regular grid: i.e delta_lon and delta-lat are constant.