Source code for mapio.multiple

from gridbase import Grid
from dataset import DataSetException
from grid2d import Grid2D
import abc
from collections import OrderedDict

[docs]class MultiGrid(Grid): reqfields = set(['xmin','xmax','ymin','ymax','xdim','ydim','ncols','nrows']) def __init__(self,layers,descriptions=None): """ Construct a semi-abstract MultiGrid object, which can contain many 2D layers of gridded data, all at the same resolution and with the same extent. :param layers: OrderedDict of Grid2D objects. :param descriptions: list of layer descriptions, or None :raises DataSetException: When: - input layer geodicts does not contain required keys - input layer geodicts do not match each other. - length of descriptions (when not None) does not match length of layers - input layers is not an OrderedDict """ if not isinstance(layers,OrderedDict): raise DataSetException('Input layers must be of type OrderedDict.') if descriptions is None: descriptions = ['' for l in layers.keys()] if len(descriptions) != len(layers): raise DataSetException('List of descriptions does not match length of layers.') lnames = layers.keys() for i in range(0,len(lnames)): layername = lnames[i] layer = layers[layername] desc = descriptions[i] geodict = layer.getGeoDict() if not set(geodict.keys()).issuperset(self.reqfields): missing = self.reqfields - set(geodict.keys()) raise DataSetException('Missing required keys "%s"' % str(missing)) self._layers[layername] = layer self._descriptions[layername] = desc @abc.abstractmethod
[docs] def save(self,filename): """ Save layers of data to a file :param filename: File to save data to. """ raise NotImplementedError("save method not implemented in MultiGrid") #subclassed implementation should be a @classmethod
@abc.abstractmethod
[docs] def load(self,filename): """ Load layers of data from a file :param filename: File to load data from. """ raise NotImplementedError("save method not implemented in MultiGrid")
[docs] def setLayer(self,name,data,desc=None): """ Add a 2D layer of data to a MultiGrid object. :param name: String which will be used to retrieve the data. :param data: 2D numpy array of data :param desc: Optional text description of layer :raises DataSetException: If the data layer dimensions don't match the geodict. """ nr,nc = data.shape if nr != self._geodict['nrows'] or nc != self._geodict['ncols']: raise DataSetException("Data layer dimensions don't match those already in the grid") self._layers[name] = Grid2D(data,self._geodict.copy()) self._descriptions[name] = desc
[docs] def getLayer(self,name): """ Retrieve the 2D associated with a layer name. :param name: Name of data layer. :returns: Grid2D object. :raises DataSetException: When name is not found in list of layer names. """ if name not in self._layers.keys(): raise DataSetException('Layer "%s" not in list of layers.' % name) return self._layers[name]
[docs] def getData(self): """ Return the OrderedDict of data layers contained in MultiGrid. :returns: OrderedDict of Grid2D objects. """ return self._layers
[docs] def setData(self,layers,descriptions=None): """ Return the OrderedDict of data layers contained in MultiGrid. :param layers: OrderedDict of Grid2D objects. """ self._layers = layers layernames = layers.keys() self._geodict = layers[layernames[0]].getGeoDict().copy()
[docs] def getGeoDict(self): """ Return the geodict object which defines the extent and resolution of all the grids. :returns: geodict dictionary (see constructor) """ return self._geodict
[docs] def getBounds(self): """ Return the lat/lon range of the data. :returns: Tuple of (lonmin,lonmax,latmin,latmax) """ return (self._geodict['xmin'],self._geodict['xmax'],self._geodict['ymin'],self._geodict['ymax'])
[docs] def trim(self,bounds,resample=False,method='linear'): """ Trim all data layers to a smaller set of bounds, resampling if requested. If not resampling, data will be trimmed to smallest grid boundary possible. :param bounds: Tuple of (lonmin,lonmax,latmin,latmax) :param resample: Boolean indicating whether the data should be resampled to *exactly* match input bounds. :param method: If resampling, method used, one of ('linear','nearest','cubic','quintic') """ for layername,layer in self._layers.iteritems(): layer.trim(bounds,resample=resample,method=method) self._geodict = layer.getGeoDict().copy()
[docs] def getLayerNames(self): """ Return the list of layer names contained in the MultiGrid. :returns: List of layer names. """ return self._layers.keys()
[docs] def getValue(self,lat,lon,layername,method='nearest',default=None): """Return numpy array at given latitude and longitude (using nearest neighbor). :param lat: Latitude (in decimal degrees) of desired data value. :param lon: Longitude (in decimal degrees) of desired data value. :param layername: Name of layer from which to retrieve data. :param method: Interpolation method, one of ('nearest','linear','cubic','quintic') :param default: Default value to return when lat/lon is outside of grid bounds. :return: Value at input latitude,longitude position. """ return self._layers[layername].getValue(lat,lon,method=method,default=default)
[docs] def getLatLon(self,row,col): """Return geographic coordinates (lat/lon decimal degrees) for given data row and column. :param row: Row dimension index into internal data array. :param col: Column dimension index into internal data array. :returns: Tuple of latitude and longitude. """ layernames = self._layers.keys() return self._layers[layernames[0]].getLatLon(row,col)
[docs] def getRowCol(self,lat,lon,returnFloat=False): """Return data row and column from given geographic coordinates (lat/lon decimal degrees). :param lat: Input latitude. :param lon: Input longitude. :param returnFloat: Boolean indicating whether floating point row/col coordinates should be returned. :returns: Tuple of row and column. """ layernames = self._layers.keys() return self._layers[layernames[0]].getRowCol(lat,lon,returnFloat=returnFloat)
[docs] def interpolateToGrid(self,geodict,method='linear'): """ Given a geodict specifying another grid extent and resolution, resample all grids to match. :param geodict: geodict dictionary from another grid whose extents are inside the extent of this grid. :keyword method: Optional interpolation method - ['linear', 'cubic','quintic','nearest'] :raises DataSetException: If the Grid object upon which this function is being called is not completely contained by the grid to which this Grid is being resampled. :raises DataSetException: If the resulting interpolated grid shape does not match input geodict. This function modifies the internal griddata and geodict object variables. """ for layername,layer in self._layers.iteritems(): layer.interpolateToGrid(geodict,method=method) self._geodict = layer.getGeoDict().copy()