safe.storage.utilities module

Utilities for storage module

safe.storage.utilities.array_to_line(A, geometry_type=101)[source]

Convert coordinates to linear_ring

Parameters:
  • A (numpy.ndarray, list) – Nx2 Array of coordinates representing either a polygon or a line. A can be either a numpy array or a list of coordinates.
  • geometry_type (ogr.wkbLinearRing, include ogr.wkbLineString) – A valid OGR geometry type. Default type ogr.wkbLinearRing
Returns:
  • ring: OGR line geometry

Note: Based on http://www.packtpub.com/article/working-geospatial-data-python

safe.storage.utilities.array_to_wkt(A, geom_type='POLYGON')[source]

Convert coordinates to wkt format

Parameters:
  • A (numpy.array) – Nx2 Array of coordinates representing either a polygon or a line. A can be either a numpy array or a list of coordinates.
  • geom_type (str) – Determines output keyword ‘POLYGON’ or ‘LINESTRING’
Returns:

wkt: geometry in the format known to ogr: Examples

Note:
POLYGON((1020 1030,1020 1045,1050 1045,1050 1030,1020 1030)) LINESTRING(1000 1000, 1100 1050)
safe.storage.utilities.bbox_intersection(*args)[source]

Compute intersection between two or more bounding boxes.

Parameters:args – two or more bounding boxes. Each is assumed to be a list or a tuple with four coordinates (W, S, E, N)
Returns:The minimal common bounding box
safe.storage.utilities.buffered_bounding_box(bbox, resolution)[source]

Grow bounding box with one unit of resolution in each direction

Note:

This will ensure there are enough pixels to robustly provide interpolated values without having to painstakingly deal with all corner cases such as 1 x 1, 1 x 2 and 2 x 1 arrays.

The border will also make sure that points that would otherwise fall outside the domain (as defined by a tight bounding box) get assigned values.

Parameters:
  • bbox (list) – Bounding box with format [W, S, E, N]
  • resolution (tuple) – (resx, resy) - Raster resolution in each direction. res - Raster resolution in either direction If resolution is None bbox is returned unchanged.
Returns:

Adjusted bounding box

Note:
Case in point: Interpolation point O would fall outside this domain
even though there are enough grid points to support it
--------------
|            |
|   *     *  | *    *
|           O|
|            |
|   *     *  | *    *
--------------
safe.storage.utilities.calculate_polygon_area(polygon, signed=False)[source]

Calculate the signed area of non-self-intersecting polygon

Parameters:
  • polygon (numpy.ndarray) – Numeric array of points (longitude, latitude). It is assumed to be closed, i.e. first and last points are identical
  • signed (bool) –

    Optional flag deciding whether returned area retains its sign:

    If points are ordered counter clockwise, the signed area will be positive.

    If points are ordered clockwise, it will be negative Default is False which means that the area is always positive.

Returns:

area: Area of polygon (subject to the value of argument signed)

Return type:

numpy.ndarray

Note:
Sources
http://paulbourke.net/geometry/polyarea/ http://en.wikipedia.org/wiki/Centroid
safe.storage.utilities.calculate_polygon_centroid(polygon)[source]

Calculate the centroid of non-self-intersecting polygon

Parameters:polygon (numpy.ndarray) – Numeric array of points (longitude, latitude). It is assumed to be closed, i.e. first and last points are identical
Returns:calculated centroid
Return type:numpy.ndarray
safe.storage.utilities.check_geotransform(geotransform)[source]

Check that geotransform is valid

Parameters:geotransform (tuple) – GDAL geotransform (6-tuple). (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution). See e.g. http://www.gdal.org/gdal_tutorial.html

Note

This assumes that the spatial reference uses geographic coordinates, so will not work for projected coordinate systems.

safe.storage.utilities.combine_polygon_and_point_layers(layers)[source]

Combine polygon and point layers

Parameters:layers (list) – List of vector layers of type polygon or point
Returns:One point layer with all input point layers and centroids from all input polygon layers.
Return type:numpy.ndarray
Raises:InaSAFEError (in case attribute names are not the same.)
safe.storage.utilities.geometry_type_to_string(g_type)[source]

Provides string representation of numeric geometry types

Parameters:g_type (ogr.wkb*, None) – geometry type:

FIXME (Ole): I can’t find anything like this in ORG. Why?

safe.storage.utilities.geotransform_to_bbox(geotransform, columns, rows)[source]

Convert geotransform to bounding box

Parameters:
  • geotransform (tuple) – GDAL geotransform (6-tuple). (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution). See e.g. http://www.gdal.org/gdal_tutorial.html
  • columns (int) – Number of columns in grid
  • rows (int) – Number of rows in grid
Returns:

bbox: Bounding box as a list of geographic coordinates [west, south, east, north]

Note

Rows and columns are needed to determine eastern and northern bounds. FIXME: Not sure if the pixel vs gridline registration issue is observed correctly here. Need to check against gdal > v1.7

safe.storage.utilities.geotransform_to_resolution(geotransform, isotropic=False)[source]

Convert geotransform to resolution

Parameters:
  • geotransform (tuple) – GDAL geotransform (6-tuple). (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution). See e.g. http://www.gdal.org/gdal_tutorial.html
  • isotropic (bool) – If True, return the average (dx + dy) / 2
Returns:

resolution: grid spacing (res_x, res_y) in (positive) decimal degrees ordered as longitude first, then latitude. or (res_x + res_y) / 2 (if isotropic is True)

safe.storage.utilities.get_geometry_type(geometry, geometry_type)[source]

Determine geometry type based on data

Parameters:
  • geometry (list) – A list of either point coordinates [lon, lat] or polygons which are assumed to be numpy arrays of coordinates
  • geometry_type (str, None) – Optional type - ‘point’, ‘line’, ‘polygon’ or None
Returns:

geometry_type: Either ogr.wkbPoint, ogr.wkbLineString or ogr.wkbPolygon

Note:

If geometry type cannot be determined an Exception is raised.

There is no consistency check across all entries of the geometry list, only the first element is used in this determination.

safe.storage.utilities.get_polygon_data(G)[source]

Extract polygon data from OGR geometry

Parameters:G – OGR polygon geometry
Returns:List of InaSAFE polygon instances
safe.storage.utilities.get_ring_data(ring)[source]

Extract coordinates from OGR ring object

Parameters:ring – OGR ring object
Returns:Nx2 numpy array of vertex coordinates (lon, lat)
Return type:numpy.array
safe.storage.utilities.is_sequence(x)[source]

Determine if x behaves like a true sequence but not a string

Parameters:x (object) – Sequence like object
Returns:Test result
Return type:bool
Note:
This will for example return True for lists, tuples and numpy arrays but False for strings and dictionaries.
safe.storage.utilities.minimal_bounding_box(bbox, min_res, eps=1e-06)[source]

Grow bounding box to exceed specified resolution if needed

Parameters:
  • bbox (list) – Bounding box with format [W, S, E, N]
  • min_res (float) – Minimal acceptable resolution to exceed
  • eps (float) – Optional tolerance that will be applied to ‘buffer’ result
Returns:

Adjusted bounding box guaranteed to exceed specified resolution

safe.storage.utilities.points_along_line(line, delta)[source]

Calculate a list of points along a line with a given delta

Parameters:
  • line (numpy.ndarray) – Numeric array of points (longitude, latitude).
  • delta (float) – Decimal number to be used as step
Returns:

Numeric array of points (longitude, latitude).

Return type:

numpy.ndarray

Note:
Sources
http://paulbourke.net/geometry/polyarea/ http://en.wikipedia.org/wiki/Centroid
safe.storage.utilities.points_between_points(point1, point2, delta)[source]

Creates an array of points between two points given a delta

Parameters:
  • point1 (numpy.ndarray) – The first point
  • point2 (numpy.ndarray) – The second point
  • delta (float) – The increment between inserted points
Returns:

Array of points.

Return type:

numpy.ndarray

Note:
u = (x1-x0, y1-y0)/L, where L=sqrt( (x1-x0)^2 + (y1-y0)^2). If r is the resolution, then the points will be given by (x0, y0) + u * n * r for n = 1, 2, .... while len(n*u*r) < L
safe.storage.utilities.raster_geometry_to_geotransform(longitudes, latitudes)[source]

Convert vectors of longitudes and latitudes to geotransform

Note:
This is the inverse operation of Raster.get_geometry().
Parameters:
  • longitudes – Vectors of geographic coordinates
  • latitudes – Vectors of geographic coordinates
Returns:

geotransform: 6-tuple (top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution)

safe.storage.utilities.read_keywords(keyword_filename, sublayer=None, all_blocks=False)[source]

Read keywords dictionary from file

Parameters:
  • keyword_filename (str) – Name of keywords file. Extension expected to be .keywords or .xml metadata. The format of one line is expected to be either string: string or string
  • sublayer (str) – Optional sublayer applicable only to multilayer formats such as sqlite or netcdf which can potentially hold more than one layer. The string should map to the layer group as per the example below. If the keywords file contains sublayer definitions but no sublayer was defined, the first layer group will be returned.
  • all_blocks (bool) – Optional, defaults to False. If True will return a dict of dicts, where the top level dict entries each represent a sublayer, and the values of that dict will be dicts of keyword entries.
Returns:

keywords: Dictionary of keyword, value pairs

A keyword layer with sublayers may look like this:

[osm_buildings] datatype: osm category: exposure subcategory: building purpose: dki title: buildings_osm_4326

[osm_flood] datatype: flood category: hazard subcategory: building title: flood_osm_4326

Whereas a simple keywords file would look like this

datatype: flood category: hazard subcategory: building title: flood_osm_4326

If filename does not exist, an empty dictionary is returned Blank lines are ignored Surrounding whitespace is removed from values, but keys are unmodified If there are no ‘:’, then the keyword is treated as a key with no value

safe.storage.utilities.rings_equal(x, y, rtol=1e-06, atol=1e-08)[source]

Compares to linear rings as numpy arrays

Parameters:
  • x (numpy.ndarray) – A 2d array of the first ring
  • y (numpy.ndarray) – A 2d array of the second ring
  • rtol (float) – The relative tolerance parameter
  • atol – The relative tolerance parameter
Returns:
  • True if x == y or x’ == y (up to the specified tolerance)

where x’ is x reversed in the first dimension. This corresponds to linear rings being seen as equal irrespective of whether they are organised in clock wise or counter clock wise order

safe.storage.utilities.safe_to_qgis_layer(layer)[source]

Helper function to make a QgsMapLayer from a safe read_layer layer.

Parameters:layer (read_layer) – Layer object as provided by InaSAFE engine.
Returns:A validated QGIS layer or None. Returns None when QGIS is not available.
Return type:QgsMapLayer, QgsVectorLayer, QgsRasterLayer, None
Raises:Exception if layer is not valid.
safe.storage.utilities.write_keywords(keywords, filename, sublayer=None)[source]

Write keywords dictonary to file

Parameters:
  • keywords (dict) – Dictionary of keyword, value pairs
  • filename (str) – Name of keywords file. Extension expected to be .keywords
  • sublayer (str) – Optional sublayer applicable only to multilayer formats such as sqlite or netcdf which can potentially hold more than one layer. The string should map to the layer group as per the example below. If the keywords file contains sublayer definitions but no sublayer was defined, keywords file content will be removed and replaced with only the keywords provided here.

A keyword file with sublayers may look like this:

[osm_buildings] datatype: osm category: exposure subcategory: building purpose: dki title: buildings_osm_4326

[osm_flood] datatype: flood category: hazard subcategory: building title: flood_osm_4326

Keys must be strings not containing the ”:” character Values can be anything that can be converted to a string (using Python’s str function)

Surrounding whitespace is removed from values, but keys are unmodified The reason being that keys must always be valid for the dictionary they came from. For values we have decided to be flexible and treat entries like ‘unit:m’ the same as ‘unit: m’, or indeed ‘unit: m ‘. Otherwise, unintentional whitespace in values would lead to surprising errors in the application.