Ejemplo n.º 1
0
def test_bounds_within_meridian():
    host = GeoDict({'xmin': -180,
                    'xmax': 150,
                    'ymin': -90,
                    'ymax': 90,
                    'dx': 30,
                    'dy': 45,
                    'nx': 12,
                    'ny': 5})
    sample = GeoDict({'xmin': 75,
                      'xmax': -135,
                      'ymin': -67.5,
                      'ymax': 67.5,
                      'dx': 30,
                      'dy': 45,
                      'nx': 6,
                      'ny': 4})

    result = GeoDict({'xmin': 90,
                      'xmax': -150,
                      'ymin': -45,
                      'ymax': 45,
                      'dx': 30,
                      'dy': 45,
                      'nx': 5,
                      'ny': 3})

    inside = host.getBoundsWithin(sample)
    assert inside == result
Ejemplo n.º 2
0
def test_grid_hdf_container():
    f,fname = tempfile.mkstemp()
    os.close(f)
    try:
        #test grid container
        container = GridHDFContainer.create(fname)

        # before we put anything in here, let's make sure we get empty lists from
        # all of the methods that are supposed to return lists of stuff.
        assert container.getGrids() == []
        
        #test grid2d
        geodict = GeoDict.createDictFromBox(-118.5,-114.5,32.1,36.7,0.01,0.02)
        nrows,ncols = geodict.ny,geodict.nx
        data = np.random.rand(nrows,ncols)
        metadata = {'name':'Gandalf',
                    'color':'white',
                    'powers':'magic'}
        grid = Grid2D(data,geodict)
        container.setGrid('testgrid',grid,metadata=metadata)
        outgrid,outmetadata = container.getGrid('testgrid')
        np.testing.assert_array_equal(outgrid.getData(),data)
        assert outgrid.getGeoDict() == geodict
        assert outmetadata == metadata

        #set another grid without compression
        geodict = GeoDict.createDictFromBox(-119.5,-115.5,32.3,37.7,0.01,0.02)
        nrows,ncols = geodict.ny,geodict.nx
        data = np.random.rand(nrows,ncols)
        metadata = {'name':'Legolas',
                    'color':'green',
                    'powers':'stealth'}
        grid2 = Grid2D(data,geodict)
        container.setGrid('testgrid2',grid2,metadata=metadata,compression=False)
        outgrid2,outmetadata2 = container.getGrid('testgrid2')
        np.testing.assert_array_equal(outgrid2.getData(),data)
        assert outgrid2.getGeoDict() == geodict
        assert outmetadata2 == metadata
        
        #test getGridNames()
        names = container.getGrids()
        assert sorted(names) == ['testgrid','testgrid2']

        #test looking for a grid that does not exist
        try:
            container.getGrid('foo')
        except LookupError as le:
            pass

        #test dropping a grid
        container.dropGrid('testgrid2')

        container.close()
        container2 = GridHDFContainer.load(fname)
        names = container2.getGrids()
        assert sorted(names) == ['testgrid']
    except:
        assert 1==2
    finally:
        os.remove(fname)
Ejemplo n.º 3
0
def test_contains():
    fxmin, fxmax = (-179.995833333333, 179.99583333189372)
    fymin, fymax = (-89.99583333333332, 89.9958333326134)
    fdx, fdy = (0.0083333333333, 0.0083333333333)
    fnx, fny = (43200, 21600)
    xmin, xmax = (-179.996, -177.496)
    ymin, ymax = (-21.89175, -19.55425)
    dx, dy = (0.025, 0.02513440860215052)
    nx, ny = (101, 94)
    host = GeoDict({'xmin': fxmin,
                    'xmax': fxmax,
                    'ymin': fymin,
                    'ymax': fymax,
                    'dx': fdx,
                    'dy': fdy,
                    'nx': fnx,
                    'ny': fny})
    sample = GeoDict({'xmin': xmin,
                      'xmax': xmax,
                      'ymin': ymin,
                      'ymax': ymax,
                      'dx': dx,
                      'dy': dy,
                      'nx': nx,
                      'ny': ny})
    assert host.contains(sample)
Ejemplo n.º 4
0
def test_bounds_within_again():
    fxmin, fxmax = (-179.995833333333, 179.99583333189372)
    fymin, fymax = (-89.99583333333332, 89.9958333326134)
    fdx, fdy = (0.0083333333333, 0.0083333333333)
    fnx, fny = (43200, 21600)

    xmin, xmax = (97.233, 99.733)
    ymin, ymax = (84.854, 85.074)
    dx, dy = (0.025, 0.024444444444444317)
    nx, ny = (101, 10)

    host = GeoDict({'xmin': fxmin,
                    'xmax': fxmax,
                    'ymin': fymin,
                    'ymax': fymax,
                    'dx': fdx,
                    'dy': fdy,
                    'nx': fnx,
                    'ny': fny})
    sample = GeoDict({'xmin': xmin,
                      'xmax': xmax,
                      'ymin': ymin,
                      'ymax': ymax,
                      'dx': dx,
                      'dy': dy,
                      'nx': nx,
                      'ny': ny})
    inside = host.getBoundsWithin(sample)
Ejemplo n.º 5
0
def test_bounds_meridian2():
    host = {'ny': 797, 'dx': 0.0083333333,
            'ymin': -21.445972496439, 'dy': 0.0083333333,
            'xmin': 178.33735967776101, 'nx': 841,
            'xmax': -174.66264035023897, 'ymax': -14.812639189639}
    sample = {'ny': 773, 'dx': 0.008333333333333333,
              'ymin': -21.35, 'dy': 0.008333333333333333,
              'xmin': 178.43333333333334, 'nx': 817,
              'xmax': -174.76666666666665, 'ymax': -14.916666666666666}

    host_geodict = GeoDict(host)
    sample_geodict = GeoDict(sample)
    within = host_geodict.getBoundsWithin(sample_geodict)
    assert within.xmin == 178.437359677361
    assert within.xmax == -174.770973683139
Ejemplo n.º 6
0
def test_write():
    data = np.arange(0, 25).reshape(5, 5).astype(np.float32)
    gdict = {
        'xmin': 5.0,
        'xmax': 9.0,
        'ymin': 4.0,
        'ymax': 8.0,
        'dx': 1.0,
        'dy': 1.0,
        'nx': 5,
        'ny': 5
    }
    gd = GeoDict(gdict)
    grid = Grid2D(data, gd)

    for format_type in ['netcdf', 'esri', 'hdf']:
        tdir = tempfile.mkdtemp()
        fname = os.path.join(tdir, 'tempfile.grd')
        try:
            write(grid, fname, format_type)
            src = rasterio.open(fname, 'r')
            tdata = src.read(1)
            np.testing.assert_almost_equal(tdata, data)
        except Exception as e:
            raise e
        finally:
            shutil.rmtree(tdir)
Ejemplo n.º 7
0
def test_rasterize():
    geodict = GeoDict({'xmin':0.5,'xmax':3.5,
                       'ymin':0.5,'ymax':3.5,
                       'dx':1.0,'dy':1.0,
                       'ny':4,'nx':4})
    print('Testing rasterizeFromGeometry() burning in values from a polygon sequence...')
    #Define two simple polygons and assign them to shapes
    poly1 = [(0.25,3.75),(1.25,3.25),(1.25,2.25)]
    poly2 = [(2.25,3.75),(3.25,3.75),(3.75,2.75),(3.75,1.50),(3.25,0.75),(2.25,2.25)]
    shape1 = {'properties':{'value':5},'geometry':mapping(Polygon(poly1))}
    shape2 = {'properties':{'value':7},'geometry':mapping(Polygon(poly2))}
    shapes = [shape1,shape2]
    print('Testing burning in values where polygons need not contain pixel centers...')
    grid = Grid2D.rasterizeFromGeometry(shapes,geodict,fillValue=0,attribute='value',mustContainCenter=False)
    output = np.array([[5,5,7,7],
                       [5,5,7,7],
                       [0,0,7,7],
                       [0,0,0,7]])
    np.testing.assert_almost_equal(grid.getData(),output)
    print('Passed burning in values where polygons need not contain pixel centers.')

    print('Testing burning in values where polygons must contain pixel centers...')
    grid2 = Grid2D.rasterizeFromGeometry(shapes,geodict,fillValue=0,attribute='value',mustContainCenter=True)
    output = np.array([[5,0,7,0],
                       [0,0,7,7],
                       [0,0,0,7],
                       [0,0,0,0]])
    np.testing.assert_almost_equal(grid2.getData(),output)
    print('Passed burning in values where polygons must contain pixel centers.')
Ejemplo n.º 8
0
def getNoDataGrid(predictors,xmin,xmax,ymin,ymax):
    txmin = xmin
    txmax = xmax
    tymin = ymin
    tymax = ymax
    mindx = 9999999999
    mindy = 9999999999
    #figure out bounds enclosing all files
    for predname,predfile in predictors.items():
        if not os.path.isfile(predfile):
            continue
        ftype = getFileType(predfile)
        if ftype == 'shapefile':
            f = fiona.open(predfile,'r')
            bxmin,bymin,bxmax,bymax = f.bounds
            f.close()
            if bxmin < txmin:
                txmin = bxmin
            if bxmax > txmax:
                txmax = bxmax
            if bymin < tymin:
                tymin = bymin
            if bymax > tymax:
                tymax = bymax
        elif ftype == 'grid':
            gridtype = getGridType(predfile)
            if gridtype is None:
                raise Exception('File "%s" does not appear to be either a GMT grid or an ESRI grid.' % gridfile)
            fdict = getFileGeoDict(predfile,gridtype)
            if fdict.dx < mindx:
                mindx = fdict.dx
            if fdict.dy < mindy:
                mindy = fdict.dy
            if fdict.xmin < txmin:
                txmin = fdict.xmin
            if fdict.xmax > txmax:
                txmax = txmax
            if fdict.ymin < tymin:
                tymin = tymin
            if fdict.ymax > tymax:
                tymax = tymax
    sdict = GeoDict.createDictFromBox(txmin,txmax,tymin,tymax,mindx,mindy)
    nanarray = np.zeros((sdict.ny,sdict.nx),dtype=np.int8)
    for predname,predfile in predictors.items():
        if not os.path.isfile(predfile):
            continue
        ftype = getFileType(predfile)
        if ftype == 'shapefile':
            shapes = list(fiona.open(predfile,'r'))
            grid = Grid2D.rasterizeFromGeometry(shapes,sdict)
        else:
            gridtype = getGridType(predfile)
            if gridtype == 'gmt':
                grid = GMTGrid.load(predfile,samplegeodict=sdict,resample=True,method='nearest',doPadding=True)
            else:
                grid = GDALGrid.load(predfile,samplegeodict=sdict,resample=True,method='nearest',doPadding=True)
        nangrid = np.isnan(grid.getData())
        nanarray = nanarray | nangrid
    nangrid = Grid2D(data=nanarray,geodict=sdict)
    return nangrid
Ejemplo n.º 9
0
def make_overlay(adict):
    """
    Make a transparent PNG of intensity and a world file

    Args:
        adict (dict): The usual dictionary for the mapping functions.

    Returns:
        nothing: Nothing.
    """
    mmidict = adict['imtdict']
    mmi_array = mmidict['mean']
    geodict = GeoDict(mmidict['mean_metadata'])
    palette = ColorPalette.fromPreset('mmi')
    mmi_rgb = palette.getDataColor(mmi_array, color_format='array')
    img = Image.fromarray(mmi_rgb)
    pngfile = os.path.join(adict['datadir'], 'intensity_overlay.png')
    img.save(pngfile, "PNG")

    # write out a world file
    # https://en.wikipedia.org/wiki/World_file
    worldfile = os.path.join(adict['datadir'], 'intensity_overlay.pngw')
    with open(worldfile, 'wt') as f:
        f.write('%.4f\n' % geodict.dx)
        f.write('0.0\n')
        f.write('0.0\n')
        f.write('-%.4f\n' % geodict.dy)
        f.write('%.4f\n' % geodict.xmin)
        f.write('%.4f\n' % geodict.ymax)
    return
Ejemplo n.º 10
0
def _trim_grid(ingrid):
    outgrid = Grid2D.copyFromGrid(ingrid)
    while np.isnan(outgrid._data).any():
        nrows, ncols = outgrid._data.shape
        top = outgrid._data[0, :]
        bottom = outgrid._data[-1, :]
        left = outgrid._data[:, 0]
        right = outgrid._data[:, -1]
        ftop = np.isnan(top).sum() / ncols
        fbottom = np.isnan(bottom).sum() / ncols
        fleft = np.isnan(left).sum() / nrows
        fright = np.isnan(right).sum() / nrows
        side = np.argmax([ftop, fbottom, fleft, fright])
        gdict = outgrid.getGeoDict().asDict()
        if side == 0:  # removing top row
            outgrid._data = outgrid._data[1:, :]
            gdict['ymax'] -= gdict['dy']
            gdict['ny'] -= 1
        elif side == 1:  # removing bottom row
            outgrid._data = outgrid._data[0:-1, :]
            gdict['ymin'] += gdict['dy']
            gdict['ny'] -= 1
        elif side == 2:  # removing left column
            outgrid._data = outgrid._data[:, 1:]
            gdict['xmin'] += gdict['dx']
            gdict['nx'] -= 1
        elif side == 3:  # removing right column
            outgrid._data = outgrid._data[:, 0:-1]
            gdict['xmax'] -= gdict['dx']
            gdict['nx'] -= 1
        geodict = GeoDict(gdict)
        outgrid = Grid2D(data=outgrid._data, geodict=geodict)

    return outgrid
Ejemplo n.º 11
0
def test_setData():
    data = np.arange(0, 16).astype(np.float32).reshape(4, 4)
    geodict = GeoDict({
        'xmin': 0.5,
        'xmax': 3.5,
        'ymin': 0.5,
        'ymax': 3.5,
        'dx': 1.0,
        'dy': 1.0,
        'ny': 4,
        'nx': 4
    })
    grid1 = Grid2D(data, geodict)
    x = np.ones((4, 4))
    try:
        grid1.setData(x)  #this should pass
        print('setData test passed.')
    except DataSetException as dse:
        print('setData test failed.')
    try:
        x = np.ones((5, 5))
        grid1.setData(x)
        print('setData test did not fail when it should have.')
    except DataSetException as dse:
        print('setData test failed as expected.')

    try:
        x = 'fred'
        grid1.setData(x)
        print('setData test did not fail when it should have.')
    except DataSetException as dse:
        print('setData test failed as expected.')
Ejemplo n.º 12
0
def test_mapmaker_intensity():
    homedir = os.path.dirname(
        os.path.abspath(__file__))  # where is this script?
    shakedir = os.path.abspath(os.path.join(homedir, '..', '..', '..'))
    out_file = os.path.join(shakedir, 'tests', 'data', 'containers',
                            'northridge', 'shake_result.hdf')
    container = ShakeMapOutputContainer.load(out_file)
    topofile = os.path.join(homedir, '..', '..', 'data', 'install', 'data',
                            'mapping', 'CA_topo.grd')

    info = container.getMetadata()
    xmin = info['output']['map_information']['min']['longitude']
    xmax = info['output']['map_information']['max']['longitude']
    ymin = info['output']['map_information']['min']['latitude']
    ymax = info['output']['map_information']['max']['latitude']
    xmin = float(xmin) - 0.1
    xmax = float(xmax) + 0.1
    ymin = float(ymin) - 0.1
    ymax = float(ymax) + 0.1
    dy = float(info['output']['map_information']['grid_spacing']['latitude'])
    dx = float(info['output']['map_information']['grid_spacing']['longitude'])
    sampledict = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
    topogrid = GMTGrid.load(topofile, samplegeodict=sampledict, resample=False)

    outpath = mkdtemp()

    model_config = container.getConfig()
    comp = container.getComponents('MMI')[0]
    textfile = os.path.join(get_data_path(), 'mapping', 'map_strings.en')
    text_dict = get_text_strings(textfile)

    cities = Cities.fromDefault()
    d = {
        'imtype': 'MMI',
        'topogrid': topogrid,
        'allcities': cities,
        'states_provinces': None,
        'countries': None,
        'oceans': None,
        'lakes': None,
        'roads': None,
        'faults': None,
        'datadir': outpath,
        'operator': 'NEIC',
        'filter_size': 10,
        'info': info,
        'component': comp,
        'imtdict': container.getIMTGrids('MMI', comp),
        'ruptdict': copy.deepcopy(container.getRuptureDict()),
        'stationdict': container.getStationDict(),
        'config': model_config,
        'tdict': text_dict
    }

    try:
        fig1, fig2 = draw_map(d)
    except Exception:
        assert 1 == 2
    finally:
        shutil.rmtree(outpath)
Ejemplo n.º 13
0
def test_bounds_within_real():
    fxmin, fxmax = (-179.995833333333, 179.99583333189372)
    fymin, fymax = (-89.99583333333332, 89.9958333326134)
    fdx, fdy = (0.0083333333333, 0.0083333333333)
    fnx, fny = (43200, 21600)
    xmin, xmax = (177.75, -179.75)
    ymin, ymax = (50.41625, 51.98375)
    dx, dy = (0.025, 0.02488095238095242)
    nx, ny = (101, 64)
    host = GeoDict({'xmin': fxmin,
                    'xmax': fxmax,
                    'ymin': fymin,
                    'ymax': fymax,
                    'dx': fdx,
                    'dy': fdy,
                    'nx': fnx,
                    'ny': fny})
    sample = GeoDict({'xmin': xmin,
                      'xmax': xmax,
                      'ymin': ymin,
                      'ymax': ymax,
                      'dx': dx,
                      'dy': dy,
                      'nx': nx,
                      'ny': ny})
    result = GeoDict({'xmin': 60,
                      'xmax': -120,
                      'ymin': -30,
                      'ymax': 30,
                      'dx': 60,
                      'dy': 30,
                      'nx': 4,
                      'ny': 3})
    inside = host.getBoundsWithin(sample)
    ixmin, ixmax = (177.75416666523603, -179.7541666666673)
    iymin, iymax = (50.4208333327717, 51.9791666660988)
    idx, idy = (0.0083333333333, 0.0083333333333)
    inx, iny = (300, 188)
    result = GeoDict({'xmin': ixmin,
                      'xmax': ixmax,
                      'ymin': iymin,
                      'ymax': iymax,
                      'dx': idx,
                      'dy': idy,
                      'nx': inx,
                      'ny': iny})
    assert inside == result
Ejemplo n.º 14
0
def test_copy():
    data = np.arange(0,16).astype(np.float32).reshape(4,4)
    geodict = GeoDict({'xmin':0.5,'xmax':3.5,'ymin':0.5,'ymax':3.5,'dx':1.0,'dy':1.0,'ny':4,'nx':4})
    grid1 = Grid2D(data,geodict)
    grid2 = grid1.copyFromGrid(grid1)
    grid1._data[0,0] = np.nan
    print(grid2._data)
    print(grid2._geodict)
Ejemplo n.º 15
0
    def createFromCenter(cls,
                         cx,
                         cy,
                         xspan,
                         yspan,
                         dx,
                         dy,
                         defaultVs30=686.0,
                         vs30File=None,
                         vs30measured_grid=None,
                         backarc=False,
                         padding=False,
                         resample=False):
        """
        Create a Sites object by defining a center point, resolution, extent, 
        and Vs30 values.

        :param cx:
            X coordinate of desired center point.
        :param cy:
            Y coordinate of desired center point.
        :param xspan:
            Width of desired grid.
        :param yspan:
            Height of desired grid.
        :param dx:
            Resolution of desired grid in X direction.
        :param dy:
            Resolution of desired grid in Y direction.
        :param defaultVs30:
            Default Vs30 value to use if vs30File not specified.
        :param vs30File:
            Name of GMT or GDAL format grid file containing Vs30 values.
        :param vs30measured_grid:
            Boolean grid indicating whether Vs30 values were measured or derived 
            (i.e., from slope)
        :param backarc:
            Boolean indicating whether event is on the backarc as defined
            `here <http://earthquake.usgs.gov/learn/glossary/?term=backarc>`__.
        :param padding:
            Boolean indicating whether or not to pad resulting Vs30 grid out to
            edges of input bounds. If False, grid will be clipped to the extent
            of the input file.
        :param resample:
            Boolean indicating whether or not the grid should be resampled.
        """
        geodict = GeoDict.createDictFromCenter(cx, cy, dx, dy, xspan, yspan)
        if vs30File is not None:
            vs30grid = cls._create(geodict, defaultVs30, vs30File, padding,
                                   resample)
        else:
            griddata = np.ones(
                (geodict.ny, geodict.nx), dtype=np.float64) * defaultVs30
            vs30grid = Grid2D(griddata, geodict)
        return cls(vs30grid,
                   vs30measured_grid=vs30measured_grid,
                   backarc=backarc,
                   defaultVs30=defaultVs30)
Ejemplo n.º 16
0
    def getRegions(self, lat, lon, depth):
        """Get information about the tectonic region of a given hypocenter.

        Args:
            lat (float): Earthquake hypocentral latitude.
            lon (float): Earthquake hypocentral longitude.
            depth (float): Earthquake hypocentral depth.
        Returns:
            Series: Pandas series object containing labels:
                - TectonicRegion: Subduction, Active, Stable, or Volcanic.
                - DistanceToStable: Distance in km to nearest stable region.
                - DistanceToActive: Distance in km to nearest active region.
                - DistanceToSubduction: Distance in km to nearest subduction
                                        region.
                - DistanceToVolcanic: Distance in km to nearest volcanic
                                      region.
                - Oceanic: Boolean indicating if epicenter is in the ocean.
                - DistanceToOceanic: Distance in km to nearest oceanic region.
                - DistanceToContinental: Distance in km to nearest continental
                                         region.
        """
        regions = OrderedDict()

        gd = GeoDict.createDictFromCenter(lon, lat, DX, DY, XSPAN, YSPAN)

        tec_grid = read(self._tectonic_grid, samplegeodict=gd)
        region_dict = get_dist_to_type(lon, lat, tec_grid, TECTONIC_REGIONS)

        ocean_grid = read(self._oceanic_grid, samplegeodict=gd)
        ocean_dict = get_dist_to_type(lon, lat, ocean_grid, OCEANIC_REGIONS)

        if region_dict['DistanceToActive'] == 0:
            region_dict['TectonicRegion'] = 'Active'
        elif region_dict['DistanceToStable'] == 0:
            region_dict['TectonicRegion'] = 'Stable'
        elif region_dict['DistanceToSubduction'] == 0:
            region_dict['TectonicRegion'] = 'Subduction'
        else:
            region_dict['TectonicRegion'] = 'Volcanic'

        region_dict['DistanceToOceanic'] = ocean_dict['DistanceToOceanic']
        region_dict['DistanceToContinental'] = ocean_dict['DistanceToContinental']
        region_dict['Oceanic'] = False
        if ocean_dict['DistanceToOceanic'] == 0:
            region_dict['Oceanic'] = True

        regions = pd.Series(region_dict, index=['TectonicRegion',
                                                'DistanceToStable',
                                                'DistanceToActive',
                                                'DistanceToSubduction',
                                                'DistanceToVolcanic',
                                                'Oceanic',
                                                'DistanceToOceanic',
                                                'DistanceToContinental'])

        return regions
Ejemplo n.º 17
0
    def getRegions(self, lat, lon, depth):
        """Get information about the tectonic region of a given hypocenter.

        Args:
            lat (float): Earthquake hypocentral latitude.
            lon (float): Earthquake hypocentral longitude.
            depth (float): Earthquake hypocentral depth.
        Returns:
            Series: Pandas series object containing labels:
                - TectonicRegion: Subduction, Active, Stable, or Volcanic.
                - DistanceToStable: Distance in km to nearest stable region.
                - DistanceToActive: Distance in km to nearest active region.
                - DistanceToSubduction: Distance in km to nearest subduction
                                        region.
                - DistanceToVolcanic: Distance in km to nearest volcanic
                                      region.
                - Oceanic: Boolean indicating if epicenter is in the ocean.
                - DistanceToOceanic: Distance in km to nearest oceanic region.
                - DistanceToContinental: Distance in km to nearest continental
                                         region.
        """
        regions = OrderedDict()

        gd = GeoDict.createDictFromCenter(lon, lat, DX, DY, XSPAN, YSPAN)

        tec_grid = read(self._tectonic_grid, samplegeodict=gd)
        region_dict = get_dist_to_type(lon, lat, tec_grid, TECTONIC_REGIONS)

        ocean_grid = read(self._oceanic_grid, samplegeodict=gd)
        ocean_dict = get_dist_to_type(lon, lat, ocean_grid, OCEANIC_REGIONS)

        if region_dict['DistanceToActive'] == 0:
            region_dict['TectonicRegion'] = 'Active'
        elif region_dict['DistanceToStable'] == 0:
            region_dict['TectonicRegion'] = 'Stable'
        elif region_dict['DistanceToSubduction'] == 0:
            region_dict['TectonicRegion'] = 'Subduction'
        else:
            region_dict['TectonicRegion'] = 'Volcanic'

        region_dict['DistanceToOceanic'] = ocean_dict['DistanceToOceanic']
        region_dict['DistanceToContinental'] = ocean_dict[
            'DistanceToContinental']
        region_dict['Oceanic'] = False
        if ocean_dict['DistanceToOceanic'] == 0:
            region_dict['Oceanic'] = True

        regions = pd.Series(region_dict,
                            index=[
                                'TectonicRegion', 'DistanceToStable',
                                'DistanceToActive', 'DistanceToSubduction',
                                'DistanceToVolcanic', 'Oceanic',
                                'DistanceToOceanic', 'DistanceToContinental'
                            ])

        return regions
Ejemplo n.º 18
0
def test_basics():
    geodict = GeoDict({
        'xmin': 0.5,
        'xmax': 3.5,
        'ymin': 0.5,
        'ymax': 3.5,
        'dx': 1.0,
        'dy': 1.0,
        'ny': 4,
        'nx': 4
    })
    data = np.arange(0, 16).reshape(4, 4).astype(np.float32)
    grid = Grid2D(data, geodict)
    print(
        'Testing basic Grid2D functionality (retrieving data, lat/lon to pixel coordinates, etc...'
    )
    np.testing.assert_almost_equal(grid.getData(), data)

    assert grid.getGeoDict() == geodict

    assert grid.getBounds() == (geodict.xmin, geodict.xmax, geodict.ymin,
                                geodict.ymax)

    lat, lon = grid.getLatLon(0, 0)

    assert lat == 3.5 and lon == 0.5

    row, col = grid.getRowCol(lat, lon)

    assert row == 0 and col == 0

    value = grid.getValue(lat, lon)

    assert value == 0

    frow, fcol = grid.getRowCol(1.0, 3.0, returnFloat=True)

    assert frow == 2.5 and fcol == 2.5

    irow, icol = grid.getRowCol(1.0, 3.0, returnFloat=False)

    assert irow == 2 and icol == 2

    #test getting values in and outside of the grid bounds
    lat = np.array([0.0, 0.5, 2.5, 4.0])
    lon = np.array([0.0, 0.5, 2.5, 4.0])
    default = np.nan
    output = np.array([np.nan, 12, 6, np.nan])
    value = grid.getValue(lat, lon, default=default)

    np.testing.assert_almost_equal(value, output)

    print(
        'Passed basic Grid2D functionality (retrieving data, lat/lon to pixel coordinates, etc...'
    )
Ejemplo n.º 19
0
def sampleGridFile(gridfile, xypoints, method='nearest'):
    """Sample grid file (ESRI or GMT format) at each of a set of XY (decimal degrees) points.

    :param gridfile:
      Name of ESRI or GMT grid format file from which to sample values.
    :param xypoints:
      2D numpy array of XY points, decimal degrees.
    :param method:
      Interpolation method, either 'nearest' or 'linear'.
    :returns:
      1D numpy array of grid values at each of input XY points.
    """
    xmin = np.min(xypoints[:, 0])
    xmax = np.max(xypoints[:, 0])
    ymin = np.min(xypoints[:, 1])
    ymax = np.max(xypoints[:, 1])
    gridtype = None
    try:
        fdict = GMTGrid.getFileGeoDict(gridfile)
        gridtype = 'gmt'
    except Exception as error:
        try:
            fdict = GDALGrid.getFileGeoDict(gridfile)
            gridtype = 'esri'
        except:
            pass
    if gridtype is None:
        raise Exception(
            'File "%s" does not appear to be either a GMT grid or an ESRI grid.'
            % gridfile)
    xmin = xmin - fdict.dx * 3
    xmax = xmax + fdict.dx * 3
    ymin = ymin - fdict.dy * 3
    ymax = ymax + fdict.dy * 3
    #bounds = (xmin, xmax, ymin, ymax)
    if gridtype == 'gmt':
        fgeodict = GMTGrid.getFileGeoDict(gridfile)
    else:
        fgeodict = GDALGrid.getFileGeoDict(gridfile)
    dx, dy = (fgeodict.dx, fgeodict.dy)
    sdict = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
    if gridtype == 'gmt':
        grid = GMTGrid.load(gridfile,
                            samplegeodict=sdict,
                            resample=False,
                            method=method,
                            doPadding=True)
    else:
        grid = GDALGrid.load(gridfile,
                             samplegeodict=sdict,
                             resample=False,
                             method=method,
                             doPadding=True)

    return sampleFromGrid(grid, xypoints)
Ejemplo n.º 20
0
def test_intersection():
    fxmin, fxmax = (178.311, -179.189)
    fymin, fymax = (50.616, 52.176)
    fdx, fdy = (0.025, 0.02516129032258068)
    fnx, fny = (101, 63)
    host = GeoDict({'xmin': fxmin,
                    'xmax': fxmax,
                    'ymin': fymin,
                    'ymax': fymax,
                    'dx': fdx,
                    'dy': fdy,
                    'nx': fnx,
                    'ny': fny})
    sxmin, sxmax = (178.31249999999858, -179.19583333333335)
    symin, symax = (50.62083333333279, 52.17083333333278)
    sdx, sdy = (0.0083333333333333, 0.0083333333333333)
    snx, sny = (300, 187)
    sample = GeoDict({'xmin': sxmin,
                      'xmax': sxmax,
                      'ymin': symin,
                      'ymax': symax,
                      'dx': sdx,
                      'dy': sdy,
                      'nx': snx,
                      'ny': sny})
    ixmin, ixmax = (178.31249999999858, -179.19583333333478)
    iymin, iymax = (50.62083333333278, 52.17083333333278)
    idx, idy = (0.0083333333333333, 0.0083333333333333)
    inx, iny = (300, 187)
    result = GeoDict({'xmin': ixmin,
                      'xmax': ixmax,
                      'ymin': iymin,
                      'ymax': iymax,
                      'dx': idx,
                      'dy': idy,
                      'nx': inx,
                      'ny': iny})
    intersection = host.getIntersection(sample)
    np.testing.assert_allclose(intersection.xmin, ixmin)
    np.testing.assert_allclose(intersection.xmax, ixmax)
    np.testing.assert_allclose(intersection.ymin, iymin)
    np.testing.assert_allclose(intersection.ymax, iymax)
Ejemplo n.º 21
0
def test_interpolate():
    geodict = GeoDict({'xmin': 0.5, 'xmax': 6.5, 'ymin': 1.5,
                       'ymax': 6.5, 'dx': 1.0, 'dy': 1.0, 'ny': 6, 'nx': 7})
    data = np.arange(14, 56).reshape(6, 7)

    for method in ['nearest', 'linear', 'cubic']:
        print('Testing interpolate with method "%s"...' % method)
        grid = Grid2D(data, geodict)
        sampledict = GeoDict({'xmin': 3.0, 'xmax': 4.0,
                              'ymin': 3.0, 'ymax': 4.0,
                              'dx': 1.0, 'dy': 1.0,
                              'ny': 2, 'nx': 2})
        grid = grid.interpolateToGrid(sampledict, method=method)
        tgrid = grid.interpolate2(sampledict, method=method)
        if method == 'nearest':
            output = np.array([[30.0, 31.0], [37.0, 38.0]])
        elif method == 'linear':
            output = np.array([[34., 35.], [41., 42.]])
        elif method == 'cubic':
            output = np.array([[34., 35.], [41., 42.]])
        else:
            pass
        np.testing.assert_almost_equal(grid.getData(), output)
        print('Passed interpolate with method "%s".' % method)
        np.testing.assert_almost_equal(tgrid.getData(), output)
        print('Passed interpolate2 with method "%s".' % method)

    # speed test of interpolateToGrid and interpolate2
    geodict = GeoDict.createDictFromBox(0, 10, 0, 10, 0.01, 0.01)
    data = np.random.rand(geodict.ny, geodict.nx)
    grid = Grid2D(data, geodict)
    sampledict = GeoDict.createDictFromBox(2, 8, 2, 8, 0.098, 0.098)
    t1 = time.time()
    grid2 = grid.interpolateToGrid(sampledict, method='linear')
    t2 = time.time()
    grid3 = grid.interpolate2(sampledict, method='linear')
    t3 = time.time()
    # np.testing.assert_almost_equal(grid2._data.sum(),grid3._data.sum())
    print('scipy method: %.3f seconds' % (t2-t1))
    print('gdal  method: %.3f seconds' % (t3-t2))
Ejemplo n.º 22
0
def test_cut():
    geodict = GeoDict({'xmin': 0.5, 'xmax': 4.5, 'ymin': 0.5,
                       'ymax': 4.5, 'dx': 1.0, 'dy': 1.0, 'ny': 5, 'nx': 5})
    data = np.arange(0, 25).reshape(5, 5)

    print('Testing data extraction...')
    grid = Grid2D(data, geodict)
    xmin, xmax, ymin, ymax = (2.5, 3.5, 2.5, 3.5)
    newgrid = grid.cut(xmin, xmax, ymin, ymax)
    output = np.array([[7, 8], [12, 13]])
    np.testing.assert_almost_equal(newgrid.getData(), output)
    print('Passed data extraction...')

    print('Testing data trimming with resampling...')
    # make a more complicated test using getboundswithin
    data = np.arange(0, 84).reshape(7, 12)
    geodict = GeoDict({'xmin': -180, 'xmax': 150,
                       'ymin': -90, 'ymax': 90,
                       'dx': 30, 'dy': 30,
                       'nx': 12, 'ny': 7})
    grid = Grid2D(data, geodict)
    sampledict = GeoDict.createDictFromBox(-75,
                                           45, -45, 75, geodict.dx, geodict.dy)
    cutdict = geodict.getBoundsWithin(sampledict)
    newgrid = grid.cut(cutdict.xmin, cutdict.xmax, cutdict.ymin, cutdict.ymax)
    output = np.array([[16, 17, 18, 19],
                       [28, 29, 30, 31],
                       [40, 41, 42, 43],
                       [52, 53, 54, 55]])
    np.testing.assert_almost_equal(newgrid.getData(), output)
    print('Passed data trimming with resampling...')

    print('Test cut with self-alignment...')
    geodict = GeoDict({'xmin': 0.5, 'xmax': 4.5,
                       'ymin': 0.5, 'ymax': 6.5,
                       'dx': 1.0, 'dy': 1.0,
                       'nx': 5, 'ny': 7})
    data = np.arange(0, 35).astype(np.float32).reshape(7, 5)
    grid = Grid2D(data, geodict)
    cutxmin = 1.7
    cutxmax = 3.7
    cutymin = 1.7
    cutymax = 5.7
    cutgrid = grid.cut(cutxmin, cutxmax, cutymin, cutymax, align=True)
    output = np.array([[7, 8],
                       [12, 13],
                       [17, 18],
                       [22, 23]])
    np.testing.assert_almost_equal(cutgrid.getData(), output)
    print('Passed cut with self-alignment.')
Ejemplo n.º 23
0
def test_interpolate():
    geodict = GeoDict({'xmin':0.5,'xmax':6.5,'ymin':1.5,'ymax':6.5,'dx':1.0,'dy':1.0,'ny':6,'nx':7})
    data = np.arange(14,56).reshape(6,7)
    
    for method in ['nearest','linear','cubic']:
        print('Testing interpolate with method "%s"...' % method)
        grid = Grid2D(data,geodict)
        sampledict = GeoDict({'xmin':3.0,'xmax':4.0,
                              'ymin':3.0,'ymax':4.0,
                              'dx':1.0,'dy':1.0,
                              'ny':2,'nx':2})
        grid = grid.interpolateToGrid(sampledict,method=method)
        if method == 'nearest':
            output = np.array([[30.0,31.0],[37.0,38.0]])
        elif method == 'linear':
            output = np.array([[34.,35.],[41.,42.]])
        elif method == 'cubic':
            output = np.array([[34.,35.],[41.,42.]])
        else:
            pass
        np.testing.assert_almost_equal(grid.getData(),output)
        print('Passed interpolate with method "%s".' % method)
Ejemplo n.º 24
0
def big_test():
    xmin = -180
    xmax = -170
    ymin = 30
    ymax = 40
    dx = 0.0083
    dy = 0.0083
    gd = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
    data = np.random.rand(gd.ny, gd.nx)
    grid = Grid2D(data, gd)
    fname = os.path.join(os.path.expanduser('~'), 'tempfile.grd')
    write(grid, fname, 'hdf')
    print(fname)
    src = rasterio.open(fname, 'r')
Ejemplo n.º 25
0
def big_test():
    xmin = -180
    xmax = -170
    ymin = 30
    ymax = 40
    dx = 0.0083
    dy = 0.0083
    gd = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
    data = np.random.rand(gd.ny, gd.nx)
    grid = Grid2D(data, gd)
    fname = os.path.join(os.path.expanduser('~'), 'tempfile.grd')
    write(grid, fname, 'hdf')
    print(fname)
    src = rasterio.open(fname, 'r')
Ejemplo n.º 26
0
def create_overlay_image(container, filename):
    """Create a semi-transparent PNG image of intensity.

    Args:
        container (ShakeMapOutputContainer): Results of model.conf.
        filename (str): Path to desired output PNG file.
    Returns:
        GeoDict: GeoDict object for the intensity grid.
    """
    # extract the intensity data from the container
    comp = container.getComponents('MMI')
    if len(comp) == 0:
        return None
    comp = comp[0]
    imtdict = container.getIMTGrids('MMI', comp)
    mmigrid = imtdict['mean']
    gd = GeoDict(imtdict['mean_metadata'])
    imtdata = mmigrid.copy()
    rows, cols = imtdata.shape

    # get the intensity colormap
    palette = ColorPalette.fromPreset('mmi')

    # map intensity values into
    # RGBA array
    rgba = palette.getDataColor(imtdata, color_format='array')

    # set the alpha value to 255 wherever we have MMI 0
    rgba[imtdata <= 1.5] = 0

    if 'CALLED_FROM_PYTEST' not in os.environ:
        # mask off the areas covered by ocean
        oceans = shpreader.natural_earth(category='physical',
                                         name='ocean',
                                         resolution='10m')
        bbox = (gd.xmin, gd.ymin, gd.xmax, gd.ymax)
        with fiona.open(oceans) as c:
            tshapes = list(c.items(bbox=bbox))
            shapes = []
            for tshp in tshapes:
                shapes.append(shape(tshp[1]['geometry']))
            if len(shapes):
                oceangrid = Grid2D.rasterizeFromGeometry(shapes, gd,
                                                         fillValue=0.0)
                rgba[oceangrid.getData() == 1] = 0

    # save rgba image as png
    img = Image.fromarray(rgba)
    img.save(filename)
    return gd
Ejemplo n.º 27
0
def test_project():
    data = np.array([[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1],
                     [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]],
                    dtype=np.int32)
    geodict = {
        'xmin': 50,
        'xmax': 50.4,
        'ymin': 50,
        'ymax': 50.4,
        'dx': 0.1,
        'dy': 0.1,
        'nx': 5,
        'ny': 5
    }
    gd = GeoDict(geodict)
    grid = GDALGrid(data, gd)
    projstr = "+proj=utm +zone=40 +north +ellps=WGS84 +datum=WGS84 +units=m +no_defs "
    newgrid = grid.project(projstr, method='nearest')

    try:
        tdir = tempfile.mkdtemp()
        outfile = os.path.join(tdir, 'output.bil')
        grid.save(outfile)
        with rasterio.open(outfile) as src:
            aff = get_affine(src)
            data = src.read(1)
            src_crs = CRS().from_string(GeoDict.DEFAULT_PROJ4).to_dict()
            dst_crs = CRS().from_string(projstr).to_dict()
            nrows, ncols = data.shape
            left = aff.xoff
            top = aff.yoff
            right, bottom = aff * (ncols - 1, nrows - 1)
            dst_transform, width, height = calculate_default_transform(
                src_crs, dst_crs, ncols, nrows, left, bottom, right, top)
            destination = np.zeros((height, width))
            reproject(data,
                      destination,
                      src_transform=aff,
                      src_crs=src_crs,
                      dst_transform=dst_transform,
                      dst_crs=dst_crs,
                      src_nodata=src.nodata,
                      dst_nodata=np.nan,
                      resampling=Resampling.nearest)
            x = 1
    except:
        pass
    finally:
        shutil.rmtree(tdir)
Ejemplo n.º 28
0
    def fromBounds(cls,
                   xmin,
                   xmax,
                   ymin,
                   ymax,
                   dx,
                   dy,
                   defaultVs30=686.0,
                   vs30File=None,
                   vs30measured_grid=None,
                   backarc=None,
                   padding=False,
                   resample=False):
        """
        Create a Sites object by defining a center point, resolution, extent,
        and Vs30 values.

        Args:
            xmin: X coordinate of left edge of bounds.
            xmax: X coordinate of right edge of bounds.
            ymin: Y coordinate of bottom edge of bounds.
            ymax: Y coordinate of top edge of bounds.
            dx: Resolution of desired grid in X direction.
            dy: Resolution of desired grid in Y direction.
            defaultVs30: Default Vs30 value to use if vs30File not specified.
            vs30File: Name of GMT or GDAL format grid file containing Vs30
                values.
            vs30measured_grid: Boolean grid indicating whether Vs30 values were
                measured or derived (i.e., from slope).
            backarc: Boolean array indicating whether site is in the subduction
                `backarc <http://earthquake.usgs.gov/learn/glossary/?term=backarc>`__.
            padding: Boolean indicating whether or not to pad resulting Vs30
                grid out to edges of input bounds. If False, grid will be
                clipped to the extent of the input file.
            resample: Boolean indicating whether or not the grid should be
                resampled.
        """  # noqa
        geodict = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
        if vs30File is not None:
            vs30grid = cls._create(geodict, defaultVs30, vs30File, padding,
                                   resample)
        else:
            griddata = np.ones(
                (geodict.ny, geodict.nx), dtype=np.float64) * defaultVs30
            vs30grid = Grid2D(griddata, geodict)
        return cls(vs30grid,
                   vs30measured_grid=vs30measured_grid,
                   backarc=backarc,
                   defaultVs30=defaultVs30)
Ejemplo n.º 29
0
def test_lat_lon_array():
    gd = GeoDict({'xmin': 0, 'xmax': 4,
                  'ymin': 0, 'ymax': 3,
                  'dx': 1.0, 'dy': 1.0,
                  'nx': 5, 'ny': 4})
    lat = np.array([0, 1, 2], dtype=np.float32)
    lon = np.array([2, 2, 2], dtype=np.float32)
    trow = np.array([3, 2, 1])
    tcol = np.array([2, 2, 2])
    row, col = gd.getRowCol(lat, lon)
    np.testing.assert_almost_equal(trow, row)
    np.testing.assert_almost_equal(tcol, col)

    gd = GeoDict({'xmin': 176, 'xmax': -176,
                  'ymin': 0, 'ymax': 6,
                  'nx': 5, 'ny': 4,
                  'dx': 2, 'dy': 2})
    lat = np.array([2, 4, 6], dtype=np.float32)
    lon = np.array([178, 180, -178], dtype=np.float32)
    row, col = gd.getRowCol(lat, lon)
    trow = np.array([2, 1, 0])
    tcol = np.array([1, 2, 3])
    np.testing.assert_almost_equal(trow, row)
    np.testing.assert_almost_equal(tcol, col)
Ejemplo n.º 30
0
def test_bounds_within_real():
    fxmin, fxmax = (-179.995833333333, 179.99583333189372)
    fymin, fymax = (-89.99583333333332, 89.9958333326134)
    fdx, fdy = (0.0083333333333, 0.0083333333333)
    fnx, fny = (43200, 21600)
    xmin, xmax = (177.75, -179.75)
    ymin, ymax = (50.41625, 51.98375)
    dx, dy = (0.025, 0.02488095238095242)
    nx, ny = (101, 64)
    host = GeoDict({
        'xmin': fxmin,
        'xmax': fxmax,
        'ymin': fymin,
        'ymax': fymax,
        'dx': fdx,
        'dy': fdy,
        'nx': fnx,
        'ny': fny
    })
    sample = GeoDict({
        'xmin': xmin,
        'xmax': xmax,
        'ymin': ymin,
        'ymax': ymax,
        'dx': dx,
        'dy': dy,
        'nx': nx,
        'ny': ny
    })
    result = GeoDict({
        'xmin': 60,
        'xmax': -120,
        'ymin': -30,
        'ymax': 30,
        'dx': 60,
        'dy': 30,
        'nx': 4,
        'ny': 3
    })
    inside = host.getBoundsWithin(sample)
    ixmin, ixmax = (177.75416666523603, -179.7541666666673)
    iymin, iymax = (50.4208333327717, 51.9791666660988)
    idx, idy = (0.0083333333333, 0.0083333333333)
    inx, iny = (300, 188)
    result = GeoDict({
        'xmin': ixmin,
        'xmax': ixmax,
        'ymin': iymin,
        'ymax': iymax,
        'dx': idx,
        'dy': idy,
        'nx': inx,
        'ny': iny
    })
    assert inside == result
Ejemplo n.º 31
0
def test_read_meridian():
    # where is this script?
    homedir = os.path.dirname(os.path.abspath(__file__))
    # this is an HDF 5 file
    datafile = os.path.join(homedir, 'data', 'globalgrid_cdf.cdf')
    sdict = {'xmin': 180,
             'xmax': -120,
             'ymin': 0,
             'ymax': 30,
             'nx': 2,
             'ny': 2,
             'dx': 60,
             'dy': 30}
    sampledict = GeoDict(sdict)
    grid = read(datafile, samplegeodict=sampledict)
    assert np.nansum(grid._data) == 50.0
Ejemplo n.º 32
0
def sampleGridFile(gridfile,xypoints,method='nearest'):
    """
    Sample grid file (ESRI or GMT format) at each of a set of XY (decimal degrees) points.
    :param gridfile:
      Name of ESRI or GMT grid format file from which to sample values.
    :param xypoints:
      2D numpy array of XY points, decimal degrees.
    :param method:
      Interpolation method, either 'nearest' or 'linear'.
    :returns:
      1D numpy array of grid values at each of input XY points.
    """
    if not len(xypoints):
        return np.array([])
    xmin = np.min(xypoints[:,0])
    xmax = np.max(xypoints[:,0])
    ymin = np.min(xypoints[:,1])
    ymax = np.max(xypoints[:,1])
    gridtype = None
    try:
        fdict,tmp = GMTGrid.getFileGeoDict(gridfile)
        gridtype = 'gmt'
    except Exception as error:
        try:
            fdict,tmp = GDALGrid.getFileGeoDict(gridfile)
            gridtype = 'esri'
        except:
            pass
    if gridtype is None:
        raise Exception('File "%s" does not appear to be either a GMT grid or an ESRI grid.' % gridfile)
    xmin = xmin - fdict.dx*3
    xmax = xmax + fdict.dx*3
    ymin = ymin - fdict.dy*3
    ymax = ymax + fdict.dy*3
    bounds = (xmin,xmax,ymin,ymax)
    if gridtype == 'gmt':
        fgeodict,tmp = GMTGrid.getFileGeoDict(gridfile)
    else:
        fgeodict,tmp = GDALGrid.getFileGeoDict(gridfile)
    dx,dy = (fgeodict.dx,fgeodict.dy)
    sdict = GeoDict.createDictFromBox(xmin,xmax,ymin,ymax,dx,dy)
    if gridtype == 'gmt':
        grid = GMTGrid.load(gridfile,samplegeodict=sdict,resample=True,method=method,doPadding=True)
    else:
        grid = GDALGrid.load(gridfile,samplegeodict=sdict,resample=True,method=method,doPadding=True)

    return sampleFromGrid(grid,xypoints)
Ejemplo n.º 33
0
def get_data_range_test():
    # a standard global grid, going from -180 to 180
    normal_dict = GeoDict({'xmin': -180, 'xmax': 120,
                           'ymin': -90, 'ymax': 90,
                           'dx': 60, 'dy': 45,
                           'nx': 6, 'ny': 5})

    # test a simple example which does NOT cross the 180 meridian
    sample1 = (-125, 65, -20, 20)
    dict1 = Grid2D.getDataRange(normal_dict, sample1)
    cdict1 = {'iulx1': 0, 'iuly1': 1,
              'ilrx1': 6, 'ilry1': 4}
    assert dict1 == cdict1

    # test a less-simple example which DOES cross the 180 meridian
    sample2 = (-235, -10, -20, 20)
    dict2 = Grid2D.getDataRange(normal_dict, sample2)
    cdict2 = {'iulx1': 5, 'iuly1': 1,
              'ilrx1': 6, 'ilry1': 4,
              'iulx2': 0, 'iuly2': 1,
              'ilrx2': 4, 'ilry2': 4}
    assert dict2 == cdict2

    # test a less-simple example which DOES cross the 180 meridian, and xmin > xmax
    sample3 = (125, -10, -20, 20)
    dict3 = Grid2D.getDataRange(normal_dict, sample3)
    cdict3 = {'iulx1': 5, 'iuly1': 1,
              'ilrx1': 6, 'ilry1': 4,
              'iulx2': 0, 'iuly2': 1,
              'ilrx2': 4, 'ilry2': 4}
    assert dict3 == cdict3

    # test an example where the sample bounds are from 0 to 360
    sample4 = (160, 200, -20, 20)
    dict4 = Grid2D.getDataRange(normal_dict, sample4)
    cdict4 = {'iulx1': 5, 'iuly1': 1,
              'ilrx1': 6, 'ilry1': 4,
              'iulx2': 0, 'iuly2': 1,
              'ilrx2': 2, 'ilry2': 4}
    assert dict4 == cdict4

    # test an example where the sample bounds are from 0 to 360
    sample5 = (220, 260, -20, 20)
    dict5 = Grid2D.getDataRange(normal_dict, sample5)
    cdict5 = {'iulx1': 0, 'iuly1': 1,
              'ilrx1': 3, 'ilry1': 4}
    assert dict5 == cdict5
Ejemplo n.º 34
0
def test_read_subset_no_resample():
    # where is this script?
    homedir = os.path.dirname(os.path.abspath(__file__))
    # this is an HDF 5 file
    datafile = os.path.join(homedir, 'data', 'samplegrid_cdf.cdf')
    sdict = {'xmin': 6,
             'xmax': 7,
             'ymin': 5,
             'ymax': 6,
             'nx': 2,
             'ny': 2,
             'dx': 1,
             'dy': 1}
    sampledict = GeoDict(sdict)
    grid = read(datafile, samplegeodict=sampledict)
    tdata = np.array([[11, 12], [16, 17]])
    np.testing.assert_almost_equal(grid._data, tdata)
Ejemplo n.º 35
0
    def fromBounds(cls, xmin, xmax, ymin, ymax, dx, dy, defaultVs30=686.0,
                         vs30File=None, vs30measured_grid=None,
                         backarc=None, padding=False, resample=False):
        """
        Create a Sites object by defining a center point, resolution, extent, 
        and Vs30 values.

        :param xmin:
            X coordinate of left edge of bounds.
        :param xmax:
            X coordinate of right edge of bounds.
        :param ymin:
            Y coordinate of bottom edge of bounds.
        :param ymax:
            Y coordinate of top edge of bounds.
        :param dx:
            Resolution of desired grid in X direction.
        :param dy:
            Resolution of desired grid in Y direction.
        :param defaultVs30:
            Default Vs30 value to use if vs30File not specified.
        :param vs30File:
            Name of GMT or GDAL format grid file containing Vs30 values.
        :param vs30measured_grid:
            Boolean grid indicating whether Vs30 values were measured or derived 
            (i.e., from slope)
        :param backarc:
            Boolean array indicating whether site is in the subduction 
            `backarc <http://earthquake.usgs.gov/learn/glossary/?term=backarc>`__.
        :param padding:
            Boolean indicating whether or not to pad resulting Vs30 grid out to
            edges of input bounds. If False, grid will be clipped to the extent
            of the input file.
        :param resample:
            Boolean indicating whether or not the grid should be resampled.
        """
        geodict = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
        if vs30File is not None:
            vs30grid = cls._create(geodict, defaultVs30,
                                   vs30File, padding, resample)
        else:
            griddata = np.ones((geodict.ny, geodict.nx),
                               dtype=np.float64) * defaultVs30
            vs30grid = Grid2D(griddata, geodict)
        return cls(vs30grid, vs30measured_grid=vs30measured_grid,
                   backarc=backarc, defaultVs30=defaultVs30)
Ejemplo n.º 36
0
def test_read_subset_with_padding():
    # where is this script?
    homedir = os.path.dirname(os.path.abspath(__file__))
    # this is an HDF 5 file
    datafile = os.path.join(homedir, 'data', 'samplegrid_cdf.cdf')
    sdict = {'xmin': 4.5,
             'xmax': 5.5,
             'ymin': 7.5,
             'ymax': 8.5,
             'nx': 2,
             'ny': 2,
             'dx': 1,
             'dy': 1}
    sampledict = GeoDict(sdict)
    grid = read(datafile, samplegeodict=sampledict,
                resample=False, doPadding=True)
    assert grid._data.shape == (3, 3)
    assert grid._data[1, 1] == 0
Ejemplo n.º 37
0
def test_resample():
    # this should fail
    # where is this script?
    homedir = os.path.dirname(os.path.abspath(__file__))
    # this is an HDF 5 file
    datafile = os.path.join(homedir, 'data', 'samplegrid_cdf.cdf')
    sdict = {'xmin': 6.5,
             'xmax': 7.5,
             'ymin': 5.5,
             'ymax': 6.5,
             'nx': 2,
             'ny': 2,
             'dx': 1,
             'dy': 1}
    sampledict = GeoDict(sdict)
    grid = read(datafile, samplegeodict=sampledict, resample=True)
    tdata = np.array([[9, 10], [14, 15]])
    np.testing.assert_almost_equal(grid._data, tdata)
Ejemplo n.º 38
0
def test_read_subset_with_resample_and_padding():
    # where is this script?
    homedir = os.path.dirname(os.path.abspath(__file__))
    # this is an HDF 5 file
    datafile = os.path.join(homedir, 'data', 'samplegrid_cdf.cdf')
    sdict = {'xmin': 4.5,
             'xmax': 5.5,
             'ymin': 7.5,
             'ymax': 8.5,
             'nx': 2,
             'ny': 2,
             'dx': 1,
             'dy': 1}
    sampledict = GeoDict(sdict)
    grid = read(datafile, samplegeodict=sampledict,
                resample=True, doPadding=True)
    atest = np.array([[np.nan, np.nan],
                      [np.nan,  3.]])
    np.testing.assert_almost_equal(grid._data, atest)
Ejemplo n.º 39
0
def test_mapmaker_contour():
    homedir = os.path.dirname(os.path.abspath(
        __file__))  # where is this script?
    shakedir = os.path.abspath(os.path.join(homedir, '..', '..', '..'))
    out_file = os.path.join(shakedir, 'tests', 'data',
                            'containers', 'northridge',
                            'shake_result.hdf')
    container = ShakeMapOutputContainer.load(out_file)
    topofile = os.path.join(homedir, '..', '..', 'data', 'install', 'data',
                            'mapping', 'CA_topo.grd')

    info = container.getMetadata()
    xmin = info['output']['map_information']['min']['longitude']
    xmax = info['output']['map_information']['max']['longitude']
    ymin = info['output']['map_information']['min']['latitude']
    ymax = info['output']['map_information']['max']['latitude']
    xmin = float(xmin) - 0.1
    xmax = float(xmax) + 0.1
    ymin = float(ymin) - 0.1
    ymax = float(ymax) + 0.1
    dy = float(info['output']['map_information']
               ['grid_spacing']['latitude'])
    dx = float(info['output']['map_information']
               ['grid_spacing']['longitude'])
    sampledict = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
    topogrid = GMTGrid.load(topofile,
                            samplegeodict=sampledict,
                            resample=False)

    oceanfile = os.path.join(homedir, '..', '..', 'data', 'install', 'data',
                             'mapping', 'northridge_ocean.json')
    outpath = mkdtemp()
    filter_size = 10
    try:
        pdf, png = draw_contour(container, 'PGA', topogrid, oceanfile,
                                outpath, 'NEIC', filter_size)
        print(pdf)
    except Exception:
        assert 1 == 2
    finally:
        shutil.rmtree(outpath)
Ejemplo n.º 40
0
def test_modify():
    print('Testing ShakeGrid interpolate() method...')
    geodict = GeoDict({
        'xmin': 0.5,
        'xmax': 6.5,
        'ymin': 1.5,
        'ymax': 6.5,
        'dx': 1.0,
        'dy': 1.0,
        'ny': 6,
        'nx': 7
    })
    data = np.arange(14, 56).reshape(6, 7)
    layers = OrderedDict()
    layers['pga'] = data
    shakeDict = {
        'event_id': 'usabcd1234',
        'shakemap_id': 'usabcd1234',
        'shakemap_version': 1,
        'code_version': '4.0',
        'process_timestamp': datetime.utcnow(),
        'shakemap_originator': 'us',
        'map_status': 'RELEASED',
        'shakemap_event_type': 'ACTUAL'
    }
    eventDict = {
        'event_id': 'usabcd1234',
        'magnitude': 7.6,
        'depth': 1.4,
        'lat': 2.0,
        'lon': 2.0,
        'event_timestamp': datetime.utcnow(),
        'event_network': 'us',
        'event_description': 'sample event'
    }
    uncDict = {'pga': (0.0, 0)}
    shake = ShakeGrid(layers, geodict, eventDict, shakeDict, uncDict)
    rdata = np.random.rand(data.shape[0], data.shape[1])
    shake.setLayer('pga', rdata)
    newdata = shake.getLayer('pga').getData()
    np.testing.assert_almost_equal(rdata, newdata)
Ejemplo n.º 41
0
    def getGrid(self, name):
        """
        Retrieve a Grid2D object and any associated metadata from the container.

        Args:
            name (str):
                The name of the Grid2D object stored in the container.

        Returns:
            (tuple) Grid2D object, and a dictionary of metadata.
        """
        array_name = '__grid_%s__' % name
        if array_name not in self._hdfobj:
            raise LookupError('Array %s not in %s' %
                              (name, self.getFileName()))
        dset = self._hdfobj[array_name]
        data = dset[()]
        array_metadata, meta_metadata = _split_dset_attrs(dset)
        geodict = GeoDict(array_metadata)
        grid = Grid2D(data, geodict)
        return grid, meta_metadata
Ejemplo n.º 42
0
    def createFromCenter(cls,cx,cy,xspan,yspan,dx,dy,defaultVs30=686.0,vs30File=None,
                         vs30measured_grid=None,backarc=False,padding=False,resample=False):
        """Create a Sites object by defining a center point, resolution, extent, and Vs30 values.

        :param cx:
          X coordinate of desired center point.
        :param cy:
          X coordinate of desired center point.
        :param xspan:
          Width of desired grid.
        :param yspan:
          Height of desired grid.
        :param dx:
          Resolution of desired grid in X direction.
        :param dy:
          Resolution of desired grid in Y direction.
        :param defaultVs30:
          Default Vs30 value to use if vs30File not specified.
        :param vs30File:
          Name of GMT or GDAL format grid file containing Vs30 values.
        :param vs30measured_grid:
          Boolean grid indicating whether Vs30 values were measured or derived (i.e., from slope)
        :param backarc:
          Boolean indicating whether event is on the backarc as defined here: 
          http://earthquake.usgs.gov/learn/glossary/?term=backarc
        :param padding:
          Boolean indicating whether or not to pad resulting Vs30 grid out to edges of input
          bounds.  If False, grid will be clipped to the extent of the input file.
        :param resample:
          Boolean indicating whether or not the grid should be resampled.
        """
        geodict = GeoDict.createDictFromCenter(cx,cy,dx,dy,xspan,yspan)
        if vs30File is not None:
            vs30grid = cls._create(geodict,defaultVs30,vs30File,padding,resample)
        else:
            griddata = np.ones((geodict.ny,geodict.nx), dtype=np.float64)*defaultVs30
            vs30grid = Grid2D(griddata,geodict)
        return cls(vs30grid,vs30measured_grid=vs30measured_grid,backarc=backarc,
                   defaultVs30=defaultVs30)
Ejemplo n.º 43
0
def test_getvalue():
    array = np.arange(1, 26).reshape(5, 5)
    gdict = GeoDict({'xmin': 1.0,
                     'xmax': 5.0,
                     'ymin': 1.0,
                     'ymax': 5.0,
                     'dx': 1.0,
                     'dy': 1.0,
                     'nx': 5,
                     'ny': 5})
    grid = Grid2D(array, gdict)
    assert grid.getValue(3.0, 3.0) == 13
    lat = np.array([3.0, 4.0])
    lon = np.array([3.0, 3.0])
    test = grid.getValue(lat, lon)
    np.testing.assert_almost_equal(test, np.array([13, 8]))
    lat = np.array([[3.0, 4.0],
                    [4.0, 5.0]])
    lon = np.array([[3.0, 3.0],
                    [4.0, 4.0]])
    test = grid.getValue(lat, lon)
    np.testing.assert_almost_equal(test, np.array([[13,  8], [9,  4]]))
Ejemplo n.º 44
0
def read_user_file_test(fname, xmin, xmax, ymin, ymax):
    gd = get_file_geodict(fname)
    sample = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, gd.dx, gd.dy)
    t1 = time.time()
    grid = read(fname, samplegeodict=sample)
    t2 = time.time()
    nrows, ncols = grid._data.shape
    npixels = nrows*ncols
    print('%.2f seconds to read %i pixels using h5py' % (t2-t1, npixels))

    west, east, south, north = (-105.00416666665,
                                -102.98750000804999,
                                34.98750000805,
                                37.00416666665)
    src = rasterio.open(fname, 'r')
    window = src.window(west, south, east, north)
    t1 = time.time()
    data = src.read(window=window)
    t2 = time.time()
    print('%.2f seconds to read %i pixels using rasterio' % (t2-t1, npixels))
    ratio = grid._data.sum()/data.sum()
    print('Ratio of h5py data to rasterio data is %.4f' % ratio)
    src.close()
Ejemplo n.º 45
0
def test_shapes():
    gd = GeoDict.createDictFromBox(100.0, 102.0, 32.0, 34.0, 0.08, 0.08)

    # pass in scalar values
    inrow, incol = (10, 10)
    lat, lon = gd.getLatLon(inrow, incol)  # should get scalar results
    assert np.isscalar(lat) and np.isscalar(lon)

    # pass in array values
    inrow = np.array([10, 11, 12])
    incol = np.array([10, 11, 12])
    lat, lon = gd.getLatLon(inrow, incol)  # should get array results
    c1 = isinstance(lat, np.ndarray) and lat.shape == inrow.shape
    c2 = isinstance(lon, np.ndarray) and lon.shape == incol.shape
    assert c1 and c2

    # this should fail, because inputs are un-dimensioned numpy arrays
    inrow = np.array(10)
    incol = np.array(10)
    try:
        lat, lon = gd.getLatLon(inrow, incol)  # should get array results
        assert 1 == 0  # this should never happen
    except DataSetException as dse:
        pass
Ejemplo n.º 46
0
def test():
    # these values taken from the shakemap header of:
    # http://earthquake.usgs.gov/realtime/product/shakemap/ak12496371/ak/1453829475592/download/grid.xml

    print('Testing various dictionaries for consistency...')

    print('Testing consistent dictionary...')
    # this should pass, and will serve as the comparison from now on
    gdict = {'xmin': -160.340600, 'xmax': -146.340600,
             'ymin': 54.104700, 'ymax': 65.104700,
             'dx': 0.025000, 'dy': 0.025000,
             'ny': 441, 'nx': 561}
    gd = GeoDict(gdict)
    print('Consistent dictionary passed.')

    print('Testing dictionary with inconsistent resolution...')
    # this should pass
    gdict = {'xmin': -160.340600, 'xmax': -146.340600,
             'ymin': 54.104700, 'ymax': 65.104700,
             'dx': 0.026000, 'dy': 0.026000,
             'ny': 441, 'nx': 561}
    gd3 = GeoDict(gdict, adjust='res')
    assert gd3 == gd
    print('Dimensions modification passed.')

    print('Testing dictionary with inconsistent lower right corner...')
    # this should pass
    gdict = {'xmin': -160.340600, 'xmax': -146.350600,
             'ymin': 54.103700, 'ymax': 65.104700,
             'dx': 0.025000, 'dy': 0.025000,
             'ny': 441, 'nx': 561}
    gd4 = GeoDict(gdict, adjust='bounds')
    assert gd4 == gd
    print('Corner modification passed.')

    print('Testing to make sure lat/lon and row/col calculations are correct...')
    # make sure the lat/lon row/col calculations are correct
    ndec = int(np.abs(np.log10(GeoDict.EPS)))
    lat, lon = gd.getLatLon(0, 0)
    dlat = np.abs(lat-gd.ymax)
    dlon = np.abs(lon-gd.xmin)
    assert dlat < GeoDict.EPS and dlon < GeoDict.EPS
    row, col = gd.getRowCol(lat, lon)
    assert row == 0 and col == 0

    lat, lon = gd.getLatLon(gd.ny-1, gd.nx-1)
    dlat = np.abs(lat-gd.ymin)
    dlon = np.abs(lon-gd.xmax)
    assert dlat < GeoDict.EPS and dlon < GeoDict.EPS
    row, col = gd.getRowCol(lat, lon)
    assert row == (gd.ny-1) and col == (gd.nx-1)
    print('lat/lon and row/col calculations are correct.')

    print('Testing a dictionary for a global grid...')
    # this is the file geodict for Landscan - should pass muster
    globaldict = {'nx': 43200,
                  'ny': 20880,
                  'dx': 0.00833333333333,
                  'xmax': 179.99583333318935,
                  'xmin': -179.99583333333334,
                  'dy': 0.00833333333333,
                  'ymax': 83.99583333326376,
                  'ymin': -89.99583333333334}
    gd5 = GeoDict(globaldict)
    lat, lon = gd5.getLatLon(gd5.ny-1, gd5.nx-1)
    dlat = np.abs(lat-gd5.ymin)
    dlon = np.abs(lon-gd5.xmax)
    assert dlat < GeoDict.EPS and dlon < GeoDict.EPS
    print('Global grid is internally consistent.')

    # Test class methods for creating a GeoDict
    print('Testing whether GeoDict creator class methods work...')
    xmin = -121.05333277776235
    xmax = -116.03833388890432
    ymin = 32.138334444506171
    ymax = 36.286665555493826
    dx = 0.0083333333333333332
    dy = 0.0083333333333333332
    gd6 = GeoDict.createDictFromBox(
        xmin, xmax, ymin, ymax, dx, dy, inside=False)
    assert gd6.xmax > xmax
    assert gd6.ymin < ymin
    print('Created dictionary (outside) is correct.')
    gd7 = GeoDict.createDictFromBox(
        xmin, xmax, ymin, ymax, dx, dy, inside=True)
    assert gd7.xmax < xmax
    assert gd7.ymin > ymin
    print('Created dictionary (inside) is correct.')
    xspan = 2.5
    yspan = 2.5
    gd8 = GeoDict.createDictFromCenter(xmin, ymin, dx, dy, xspan, yspan)
    print('Created dictionary (from center point) is valid.')

    print('Testing a geodict with dx/dy values that are NOT the same...')
    xmin, xmax, ymin, ymax = (-121.06166611109568, -116.03000055557099,
                              32.130001111172838, 36.294998888827159)
    dx, dy = (0.009999722214505959, 0.009999444413578534)
    td = GeoDict.createDictFromBox(xmin, xmax, ymin, ymax, dx, dy)
    print('Passed testing a geodict with dx/dy values that are NOT the same...')

    # test getBoundsWithin
    # use global grid, and then a shakemap grid that we can get
    print('Testing getBoundsWithin...')
    grussia = {'xmin': 155.506400, 'xmax': 161.506400,
               'ymin': 52.243000, 'ymax': 55.771000,
               'dx': 0.016667, 'dy': 0.016642,
               'nx': 361, 'ny': 213}
    gdrussia = GeoDict(grussia, adjust='res')
    sampledict = gd5.getBoundsWithin(gdrussia)
    xSmaller = sampledict.xmin > grussia['xmin'] and sampledict.xmax < grussia['xmax']
    ySmaller = sampledict.ymin > grussia['ymin'] and sampledict.ymax < grussia['ymax']
    assert xSmaller and ySmaller
    assert gd5.isAligned(sampledict)
    print('getBoundsWithin returned correct result.')

    print('Testing isAligned() method...')
    gd = GeoDict({'xmin': 0.5, 'xmax': 3.5,
                  'ymin': 0.5, 'ymax': 3.5,
                  'dx': 1.0, 'dy': 1.0,
                  'nx': 4, 'ny': 4})

    inside_aligned = GeoDict({'xmin': 1.5, 'xmax': 2.5,
                              'ymin': 1.5, 'ymax': 2.5,
                              'dx': 1.0, 'dy': 1.0,
                              'nx': 2, 'ny': 2})
    inside_not_aligned = GeoDict({'xmin': 2.0, 'xmax': 3.0,
                                  'ymin': 2.0, 'ymax': 3.0,
                                  'dx': 1.0, 'dy': 1.0,
                                  'nx': 2, 'ny': 2})
    assert gd.isAligned(inside_aligned)
    assert not gd.isAligned(inside_not_aligned)
    print('Passed isAligned() method...')

    print('Testing getAligned method...')
    popdict = GeoDict({'dx': 0.00833333333333,
                       'dy': 0.00833333333333,
                       'nx': 43200,
                       'ny': 20880,
                       'xmax': 179.99583333318935,
                       'xmin': -179.99583333333334,
                       'ymax': 83.99583333326376,
                       'ymin': -89.99583333333334})
    sampledict = GeoDict({'dx': 0.008333333333333333,
                          'dy': 0.008336693548387094,
                          'nx': 601,
                          'ny': 497,
                          'xmax': -116.046,
                          'xmin': -121.046,
                          'ymax': 36.2785,
                          'ymin': 32.1435})
    aligndict = popdict.getAligned(sampledict)
    assert popdict.isAligned(aligndict)

    print('Testing geodict intersects method...')
    gd1 = GeoDict({'xmin': 0.5, 'xmax': 3.5,
                   'ymin': 0.5, 'ymax': 3.5,
                   'dx': 1.0, 'dy': 1.0,
                   'nx': 4, 'ny': 4})

    print('Testing geodict intersects method...')
    gd2 = GeoDict({'xmin': 2.5, 'xmax': 5.5,
                   'ymin': 2.5, 'ymax': 5.5,
                   'dx': 1.0, 'dy': 1.0,
                   'nx': 4, 'ny': 4})
    gd3 = GeoDict({'xmin': 4.5, 'xmax': 7.5,
                   'ymin': 4.5, 'ymax': 7.5,
                   'dx': 1.0, 'dy': 1.0,
                   'nx': 4, 'ny': 4})
    gd4 = GeoDict({'xmin': 1.5, 'xmax': 2.5,
                   'ymin': 1.5, 'ymax': 2.5,
                   'dx': 1.0, 'dy': 1.0,
                   'nx': 2, 'ny': 2})
    assert gd1.intersects(gd2)
    assert not gd1.intersects(gd3)
    print('Passed intersects method...')

    print('Testing geodict intersects method with real geographic data...')
    gda = GeoDict({'ymax': 83.62083333333263, 'nx': 43201,
                   'ny': 20835, 'dx': 0.00833333333333,
                   'dy': 0.00833333333333, 'xmin': -179.99583333333334,
                   'ymin': -89.99583333326461, 'xmax': -179.99583333347732})
    gdb = GeoDict({'ymax': 28.729166666619193, 'nx': 300,
                   'ny': 264, 'dx': 0.00833333333333,
                   'dy': 0.00833333333333, 'xmin': 84.08749999989436,
                   'ymin': 26.537499999953404, 'xmax': 86.57916666656007})
    assert gda.intersects(gdb)
    print('Passed geodict intersects method with real geographic data.')

    print('Testing geodict doesNotContain method...')
    assert gd1.doesNotContain(gd3)
    assert not gd1.doesNotContain(gd4)

    print('Passed doesNotContain method...')

    print('Testing geodict contains method...')

    assert gd1.contains(gd4)
    assert not gd1.contains(gd3)
    print('Passed contains method...')
Ejemplo n.º 47
0
def test_project():
    # test projecting a grid that wraps the 180 meridian
    gd = GeoDict.createDictFromBox(175, -175, -5, 5, 1.0, 1.0)
    ncells = gd.ny * gd.nx
    data = np.arange(0.0, ncells).reshape(gd.ny, gd.nx)
    grid = GDALGrid(data, gd)
    projstr = "+proj=merc +lat_ts=55 +lon_0=180 +ellps=WGS84"
    newgrid = grid.project(projstr, method='nearest')
    proj = pyproj.Proj(projstr)
    # what would the ul/lr corners be?
    ulx, uly = proj(grid._geodict.xmin, grid._geodict.ymax)
    lrx, lry = proj(grid._geodict.xmax, grid._geodict.ymin)
    # what if we back-project?
    newxmin, newymax = proj(newgrid._geodict.xmin,
                            newgrid._geodict.ymax, inverse=True)
    newxmax, newymin = proj(newgrid._geodict.xmax,
                            newgrid._geodict.ymin, inverse=True)
    x = 1

    # test simple projection
    data = np.array([[0, 0, 1, 0, 0],
                     [0, 0, 1, 0, 0],
                     [1, 1, 1, 1, 1],
                     [0, 0, 1, 0, 0],
                     [0, 0, 1, 0, 0]], dtype=np.int32)
    geodict = {'xmin': 50, 'xmax': 50.4, 'ymin': 50,
               'ymax': 50.4, 'dx': 0.1, 'dy': 0.1, 'nx': 5, 'ny': 5}
    gd = GeoDict(geodict)
    grid = GDALGrid(data, gd)
    projstr = "+proj=utm +zone=40 +north +ellps=WGS84 +datum=WGS84 +units=m +no_defs "
    newgrid = grid.project(projstr, method='nearest')

    try:
        tdir = tempfile.mkdtemp()
        outfile = os.path.join(tdir, 'output.bil')
        grid.save(outfile)
        with rasterio.open(outfile) as src:
            aff = get_affine(src)
            data = src.read(1)
            src_crs = CRS().from_string(GeoDict.DEFAULT_PROJ4).to_dict()
            dst_crs = CRS().from_string(projstr).to_dict()
            nrows, ncols = data.shape
            left = aff.xoff
            top = aff.yoff
            right, bottom = aff * (ncols-1, nrows-1)
            dst_transform, width, height = calculate_default_transform(src_crs, dst_crs,
                                                                       ncols, nrows,
                                                                       left, bottom,
                                                                       right, top)
            destination = np.zeros((height, width))
            reproject(data,
                      destination,
                      src_transform=aff,
                      src_crs=src_crs,
                      dst_transform=dst_transform,
                      dst_crs=dst_crs,
                      src_nodata=src.nodata,
                      dst_nodata=np.nan,
                      resampling=Resampling.nearest)
            x = 1
    except:
        pass
    finally:
        shutil.rmtree(tdir)
Ejemplo n.º 48
0
def test_bounds_within():
    host = GeoDict({'xmin': -180,
                    'xmax': 150,
                    'ymin': -90,
                    'ymax': 90,
                    'dx': 30,
                    'dy': 45,
                    'nx': 12,
                    'ny': 5})
    sample = GeoDict({'xmin': -75,
                      'xmax': 45,
                      'ymin': -67.5,
                      'ymax': 67.5,
                      'dx': 30,
                      'dy': 45,
                      'nx': 5,
                      'ny': 4})

    result = GeoDict({'xmin': -60,
                      'xmax': 30,
                      'ymin': -45,
                      'ymax': 45,
                      'dx': 30,
                      'dy': 45,
                      'nx': 4,
                      'ny': 3})

    inside = host.getBoundsWithin(sample)
    assert inside == result

    # test degenerate case where first pass at getting inside bounds fails (xmax)
    host = GeoDict({'ymax': 84.0,
                    'dx': 0.008333333333333333,
                    'ny': 16801,
                    'xmax': 179.99166666666667,
                    'xmin': -180.0,
                    'nx': 43200,
                    'dy': 0.008333333333333333,
                    'ymin': -56.0})

    sample = GeoDict({'ymax': 18.933333333333334,
                      'dx': 0.008333333333333333,
                      'ny': 877,
                      'xmax': -90.28333333333333,
                      'xmin': -97.86666666666666,
                      'nx': 911,
                      'dy': 0.008333333333333333,
                      'ymin': 11.633333333333333})
    inside = host.getBoundsWithin(sample)
    assert sample.contains(inside)

    # this tests some logic that I can't figure out
    # a way to make happen inside getBoundsWithin().
    newymin, ymin = (11.63333333333334, 11.633333333333333)
    fdy = 0.008333333333333333
    yminrow = 8684.0
    fymax = 84.0
    newymin -= fdy/2  # bump it down
    while newymin <= ymin:
        yminrow = yminrow - 1
        newymin = fymax - yminrow*fdy
    assert newymin > ymin
Ejemplo n.º 49
0
def test_output_container():
    geodict = GeoDict.createDictFromBox(-118.5,-114.5,32.1,36.7,0.01,0.02)
    nrows,ncols = geodict.ny,geodict.nx

    #create MMI mean data for maximum component
    mean_mmi_maximum_data = np.random.rand(nrows,ncols)
    mean_mmi_maximum_metadata = {'name':'Gandalf',
                                 'color':'white',
                                 'powers':'magic'}
    mean_mmi_maximum_grid = Grid2D(mean_mmi_maximum_data,geodict)

    #create MMI std data for maximum component
    std_mmi_maximum_data = mean_mmi_maximum_data/10
    std_mmi_maximum_metadata = {'name':'Legolas',
                                'color':'green',
                                'powers':'good hair'}
    std_mmi_maximum_grid = Grid2D(std_mmi_maximum_data,geodict)

    #create MMI mean data for rotd50 component
    mean_mmi_rotd50_data = np.random.rand(nrows,ncols)
    mean_mmi_rotd50_metadata = {'name':'Gimli',
                                 'color':'brown',
                                 'powers':'axing'}
    mean_mmi_rotd50_grid = Grid2D(mean_mmi_rotd50_data,geodict)

    #create MMI std data for rotd50 component
    std_mmi_rotd50_data = mean_mmi_rotd50_data/10
    std_mmi_rotd50_metadata = {'name':'Aragorn',
                                'color':'white',
                                'powers':'scruffiness'}
    std_mmi_rotd50_grid = Grid2D(std_mmi_rotd50_data,geodict)

    #create PGA mean data for maximum component
    mean_pga_maximum_data = np.random.rand(nrows,ncols)
    mean_pga_maximum_metadata = {'name':'Pippin',
                                 'color':'purple',
                                 'powers':'rashness'}
    mean_pga_maximum_grid = Grid2D(mean_pga_maximum_data,geodict)

    #create PGA std data for maximum component
    std_pga_maximum_data = mean_pga_maximum_data/10
    std_pga_maximum_metadata = {'name':'Merry',
                                'color':'grey',
                                'powers':'hunger'}
    std_pga_maximum_grid = Grid2D(std_pga_maximum_data,geodict)

    f,datafile = tempfile.mkstemp()
    os.close(f)
    try:
        container = ShakeMapOutputContainer.create(datafile)
        container.setIMTGrids('mmi',
                         mean_mmi_maximum_grid,mean_mmi_maximum_metadata,
                         std_mmi_maximum_grid,std_mmi_maximum_metadata,
                         component='maximum')
        container.setIMTGrids('mmi',
                         mean_mmi_rotd50_grid,mean_mmi_rotd50_metadata,
                         std_mmi_rotd50_grid,std_mmi_rotd50_metadata,
                         component='rotd50')
        container.setIMTGrids('pga',
                         mean_pga_maximum_grid,mean_pga_maximum_metadata,
                         std_pga_maximum_grid,std_pga_maximum_metadata,
                         component='maximum')

        #get the maximum MMI imt data
        mmi_max_dict = container.getIMTGrids('mmi',component='maximum')
        np.testing.assert_array_equal(mmi_max_dict['mean'].getData(),
                                      mean_mmi_maximum_data)
        np.testing.assert_array_equal(mmi_max_dict['std'].getData(),
                                      std_mmi_maximum_data)
        assert mmi_max_dict['mean_metadata'] == mean_mmi_maximum_metadata
        assert mmi_max_dict['std_metadata'] == std_mmi_maximum_metadata

        #get the rotd50 MMI imt data
        mmi_rot_dict = container.getIMTGrids('mmi',component='rotd50')
        np.testing.assert_array_equal(mmi_rot_dict['mean'].getData(),
                                      mean_mmi_rotd50_data)
        np.testing.assert_array_equal(mmi_rot_dict['std'].getData(),
                                      std_mmi_rotd50_data)
        assert mmi_rot_dict['mean_metadata'] == mean_mmi_rotd50_metadata
        assert mmi_rot_dict['std_metadata'] == std_mmi_rotd50_metadata

        #get list of maximum imts
        max_imts = container.getIMTs(component='maximum')
        assert sorted(max_imts) == ['mmi','pga']

        #get list of components for mmi
        mmi_comps = container.getComponents('mmi')
        assert sorted(mmi_comps) == ['maximum','rotd50']
    except Exception as e:
        raise(e)
    finally:
        os.remove(datafile)
Ejemplo n.º 50
0
            gridtype = 'esri'
        except:
            pass
    if gridtype is None:
        raise Exception('File "%s" does not appear to be either a GMT grid or an ESRI grid.' % gridfile)
    xmin = xmin - fdict.dx*3
    xmax = xmax + fdict.dx*3
    ymin = ymin - fdict.dy*3
    ymax = ymax + fdict.dy*3
    bounds = (xmin,xmax,ymin,ymax)
    if gridtype == 'gmt':
        fgeodict = GMTGrid.getFileGeoDict(gridfile)
    else:
        fgeodict = GDALGrid.getFileGeoDict(gridfile)
    dx,dy = (fgeodict.dx,fgeodict.dy)
    sdict = GeoDict.createDictFromBox(xmin,xmax,ymin,ymax,dx,dy)
    if gridtype == 'gmt':
        grid = GMTGrid.load(gridfile,samplegeodict=sdict,resample=False,method=method,doPadding=True)
    else:
        grid = GDALGrid.load(gridfile,samplegeodict=sdict,resample=False,method=method,doPadding=True)

    return sampleFromGrid(grid,xypoints)

def sampleFromGrid(grid,xypoints,method='nearest'):
    """
    Sample 2D grid object at each of a set of XY (decimal degrees) points.
    :param grid:
      Grid2D object at which to sample data.
    :param xypoints:
      2D numpy array of XY points, decimal degrees.
    :param method:
Ejemplo n.º 51
0
def test_rupture_depth(interactive=False):
    DIP = 17.0
    WIDTH = 20.0
    GRIDRES = 0.1

    names = ['single', 'double', 'triple',
             'concave', 'concave_simple', 'ANrvSA']
    means = [3.1554422780092461, 2.9224454569459781,
             3.0381968625073563, 2.0522694624400271,
             2.4805390352818755, 2.8740121776209673]
    stds = [2.1895293825074575, 2.0506459673526174,
            2.0244588429154402, 2.0112565876976416,
            2.1599789955270019, 1.6156220309120068]
    xp0list = [np.array([118.3]),
               np.array([10.1, 10.1]),
               np.array([10.1, 10.1, 10.3]),
               np.array([10.9, 10.5, 10.9]),
               np.array([10.9, 10.6]),
               np.array([-76.483, -76.626, -76.757, -76.99, -77.024, -76.925,
                         -76.65, -76.321, -75.997, -75.958])]
    xp1list = [np.array([118.3]),
               np.array([10.1, 10.3]),
               np.array([10.1, 10.3, 10.1]),
               np.array([10.5, 10.9, 11.3]),
               np.array([10.6, 10.9]),
               np.array([-76.626, -76.757, -76.99, -77.024, -76.925, -76.65,
                         -76.321, -75.997, -75.958, -76.006])]
    yp0list = [np.array([34.2]),
               np.array([34.2, 34.5]),
               np.array([34.2, 34.5, 34.8]),
               np.array([34.2, 34.5, 34.8]),
               np.array([35.1, 35.2]),
               np.array([-52.068, -51.377, -50.729, -49.845, -49.192, -48.507,
                         -47.875, -47.478, -47.08, -46.422])]
    yp1list = [np.array([34.5]),
               np.array([34.5, 34.8]),
               np.array([34.5, 34.8, 35.1]),
               np.array([34.5, 34.8, 34.6]),
               np.array([35.2, 35.4]),
               np.array([-51.377, -50.729, -49.845, -49.192, -48.507, -47.875,
                         -47.478, -47.08, -46.422, -45.659])]

    for i in range(0, len(xp0list)):
        xp0 = xp0list[i]
        xp1 = xp1list[i]
        yp0 = yp0list[i]
        yp1 = yp1list[i]
        name = names[i]
        mean_value = means[i]
        std_value = stds[i]

        zp = np.zeros(xp0.shape)
        strike = azimuth(xp0[0], yp0[0], xp1[-1], yp1[-1])
        widths = np.ones(xp0.shape) * WIDTH
        dips = np.ones(xp0.shape) * DIP
        strike = [strike]
        origin = Origin({'eventsourcecode': 'test', 'lat': 0, 'lon': 0,
                         'depth': 5.0, 'mag': 7.0})
        rupture = QuadRupture.fromTrace(
            xp0, yp0, xp1, yp1, zp, widths, dips, origin, strike=strike)

        # make a grid of points over both quads, ask for depths
        ymin = np.nanmin(rupture.lats)
        ymax = np.nanmax(rupture.lats)
        xmin = np.nanmin(rupture.lons)
        xmax = np.nanmax(rupture.lons)

        xmin = np.floor(xmin * (1 / GRIDRES)) / (1 / GRIDRES)
        xmax = np.ceil(xmax * (1 / GRIDRES)) / (1 / GRIDRES)
        ymin = np.floor(ymin * (1 / GRIDRES)) / (1 / GRIDRES)
        ymax = np.ceil(ymax * (1 / GRIDRES)) / (1 / GRIDRES)
        geodict = GeoDict.createDictFromBox(
            xmin, xmax, ymin, ymax, GRIDRES, GRIDRES)
        nx = geodict.nx
        ny = geodict.ny
        depths = np.zeros((ny, nx))
        for row in range(0, ny):
            for col in range(0, nx):
                lat, lon = geodict.getLatLon(row, col)
                depth = rupture.getDepthAtPoint(lat, lon)
                depths[row, col] = depth

        np.testing.assert_almost_equal(np.nanmean(depths), mean_value)
        np.testing.assert_almost_equal(np.nanstd(depths), std_value)

        if interactive:
            fig, axes = plt.subplots(nrows=2, ncols=1)
            ax1, ax2 = axes
            xdata = np.append(xp0, xp1[-1])
            ydata = np.append(yp0, yp1[-1])
            plt.sca(ax1)
            plt.plot(xdata, ydata, 'b')
            plt.sca(ax2)
            im = plt.imshow(depths, cmap='viridis_r')  # noqa
            ch = plt.colorbar()  # noqa
            fname = os.path.join(os.path.expanduser('~'),
                                 'quad_%s_test.png' % name)
            print('Saving image for %s quad test... %s' % (name, fname))
            plt.savefig(fname)
            plt.close()
Ejemplo n.º 52
0
def modelMap(grids, shakefile=None, suptitle=None, inventory_shapefile=None,
             plotorder=None, maskthreshes=None, colormaps=None, boundaries=None,
             zthresh=0, scaletype='continuous', lims=None, logscale=False,
             ALPHA=0.7, maproads=True, mapcities=True, isScenario=False,
             roadfolder=None, topofile=None, cityfile=None, oceanfile=None,
             roadcolor='#6E6E6E', watercolor='#B8EEFF', countrycolor='#177F10',
             outputdir=None, savepdf=True, savepng=True, showplots=False,
             roadref='unknown', cityref='unknown', oceanref='unknown',
             printparam=False, ds=True, dstype='mean', upsample=False):
    """
    This function creates maps of mapio grid layers (e.g. liquefaction or
    landslide models with their input layers)
    All grids must use the same bounds
    TO DO change so that all input layers do not have to have the same bounds,
    test plotting multiple probability layers, and add option so that if PDF and
    PNG aren't output, opens plot on screen using plt.show()

    :param grids: Dictionary of N layers and metadata formatted like:
        maplayers['layer name']={
        'grid': mapio grid2D object,
        'label': 'label for colorbar and top line of subtitle',
        'type': 'output or input to model',
        'description': 'detailed description of layer for subtitle'}.
      Layer names must be unique.
    :type name: Dictionary or Ordered dictionary - import collections;
      grids = collections.OrderedDict()
    :param shakefile: optional ShakeMap file (url or full file path) to extract information for labels and folder names
    :type shakefile: Shakemap Event Dictionary
    :param suptitle: This will be displayed at the top of the plots and in the
      figure names
    :type suptitle: string
    :param plotorder: List of keys describing the order to plot the grids, if
      None and grids is an ordered dictionary, it will use the order of the
      dictionary, otherwise it will choose order which may be somewhat random
      but it will always put a probability grid first
    :type plotorder: list
    :param maskthreshes: N x 1 array or list of lower thresholds for masking
      corresponding to order in plotorder or order of OrderedDict if plotorder
      is None. If grids is not an ordered dict and plotorder is not specified,
      this will not work right. If None (default), nothing will be masked
    :param colormaps: List of strings of matplotlib colormaps (e.g. cm.autumn_r)
      corresponding to plotorder or order of dictionary if plotorder is None.
      The list can contain both strings and None e.g. colormaps = ['cm.autumn',
      None, None, 'cm.jet'] and None's will default to default colormap
    :param boundaries: None to show entire study area, 'zoom' to zoom in on the
      area of action (only works if there is a probability layer) using zthresh
      as a threshold, or a dictionary defining lats and lons in the form of
      boundaries.xmin = minlon, boundaries.xmax = maxlon, boundaries.ymin =
      min lat, boundaries.ymax = max lat
    :param zthresh: threshold for computing zooming bounds, only used if
      boundaries = 'zoom'
    :type zthresh: float
    :param scaletype: Type of scale for plotting, 'continuous' or 'binned' -
      will be reflected in colorbar
    :type scaletype: string
    :param lims: None or Nx1 list of tuples or numpy arrays corresponding to
      plotorder defining the limits for saturating the colorbar (vmin, vmax) if
      scaletype is continuous or the bins to use (clev) if scaletype if binned.
      The list can contain tuples, arrays, and Nones, e.g. lims = [(0., 10.),
      None, (0.1, 1.5), np.linspace(0., 1.5, 15)]. When None is specified, the
      program will estimate the limits, when an array is specified but the scale
      type is continuous, vmin will be set to min(array) and vmax will be set
      to max(array)
    :param lims: None or Nx1 list of Trues and Falses corresponding to
      plotorder defining whether to use a linear or log scale (log10) for
      plotting the layer. This will be reflected in the labels
    :param ALPHA: Transparency for mapping, if there is a hillshade that will
      plot below each layer, it is recommended to set this to at least 0.7
    :type ALPHA: float
    :param maproads: Whether to show roads or not, default True, but requires
      that roadfile is specified and valid to work
    :type maproads: boolean
    :param mapcities: Whether to show cities or not, default True, but requires
      that cityfile is specified and valid to work
    :type mapcities: boolean
    :param isScenario: Whether this is a scenario (True) or a real event (False)
      (default False)
    :type isScenario: boolean
    :param roadfolder: Full file path to folder containing road shapefiles
    :type roadfolder: string
    :param topofile: Full file path to topography grid (GDAL compatible) - this
      is only needed to make a hillshade if a premade hillshade is not specified
    :type topofile: string
    :param cityfile: Full file path to Pager file containing city & population
      information
    :type cityfile: string
    :param roadcolor: Color to use for roads, if plotted, default #6E6E6E
    :type roadcolor: Hex color or other matplotlib compatible way of defining
      color
    :param watercolor: Color to use for oceans, lakes, and rivers, default
      #B8EEFF
    :type watercolor: Hex color or other matplotlib compatible way of defining
      color
    :param countrycolor: Color for country borders, default #177F10
    :type countrycolor: Hex color or other matplotlib compatible way of defining
      color
    :param outputdir: File path for outputting figures, if edict is defined, a
      subfolder based on the event id will be created in this folder. If None,
      will use current directory
    :param savepdf: True to save pdf figure, False to not
    :param savepng: True to save png figure, False to not
    :param ds: True to allow downsampling for display (necessary when arrays
      are quite large, False to not allow)
    :param dstype: What function to use in downsampling, options are 'min',
      'max', 'median', or 'mean'
    :param upsample: True to upsample the layer to the DEM resolution for better
      looking hillshades

    :returns:
        * PDF and/or PNG of map
        * Downsampled and trimmed version of input grids. If no
        modification was needed for plotting, this will be identical to grids but
        without the metadata

    """

    if suptitle is None:
        suptitle = ' '

    plt.ioff()

    defaultcolormap = cm.jet

    if shakefile is not None:
        edict = ShakeGrid.load(shakefile, adjust='res').getEventDict()
        temp = ShakeGrid.load(shakefile, adjust='res').getShakeDict()
        edict['eventid'] = temp['shakemap_id']
        edict['version'] = temp['shakemap_version']
    else:
        edict = None

    # Get output file location
    if outputdir is None:
        print('No output location given, using current directory for outputs\n')
        outputdir = os.getcwd()
    if edict is not None:
        outfolder = os.path.join(outputdir, edict['event_id'])
    else:
        outfolder = outputdir
    if not os.path.isdir(outfolder):
        os.makedirs(outfolder)

    # Get plotting order, if not specified
    if plotorder is None:
        plotorder = list(grids.keys())

    # Get boundaries to use for all plots
    cut = True
    if boundaries is None:
        cut = False
        keytemp = list(grids.keys())
        boundaries = grids[keytemp[0]]['grid'].getGeoDict()
    elif boundaries == 'zoom':
        # Find probability layer (will just take the maximum bounds if there is
        # more than one)
        keytemp = list(grids.keys())
        key1 = [key for key in keytemp if 'model' in key.lower()]
        if len(key1) == 0:
            print('Could not find model layer to use for zoom, using default boundaries')
            keytemp = list(grids.keys())
            boundaries = grids[keytemp[0]]['grid'].getGeoDict()
        else:
            lonmax = -1.e10
            lonmin = 1.e10
            latmax = -1.e10
            latmin = 1.e10
            for key in key1:
                # get lat lons of areas affected and add, if no areas affected,
                # switch to shakemap boundaries
                temp = grids[key]['grid']
                xmin, xmax, ymin, ymax = temp.getBounds()
                lons = np.linspace(xmin, xmax, temp.getGeoDict().nx)
                lats = np.linspace(ymax, ymin, temp.getGeoDict().ny)  # backwards so it plots right
                row, col = np.where(temp.getData() > float(zthresh))
                lonmin = lons[col].min()
                lonmax = lons[col].max()
                latmin = lats[row].min()
                latmax = lats[row].max()
                # llons, llats = np.meshgrid(lons, lats)  # make meshgrid
                # llons1 = llons[temp.getData() > float(zthresh)]
                # llats1 = llats[temp.getData() > float(zthresh)]
                # if llons1.min() < lonmin:
                #     lonmin = llons1.min()
                # if llons1.max() > lonmax:
                #     lonmax = llons1.max()
                # if llats1.min() < latmin:
                #     latmin = llats1.min()
                # if llats1.max() > latmax:
                #     latmax = llats1.max()
            boundaries1 = {'dx': 100, 'dy': 100., 'nx': 100., 'ny': 100}  # dummy fillers, only really care about bounds
            if xmin < lonmin-0.15*(lonmax-lonmin):
                boundaries1['xmin'] = lonmin-0.1*(lonmax-lonmin)
            else:
                boundaries1['xmin'] = xmin
            if xmax > lonmax+0.15*(lonmax-lonmin):
                boundaries1['xmax'] = lonmax+0.1*(lonmax-lonmin)
            else:
                boundaries1['xmax'] = xmax
            if ymin < latmin-0.15*(latmax-latmin):
                boundaries1['ymin'] = latmin-0.1*(latmax-latmin)
            else:
                boundaries1['ymin'] = ymin
            if ymax > latmax+0.15*(latmax-latmin):
                boundaries1['ymax'] = latmax+0.1*(latmax-latmin)
            else:
                boundaries1['ymax'] = ymax
            boundaries = GeoDict(boundaries1, adjust='res')
    else:
        # SEE IF BOUNDARIES ARE SAME AS BOUNDARIES OF LAYERS
        keytemp = list(grids.keys())
        tempgdict = grids[keytemp[0]]['grid'].getGeoDict()
        if np.abs(tempgdict.xmin-boundaries['xmin']) < 0.05 and \
           np.abs(tempgdict.ymin-boundaries['ymin']) < 0.05 and \
           np.abs(tempgdict.xmax-boundaries['xmax']) < 0.05 and \
           np.abs(tempgdict.ymax - boundaries['ymax']) < 0.05:
            print('Input boundaries are almost the same as specified boundaries, no cutting needed')
            boundaries = tempgdict
            cut = False
        else:
            try:
                if boundaries['xmin'] > boundaries['xmax'] or \
                   boundaries['ymin'] > boundaries['ymax']:
                    print('Input boundaries are not usable, using default boundaries')
                    keytemp = list(grids.keys())
                    boundaries = grids[keytemp[0]]['grid'].getGeoDict()
                    cut = False
                else:
                    # Build dummy GeoDict
                    boundaries = GeoDict({'xmin': boundaries['xmin'],
                                          'xmax': boundaries['xmax'],
                                          'ymin': boundaries['ymin'],
                                          'ymax': boundaries['ymax'],
                                          'dx': 100.,
                                          'dy': 100.,
                                          'ny': 100.,
                                          'nx': 100.},
                                         adjust='res')
            except:
                print('Input boundaries are not usable, using default boundaries')
                keytemp = list(grids.keys())
                boundaries = grids[keytemp[0]]['grid'].getGeoDict()
                cut = False

    # Pull out bounds for various uses
    bxmin, bxmax, bymin, bymax = boundaries.xmin, boundaries.xmax, boundaries.ymin, boundaries.ymax

    # Determine if need a single panel or multi-panel plot and if multi-panel,
    # how many and how it will be arranged
    fig = plt.figure()
    numpanels = len(grids)
    if numpanels == 1:
        rowpan = 1
        colpan = 1
        # create the figure and axes instances.
        fig.set_figwidth(5)
    elif numpanels == 2 or numpanels == 4:
        rowpan = np.ceil(numpanels/2.)
        colpan = 2
        fig.set_figwidth(13)
    else:
        rowpan = np.ceil(numpanels/3.)
        colpan = 3
        fig.set_figwidth(15)
    if rowpan == 1:
        fig.set_figheight(rowpan*6.0)
    else:
        fig.set_figheight(rowpan*5.3)

    # Need to update naming to reflect the shakemap version once can get
    # getHeaderData to work, add edict['version'] back into title, maybe
    # shakemap id also?
    fontsizemain = 14.
    fontsizesub = 12.
    fontsizesmallest = 10.
    if rowpan == 1.:
        fontsizemain = 12.
        fontsizesub = 10.
        fontsizesmallest = 8.
    if edict is not None:
        if isScenario:
            title = edict['event_description']
        else:
            timestr = edict['event_timestamp'].strftime('%b %d %Y')
            title = 'M%.1f %s v%i - %s' % (edict['magnitude'], timestr, edict['version'], edict['event_description'])
        plt.suptitle(title+'\n'+suptitle, fontsize=fontsizemain)
    else:
        plt.suptitle(suptitle, fontsize=fontsizemain)

    clear_color = [0, 0, 0, 0.0]

    # Cut all of them and release extra memory

    xbuff = (bxmax-bxmin)/10.
    ybuff = (bymax-bymin)/10.
    cutxmin = bxmin-xbuff
    cutymin = bymin-ybuff
    cutxmax = bxmax+xbuff
    cutymax = bymax+ybuff
    if cut is True:
        newgrids = collections.OrderedDict()
        for k, layer in enumerate(plotorder):
            templayer = grids[layer]['grid']
            try:
                newgrids[layer] = {'grid': templayer.cut(cutxmin, cutxmax, cutymin, cutymax, align=True)}
            except Exception as e:
                print(('Cutting failed, %s, continuing with full layers' % e))
                newgrids = grids
                continue
        del templayer
        gc.collect()
    else:
        newgrids = grids
    tempgdict = newgrids[list(grids.keys())[0]]['grid'].getGeoDict()

    # Upsample layers to same as topofile if desired for better looking hillshades
    if upsample is True and topofile is not None:
        try:
            topodict = GDALGrid.getFileGeoDict(topofile)
            if topodict.dx >= tempgdict.dx or topodict.dy >= tempgdict.dy:
                print('Upsampling not possible, resolution of results already smaller than DEM')
                pass
            else:
                tempgdict1 = GeoDict({'xmin': tempgdict.xmin-xbuff,
                                      'ymin': tempgdict.ymin-ybuff,
                                      'xmax': tempgdict.xmax+xbuff,
                                      'ymax': tempgdict.ymax+ybuff,
                                      'dx': topodict.dx,
                                      'dy': topodict.dy,
                                      'nx': topodict.nx,
                                      'ny': topodict.ny},
                                     adjust='res')
                tempgdict2 = tempgdict1.getBoundsWithin(tempgdict)
                for k, layer in enumerate(plotorder):
                    newgrids[layer]['grid'] = newgrids[layer]['grid'].subdivide(tempgdict2)
        except:
            print('Upsampling failed, continuing')

    # Downsample all of them for plotting, if needed, and replace them in
    # grids (to save memory)
    tempgrid = newgrids[list(grids.keys())[0]]['grid']
    xsize = tempgrid.getGeoDict().nx
    ysize = tempgrid.getGeoDict().ny
    inchesx, inchesy = fig.get_size_inches()
    divx = int(np.round(xsize/(500.*inchesx)))
    divy = int(np.round(ysize/(500.*inchesy)))
    xmin, xmax, ymin, ymax = tempgrid.getBounds()
    gdict = tempgrid.getGeoDict()  # Will be replaced if downsampled
    del tempgrid
    gc.collect()

    if divx <= 1:
        divx = 1
    if divy <= 1:
        divy = 1
    if (divx > 1. or divy > 1.) and ds:
        if dstype == 'max':
            func = np.nanmax
        elif dstype == 'min':
            func = np.nanmin
        elif dstype == 'med':
            func = np.nanmedian
        else:
            func = np.nanmean
        for k, layer in enumerate(plotorder):
            layergrid = newgrids[layer]['grid']
            dat = block_reduce(layergrid.getData().copy(),
                               block_size=(divy, divx),
                               cval=float('nan'),
                               func=func)
            if k == 0:
                lons = block_reduce(np.linspace(xmin, xmax, layergrid.getGeoDict().nx),
                                    block_size=(divx,),
                                    func=np.mean,
                                    cval=float('nan'))
                if math.isnan(lons[-1]):
                    lons[-1] = lons[-2] + (lons[1]-lons[0])
                lats = block_reduce(np.linspace(ymax, ymin, layergrid.getGeoDict().ny),
                                    block_size=(divy,),
                                    func=np.mean,
                                    cval=float('nan'))
                if math.isnan(lats[-1]):
                    lats[-1] = lats[-2] + (lats[1]-lats[0])
                gdict = GeoDict({'xmin': lons.min(),
                                 'xmax': lons.max(),
                                 'ymin': lats.min(),
                                 'ymax': lats.max(),
                                 'dx': np.abs(lons[1]-lons[0]),
                                 'dy': np.abs(lats[1]-lats[0]),
                                 'nx': len(lons),
                                 'ny': len(lats)},
                                adjust='res')
            newgrids[layer]['grid'] = Grid2D(dat, gdict)
        del layergrid, dat
    else:
        lons = np.linspace(xmin, xmax, xsize)
        lats = np.linspace(ymax, ymin, ysize)  # backwards so it plots right side up

    #make meshgrid
    llons1, llats1 = np.meshgrid(lons, lats)

    # See if there is an oceanfile for masking
    bbox = PolygonSH(((cutxmin, cutymin), (cutxmin, cutymax), (cutxmax, cutymax), (cutxmax, cutymin)))
    if oceanfile is not None:
        try:
            f = fiona.open(oceanfile)
            oc = next(f)
            f.close
            shapes = shape(oc['geometry'])
            # make boundaries into a shape
            ocean = shapes.intersection(bbox)
        except:
            print('Not able to read specified ocean file, will use default ocean masking')
            oceanfile = None
    if inventory_shapefile is not None:
        try:
            f = fiona.open(inventory_shapefile)
            invshp = list(f.items(bbox=(bxmin, bymin, bxmax, bymax)))
            f.close()
            inventory = [shape(inv[1]['geometry']) for inv in invshp]
        except:
            print('unable to read inventory shapefile specified, will not plot inventory')
            inventory_shapefile = None

    # # Find cities that will be plotted
    if mapcities is True and cityfile is not None:
        try:
            mycity = BasemapCities.loadFromGeoNames(cityfile=cityfile)
            bcities = mycity.limitByBounds((bxmin, bxmax, bymin, bymax))
            #bcities = bcities.limitByPopulation(40000)
            bcities = bcities.limitByGrid(nx=4, ny=4, cities_per_grid=2)
        except:
            print('Could not read in cityfile, not plotting cities')
            mapcities = False
            cityfile = None

    # Load in topofile
    if topofile is not None:
        try:
            topomap = GDALGrid.load(topofile, resample=True, method='linear', samplegeodict=gdict)
        except:
            topomap = GMTGrid.load(topofile, resample=True, method='linear', samplegeodict=gdict)
        topodata = topomap.getData().copy()
        # mask oceans if don't have ocean shapefile
        if oceanfile is None:
            topodata = maskoceans(llons1, llats1, topodata, resolution='h', grid=1.25, inlands=True)
    else:
        print('no hillshade is possible\n')
        topomap = None
        topodata = None

    # Load in roads, if needed
    if maproads is True and roadfolder is not None:
        try:
            roadslist = []
            for folder in os.listdir(roadfolder):
                road1 = os.path.join(roadfolder, folder)
                shpfiles = glob.glob(os.path.join(road1, '*.shp'))
                if len(shpfiles):
                    shpfile = shpfiles[0]
                    f = fiona.open(shpfile)
                    shapes = list(f.items(bbox=(bxmin, bymin, bxmax, bymax)))
                    for shapeid, shapedict in shapes:
                        roadslist.append(shapedict)
                    f.close()
        except:
            print('Not able to plot roads')
            roadslist = None

    val = 1
    for k, layer in enumerate(plotorder):
        layergrid = newgrids[layer]['grid']
        if 'label' in list(grids[layer].keys()):
            label1 = grids[layer]['label']
        else:
            label1 = layer
        try:
            sref = grids[layer]['description']['name']
        except:
            sref = None
        ax = fig.add_subplot(rowpan, colpan, val)
        val += 1
        clat = bymin + (bymax-bymin)/2.0
        clon = bxmin + (bxmax-bxmin)/2.0
        # setup of basemap ('lcc' = lambert conformal conic).
        # use major and minor sphere radii from WGS84 ellipsoid.
        m = Basemap(llcrnrlon=bxmin, llcrnrlat=bymin, urcrnrlon=bxmax, urcrnrlat=bymax,
                    rsphere=(6378137.00, 6356752.3142),
                    resolution='l', area_thresh=1000., projection='lcc',
                    lat_1=clat, lon_0=clon, ax=ax)

        x1, y1 = m(llons1, llats1)  # get projection coordinates
        axsize = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
        if k == 0:
            wid, ht = axsize.width, axsize.height
        if colormaps is not None and \
           len(colormaps) == len(newgrids) and \
           colormaps[k] is not None:
            palette = colormaps[k]
        else:  # Find preferred default color map for each type of layer
            if 'prob' in layer.lower() or 'pga' in layer.lower() or \
               'pgv' in layer.lower() or 'cohesion' in layer.lower() or \
               'friction' in layer.lower() or 'fs' in layer.lower():
                palette = cm.jet
            elif 'slope' in layer.lower():
                palette = cm.gnuplot2
            elif 'precip' in layer.lower():
                palette = cm2.s3pcpn
            else:
                palette = defaultcolormap

        if topodata is not None:
            if k == 0:
                ptopo = m.transform_scalar(
                    np.flipud(topodata), lons+0.5*gdict.dx,
                    lats[::-1]-0.5*gdict.dy, np.round(300.*wid),
                    np.round(300.*ht), returnxy=False, checkbounds=False,
                    order=1, masked=False)
                #use lightsource class to make our shaded topography
                ls = LightSource(azdeg=135, altdeg=45)
                ls1 = LightSource(azdeg=120, altdeg=45)
                ls2 = LightSource(azdeg=225, altdeg=45)
                intensity1 = ls1.hillshade(ptopo, fraction=0.25, vert_exag=1.)
                intensity2 = ls2.hillshade(ptopo, fraction=0.25, vert_exag=1.)
                intensity = intensity1*0.5 + intensity2*0.5
                #hillshm_im = m.transform_scalar(np.flipud(hillshm), lons, lats[::-1], np.round(300.*wid), np.round(300.*ht), returnxy=False, checkbounds=False, order=0, masked=False)
            #m.imshow(hillshm_im, cmap='Greys', vmin=0., vmax=3., zorder=1, interpolation='none')  # vmax = 3 to soften colors to light gray
            #m.pcolormesh(x1, y1, hillshm, cmap='Greys', linewidth=0., rasterized=True, vmin=0., vmax=3., edgecolors='none', zorder=1);
            # plt.draw()

        # Get the data
        dat = layergrid.getData().copy()

        # mask out anything below any specified thresholds
        # Might need to move this up to before downsampling...might give illusion of no hazard in places where there is some that just got averaged out
        if maskthreshes is not None and len(maskthreshes) == len(newgrids):
            if maskthreshes[k] is not None:
                dat[dat <= maskthreshes[k]] = float('NaN')
                dat = np.ma.array(dat, mask=np.isnan(dat))

        if logscale is not False and len(logscale) == len(newgrids):
            if logscale[k] is True:
                dat = np.log10(dat)
                label1 = r'$log_{10}$(' + label1 + ')'

        if scaletype.lower() == 'binned':
            # Find order of range to know how to scale
            order = np.round(np.log(np.nanmax(dat) - np.nanmin(dat)))
            if order < 1.:
                scal = 10**-order
            else:
                scal = 1.
            if lims is None or len(lims) != len(newgrids):
                clev = (np.linspace(np.floor(scal*np.nanmin(dat)), np.ceil(scal*np.nanmax(dat)), 10))/scal
            else:
                if lims[k] is None:
                    clev = (np.linspace(np.floor(scal*np.nanmin(dat)), np.ceil(scal*np.nanmax(dat)), 10))/scal
                else:
                    clev = lims[k]
            # Adjust to colorbar levels
            dat[dat < clev[0]] = clev[0]
            for j, level in enumerate(clev[:-1]):
                dat[(dat >= clev[j]) & (dat < clev[j+1])] = clev[j]
            # So colorbar saturates at top
            dat[dat > clev[-1]] = clev[-1]
            #panelhandle = m.contourf(x1, y1, datm, clev, cmap=palette, linewidth=0., alpha=ALPHA, rasterized=True)
            vmin = clev[0]
            vmax = clev[-1]
        else:
            if lims is not None and len(lims) == len(newgrids):
                if lims[k] is None:
                    vmin = np.nanmin(dat)
                    vmax = np.nanmax(dat)
                else:
                    vmin = lims[k][0]
                    vmax = lims[k][-1]
            else:
                vmin = np.nanmin(dat)
                vmax = np.nanmax(dat)

        # Mask out cells overlying oceans or block with a shapefile if available
        if oceanfile is None:
            dat = maskoceans(llons1, llats1, dat, resolution='h', grid=1.25, inlands=True)
        else:
            #patches = []
            if type(ocean) is PolygonSH:
                ocean = [ocean]
            for oc in ocean:
                patch = getProjectedPatch(oc, m, edgecolor="#006280", facecolor=watercolor, lw=0.5, zorder=4.)
                #x, y = m(oc.exterior.xy[0], oc.exterior.xy[1])
                #xy = zip(x, y)
                #patch = Polygon(xy, facecolor=watercolor, edgecolor="#006280", lw=0.5, zorder=4.)
                ##patches.append(Polygon(xy, facecolor=watercolor, edgecolor=watercolor, zorder=500.))
                ax.add_patch(patch)
            ##ax.add_collection(PatchCollection(patches))

        if inventory_shapefile is not None:
            for in1 in inventory:
                if 'point' in str(type(in1)):
                    x, y = in1.xy
                    x = x[0]
                    y = y[0]
                    m.scatter(x, y, c='m', s=50, latlon=True, marker='^',
                              zorder=100001)
                else:
                    x, y = m(in1.exterior.xy[0], in1.exterior.xy[1])
                    xy = list(zip(x, y))
                    patch = Polygon(xy, facecolor='none', edgecolor='k', lw=0.5, zorder=10.)
                    #patches.append(Polygon(xy, facecolor=watercolor, edgecolor=watercolor, zorder=500.))
                    ax.add_patch(patch)
        palette.set_bad(clear_color, alpha=0.0)
        # Plot it up
        dat_im = m.transform_scalar(
            np.flipud(dat), lons+0.5*gdict.dx, lats[::-1]-0.5*gdict.dy,
            np.round(300.*wid), np.round(300.*ht), returnxy=False,
            checkbounds=False, order=0, masked=True)
        if topodata is not None:  # Drape over hillshade
            #turn data into an RGBA image
            cmap = palette
            #adjust data so scaled between vmin and vmax and between 0 and 1
            dat1 = dat_im.copy()
            dat1[dat1 < vmin] = vmin
            dat1[dat1 > vmax] = vmax
            dat1 = (dat1 - vmin)/(vmax-vmin)
            rgba_img = cmap(dat1)
            maskvals = np.dstack((dat1.mask, dat1.mask, dat1.mask))
            rgb = np.squeeze(rgba_img[:, :, 0:3])
            rgb[maskvals] = 1.
            draped_hsv = ls.blend_hsv(rgb, np.expand_dims(intensity, 2))
            m.imshow(draped_hsv, zorder=3., interpolation='none')
            # This is just a dummy layer that will be deleted to make the
            # colorbar look right
            panelhandle = m.imshow(dat_im, cmap=palette, zorder=0.,
                                   vmin=vmin, vmax=vmax)
        else:
            panelhandle = m.imshow(dat_im, cmap=palette, zorder=3.,
                                   vmin=vmin, vmax=vmax, interpolation='none')
        #panelhandle = m.pcolormesh(x1, y1, dat, linewidth=0., cmap=palette, vmin=vmin, vmax=vmax, alpha=ALPHA, rasterized=True, zorder=2.);
        #panelhandle.set_edgecolors('face')
        # add colorbar
        cbfmt = '%1.1f'
        if vmax is not None and vmin is not None:
            if (vmax - vmin) < 1.:
                cbfmt = '%1.2f'
            elif vmax > 5.:  # (vmax - vmin) > len(clev):
                cbfmt = '%1.0f'

        #norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
        if scaletype.lower() == 'binned':
            cbar = fig.colorbar(panelhandle, spacing='proportional',
                                ticks=clev, boundaries=clev, fraction=0.036,
                                pad=0.04, format=cbfmt, extend='both')
            #cbar1 = ColorbarBase(cbar.ax, cmap=palette, norm=norm, spacing='proportional', ticks=clev, boundaries=clev, fraction=0.036, pad=0.04, format=cbfmt, extend='both', extendfrac='auto')

        else:
            cbar = fig.colorbar(panelhandle, fraction=0.036, pad=0.04,
                                extend='both', format=cbfmt)
            #cbar1 = ColorbarBase(cbar.ax, cmap=palette, norm=norm, fraction=0.036, pad=0.04, extend='both', extendfrac='auto', format=cbfmt)

        if topodata is not None:
            panelhandle.remove()

        cbar.set_label(label1, fontsize=10)
        cbar.ax.tick_params(labelsize=8)

        parallels = m.drawparallels(getMapLines(bymin, bymax, 3),
                                    labels=[1, 0, 0, 0], linewidth=0.5,
                                    labelstyle='+/-', fontsize=9, xoffset=-0.8,
                                    color='gray', zorder=100.)
        m.drawmeridians(getMapLines(bxmin, bxmax, 3), labels=[0, 0, 0, 1],
                        linewidth=0.5, labelstyle='+/-', fontsize=9,
                        color='gray', zorder=100.)
        for par in parallels:
            try:
                parallels[par][1][0].set_rotation(90)
            except:
                pass

        #draw roads on the map, if they were provided to us
        if maproads is True and roadslist is not None:
            try:
                for road in roadslist:
                    try:
                        xy = list(road['geometry']['coordinates'])
                        roadx, roady = list(zip(*xy))
                        mapx, mapy = m(roadx, roady)
                        m.plot(mapx, mapy, roadcolor, lw=0.5, zorder=9)
                    except:
                        continue
            except Exception as e:
                print(('Failed to plot roads, %s' % e))

        #add city names to map
        if mapcities is True and cityfile is not None:
            try:
                fontname = 'Arial'
                fontsize = 8
                if k == 0:  # Only need to choose cities first time and then apply to rest
                    fcities = bcities.limitByMapCollision(
                        m, fontname=fontname, fontsize=fontsize)
                    ctlats, ctlons, names = fcities.getCities()
                    cxis, cyis = m(ctlons, ctlats)
                for ctlat, ctlon, cxi, cyi, name in zip(ctlats, ctlons, cxis, cyis, names):
                    m.scatter(ctlon, ctlat, c='k', latlon=True, marker='.',
                              zorder=100000)
                    ax.text(cxi, cyi, name, fontname=fontname,
                            fontsize=fontsize, zorder=100000)
            except Exception as e:
                print('Failed to plot cities, %s' % e)

        #draw star at epicenter
        plt.sca(ax)
        if edict is not None:
            elat, elon = edict['lat'], edict['lon']
            ex, ey = m(elon, elat)
            plt.plot(ex, ey, '*', markeredgecolor='k', mfc='None', mew=1.0,
                     ms=15, zorder=10000.)

        m.drawmapboundary(fill_color=watercolor)

        m.fillcontinents(color=clear_color, lake_color=watercolor)
        m.drawrivers(color=watercolor)
        ##m.drawcoastlines()

        #draw country boundaries
        m.drawcountries(color=countrycolor, linewidth=1.0)

        #add map scale
        m.drawmapscale((bxmax+bxmin)/2., (bymin+(bymax-bymin)/9.), clon, clat, np.round((((bxmax-bxmin)*111)/5)/10.)*10, barstyle='fancy', zorder=10)

        # Add border
        autoAxis = ax.axis()
        rec = Rectangle((autoAxis[0]-0.7, autoAxis[2]-0.2), (autoAxis[1]-autoAxis[0])+1, (autoAxis[3]-autoAxis[2])+0.4, fill=False, lw=1, zorder=1e8)
        rec = ax.add_patch(rec)
        rec.set_clip_on(False)

        plt.draw()

        if sref is not None:
            label2 = '%s\nsource: %s' % (label1, sref)  # '%s\n' % label1 + r'{\fontsize{10pt}{3em}\selectfont{}%s}' % sref  #
        else:
            label2 = label1
        plt.title(label2, axes=ax, fontsize=fontsizesub)

        #draw scenario watermark, if scenario
        if isScenario:
            plt.sca(ax)
            cx, cy = m(clon, clat)
            plt.text(cx, cy, 'SCENARIO', rotation=45, alpha=0.10, size=72, ha='center', va='center', color='red')

        #if ds: # Could add this to print "downsampled" on map
        #    plt.text()

        if k == 1 and rowpan == 1:
            # adjust single level plot
            axsize = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
            ht2 = axsize.height
            fig.set_figheight(ht2*1.6)
        else:
            plt.tight_layout()

        # Make room for suptitle - tight layout doesn't account for it
        plt.subplots_adjust(top=0.92)

    if printparam is True:
        try:
            fig = plt.gcf()
            dictionary = grids['model']['description']['parameters']
            paramstring = 'Model parameters: '
            halfway = np.ceil(len(dictionary)/2.)
            for i, key in enumerate(dictionary):
                if i == halfway and colpan == 1:
                    paramstring += '\n'
                paramstring += ('%s = %s; ' % (key, dictionary[key]))
            print(paramstring)
            fig.text(0.01, 0.015, paramstring, fontsize=fontsizesmallest)
            plt.draw()
        except:
            print('Could not display model parameters')

    if edict is not None:
        eventid = edict['eventid']
    else:
        eventid = ''

    time1 = datetime.datetime.utcnow().strftime('%d%b%Y_%H%M')
    outfile = os.path.join(outfolder, '%s_%s_%s.pdf' % (eventid, suptitle, time1))
    pngfile = os.path.join(outfolder, '%s_%s_%s.png' % (eventid, suptitle, time1))

    if savepdf is True:
        print('Saving map output to %s' % outfile)
        plt.savefig(outfile, dpi=300)
    if savepng is True:
        print('Saving map output to %s' % pngfile)
        plt.savefig(pngfile)
    if showplots is True:
        plt.show()
    else:
        plt.close(fig)

    return newgrids
Ejemplo n.º 53
0
def getYesPoints(pshapes,proj,dx,nmax,touch_center=True):
    """
    Collect x/y coordinates of all points within hazard coverage polygons at desired resolution.
    :param pshapes:
      Sequence of orthographically projected shapes.
    :param proj:
      PyProj projection object used to transform input shapes
    :param dx:
      Float resolution of grid at which to sample points, must be round number
    :param nmax:
      Threshold maximum number of points in total data mesh.
    :param touch_center:
      Boolean indicating whether presence of polygon in each grid cell is enough to turn that
      into a yes pixel.  Setting this to false presumes that the dx is relatively large, such
      that creating a grid at that resolution will not tax the resources of the system.
    :returns:
      - numpy 2-D array of X/Y coordinates inside hazard polygons.
      - number of rows of resulting mesh
      - number of columns of resulting mesh
      - numpy array of x coordinate centers of columns
      - numpy array of y coordinate centers of rows
      - 1D array of indices where yes pixels are located (use np.unravel_index to unpack to 2D array)
    """
    mxmin = 9e10
    mxmax = -9e10
    mymin = 9e10
    mymax = -9e10
    for pshape in pshapes:
        pxmin,pymin,pxmax,pymax = pshape.bounds
        if pxmin < mxmin:
            mxmin = pxmin
        if pxmax > mxmax:
            mxmax = pxmax
        if pymin < mymin:
            mymin = pymin
        if pymax > mymax:
            mymax = pymax

    #
    if not touch_center:
        geodict = GeoDict.createDictFromBox(mxmin,mxmax,mymin,mymax,dx,dx)
        img = rasterizeShapes(pshapes,geodict)
        #now get the numpy array of x/y coordinates where covgrid == 1
        idx = np.where(img == 1)[0]
        x,y = np.unravel_index(idx,(geodict.ny,geodict.nx))
        yespoints = list(zip(x.flatten(),y.flatten()))
        nrows = geodict.ny
        ncols = geodict.nx
        #Create the sequence of column and row centers
        xvar = np.arange(geodict.xmin,geodict.xmax+geodict.dx,geodict.dx)
        yvar = np.arange(geodict.ymin,geodict.ymax+geodict.dy,geodict.dy)
    else:
        xvar = np.arange(mxmin,mxmax+dx,dx)
        yvar = np.arange(mymin,mymax+dx,dx)
        ncols = len(xvar)
        nrows = len(yvar)
        if nmax is not None:
            if ncols*nrows > nmax:
                aspect = ncols/nrows
                ncols = np.sqrt(nmax*aspect)
                nrows = nmax/ncols
                ncols = int(ncols)
                nrows = int(nrows)
                #re-calculate dx here...
                tdx = (mxmax-mxmin)/ncols
                tdy = (mymax-mymin)/nrows
                dx = np.max([tdx,tdy])
                xvar = np.arange(mxmin,mxmax+dx,dx)
                yvar = np.arange(mymin,mymax+dx,dx)

        #Get the "yes" points to sample from
        #here, we're in the situation
        yespoints = []
        idx = []
        shapeidx = 0
        if pshapes[0].type == 'Polygon':
            #loop over shapes, projecting each one, then get the sample points
            for pshape in pshapes:
                if not shapeidx % 1000:
                    print('Searching polygon %i of %i' % (shapeidx,len(pshapes)))
                shapeidx += 1
                pxmin,pymin,pxmax,pymax = pshape.bounds
                leftcol = np.where((pxmin - xvar) >= 0)
                rightcol = np.where((xvar - pxmax) >= 0)
                if len(leftcol[0]) and len(rightcol[0]):
                    leftcol = leftcol[0].argmax()
                    rightcol = rightcol[0].argmax()

                bottomrow = np.where((pymin - yvar) >= 0)
                toprow = np.where((yvar - pymax) >= 0)
                if len(bottomrow[0]) and len(toprow[0]):
                    bottomrow = bottomrow[0].argmax()
                    toprow = toprow[0][0]

                xp = np.arange(xvar[leftcol],xvar[rightcol]+dx,dx)
                yp = np.arange(yvar[bottomrow],yvar[toprow]+dx,dx)
                xmesh,ymesh = np.meshgrid(xp,yp)
                xy = list(zip(xmesh.flatten(),ymesh.flatten()))
                for point in xy:
                    ix = np.where(xvar == point[0])
                    iy = np.where(yvar == point[1])
                    if len(ix[0]) and len(iy[0]):
                        ix = ix[0][0]
                        try:
                            iy = iy[0][0]
                        except:
                            foo = 1
                        if pshape.contains(Point(point)):
                            yespoints.append(point)
                            idx.append(np.ravel_multi_index((iy,ix),(nrows,ncols),mode='raise',order='C'))
                            
        else:
            yespoints = []
            for pshape in pshapes:
                yespoints.append(pshape.coords[0])
            
    return (np.array(yespoints),nrows,ncols,xvar,yvar,idx)