Ejemplo n.º 1
0
def get_average(file, points, radius=40):
    '''Like get_values, but computes the average value within a circle of the 
    specified radius (in km).
    
    Missing values are ignored. Returns None if there were no values within the 
    circle.
    
    >>> lat_lons = [(10,10), (20,20), (0,0)]
    >>> [type(x) for x in get_average('bio1', lat_lons, 0)]
    [<type 'float'>, <type 'float'>, <type 'NoneType'>]
    >>> get_average('bio1', lat_lons, 100) != get_average('bio1', lat_lons, 50) != get_average('bio1', lat_lons, 0)
    True
    '''

    data, no_value, ul, dims, size = extract_attributes(file)

    result = []
    for point in points:
        within = points_within_distance(*(point + ul + dims), radius=radius)
        raster_positions = [
            xy_coords(lat, lon, *(ul + dims)) for (lat, lon) in within
        ]
        values = [
            get_point(data, pos[0], pos[1], no_value)
            for pos in raster_positions
        ]
        values = [v for v in values if not v is None]
        if len(values) == 0: result.append(None)
        else:
            result.append(sum(values) / float(len(values)))

    return result
Ejemplo n.º 2
0
def get_values(file, points):
    '''Given a .bil file (or other file readable by GDAL) and a set of (lat,lon) 
    points, return a list of values for those points. -9999 will be converted to 
    None.
    
    >>> lat_lons = [(15,15), (20,20), (-60,0)]
    
    # Two points on land, one in the water:
    >>> [type(x) for x in get_values('bio1', lat_lons)]
    [<type 'float'>, <type 'float'>, <type 'NoneType'>]

    # Sahara hotter than Siberia (max temp. of hottest quarter):
    >>> get_values('bio10', [(0, 20)])[0] > get_values('bio10', [(140, 65)])[0]
    True

    # Albuquerque hotter than Anchorage (mean annual temperature):
    >>> get_values('bio1', [(35, -107)])[0] > get_values('bio1', [(61, -150)])[0]
    True
    '''

    data, no_value, ul, dims, size = extract_attributes(file)

    result = []
    for (lat, lon) in points:
        x, y = xy_coords(lat, lon, *(ul + dims))
        value = get_point(data, x, y, no_value)
        if value == no_value: value = None
        result.append(value)

    return result
Ejemplo n.º 3
0
def get_average(file, points, radius=40):
    '''Like get_values, but computes the average value within a circle of the 
    specified radius (in km).
    
    Missing values are ignored. Returns None if there were no values within the 
    circle.
    
    >>> lat_lons = [(10,10), (20,20), (0,0)]
    >>> [type(x) for x in get_average('bio1', lat_lons, 0)]
    [<type 'float'>, <type 'float'>, <type 'NoneType'>]
    >>> get_average('bio1', lat_lons, 100) != get_average('bio1', lat_lons, 50) != get_average('bio1', lat_lons, 0)
    True
    '''

    data, no_value, ul, dims, size = extract_attributes(file)
    
    result = []
    for point in points:
        within = points_within_distance(*(point + ul + dims), radius=radius)
        raster_positions = [xy_coords(lat, lon, *(ul + dims)) for (lat, lon) in within]
        values = [get_point(data, pos[0], pos[1], no_value) 
                  for pos in raster_positions]
        values = [v for v in values if not v is None]
        if len(values) == 0: result.append(None)
        else:
            result.append(sum(values)/float(len(values)))

    return result
Ejemplo n.º 4
0
def get_values(file, points):
    '''Given a .bil file (or other file readable by GDAL) and a set of (lat,lon) 
    points, return a list of values for those points. -9999 will be converted to 
    None.
    
    >>> lat_lons = [(15,15), (20,20), (-60,0)]
    
    # Two points on land, one in the water:
    >>> [type(x) for x in get_values('bio1', lat_lons)]
    [<type 'float'>, <type 'float'>, <type 'NoneType'>]

    # Sahara hotter than Siberia (max temp. of hottest quarter):
    >>> get_values('bio10', [(0, 20)])[0] > get_values('bio10', [(140, 65)])[0]
    True

    # Albuquerque hotter than Anchorage (mean annual temperature):
    >>> get_values('bio1', [(35, -107)])[0] > get_values('bio1', [(61, -150)])[0]
    True
    '''

    data, no_value, ul, dims, size = extract_attributes(file)

    result = []
    for (lat, lon) in points:
        x,y = xy_coords(lat, lon, *(ul+dims))
        value = get_point(data, x, y, no_value)
        if value == no_value: value = None
        result.append(value)

    return result
Ejemplo n.º 5
0
def draw_map(file, map=None, show=True, title=None, log=False, map_type=None):
    '''Use Matplotlib's basemap to generate a map of a given BIOCLIM data 
    file.
    
    You can supply a Basemap object (in any projection) as the optional 
    keyword argument "map." If none is provided, the default Miller 
    projection will be used.'''
    
    data, no_value, ul, dims, size = extract_attributes(file)
    data = get_dataset(file)
    lats = np.linspace(ul[0], ul[0]-dims[0]*size[0], size[0], endpoint=False)
    lons = np.linspace(ul[1], ul[1]+dims[1]*size[1], size[1], endpoint=False)
    if map_type == 'variance':
        x, y = np.meshgrid(lons, lats)
        raster = np.zeros(x.shape)
        values = get_spatial_variance(file, 
                                      [(lat, lon) 
                                       for lat in lats 
                                       for lon in lons])
        for a in range(data.shape[0]):
            for b in range(data.shape[1]):
                data[a,b] = values.pop()
    else:
        raster = data.ReadAsArray()

    
    # because missing data is entered as -9999, created a masked array so that 
    # these points will not be plotted
    values = np.ma.masked_where(raster==no_value, raster)
    
    # log transform data, if requested
    if log:
        if (values < 0).any():
            values -= min(values)
        values = np.log1p(values)
    
    plt.figure()
    if title is None:
        title = '%s' % file
        if file in variable_names:
            title += ': %s' % variable_names[file]
    plt.title(title)
    if map is None:
        map = Basemap(projection='mill',lon_0=0)
        map.drawcoastlines(linewidth=1)
        map.drawcountries(linewidth=1)
        map.drawstates(linewidth=0.5)
        parallels = np.arange(-90.,90,10.)
        map.drawparallels(parallels,labels=[False,True,True,False])
        meridians = np.arange(-180.,180.,20.)
        map.drawmeridians(meridians,labels=[True,False,False,True])    

    x, y = np.meshgrid(lons, lats)
            
    map.pcolormesh(x, y, data=values, latlon=True, cmap=plt.cm.Spectral_r)
    cbar = plt.colorbar()
    
    if show: plt.show()
Ejemplo n.º 6
0
def get_spatial_variance(file, points, radius=40):
    '''Like get_values, but computes the spatial variance within a circle of the
    specified radius (in km).
    
    Missing values are ignored. Returns None if there were no values within the 
    circle.
    
    >>> lat_lons = [(10,10), (20,20), (0,0)]
    >>> get_spatial_variance('bio1', lat_lons, 0)
    [0.0, 0.0, None]
    >>> (get_spatial_variance('bio1', lat_lons[0:1], 100) >= 
    ... get_spatial_variance('bio1', lat_lons[0:1], 50) >= 
    ... get_spatial_variance('bio1', lat_lons[0:1], 0))
    True
    '''

    data, no_value, ul, dims, size = extract_attributes(file)

    result = []
    for point in points:
        # because the distance between longitude points approaches 0 at the
        # poles, only compute variance between 60 N and 60 S
        if abs(point[0]) > 60:
            result.append(None)
            continue

        within = points_within_distance(*(point + ul + dims), radius=radius)
        raster_positions = [
            xy_coords(lat, lon, *(ul + dims)) for (lat, lon) in within
        ]
        values = [
            get_point(data, pos[0], pos[1], no_value)
            for pos in raster_positions
        ]
        values = [v for v in values if not v is None]
        if len(values) == 0: result.append(None)
        else:
            result.append(float(np.var(values)))

    return result
Ejemplo n.º 7
0
def get_spatial_variance(file, points, radius=40):
    '''Like get_values, but computes the spatial variance within a circle of the
    specified radius (in km).
    
    Missing values are ignored. Returns None if there were no values within the 
    circle.
    
    >>> lat_lons = [(10,10), (20,20), (0,0)]
    >>> get_spatial_variance('bio1', lat_lons, 0)
    [0.0, 0.0, None]
    >>> (get_spatial_variance('bio1', lat_lons[0:1], 100) >= 
    ... get_spatial_variance('bio1', lat_lons[0:1], 50) >= 
    ... get_spatial_variance('bio1', lat_lons[0:1], 0))
    True
    '''

    data, no_value, ul, dims, size = extract_attributes(file)
    
    result = []
    for point in points:
        # because the distance between longitude points approaches 0 at the 
        # poles, only compute variance between 60 N and 60 S
        if abs(point[0]) > 60:
            result.append(None)
            continue

        within = points_within_distance(*(point + ul + dims), radius=radius)
        raster_positions = [xy_coords(lat, lon, *(ul + dims)) for (lat, lon) in within]
        values = [get_point(data, pos[0], pos[1], no_value) 
                  for pos in raster_positions]
        values = [v for v in values if not v is None]
        if len(values) == 0: result.append(None)
        else:
            result.append(float(np.var(values)))

    return result