Example #1
0
    def test_pyproj_trafo(self):

        x = np.random.randn(int(1e6)) * 60
        y = np.random.randn(int(1e6)) * 60

        for i in np.arange(3):
            xx, yy = pyproj.transform(wgs84, wgs84, x, y)
        assert_allclose(xx, x)
        assert_allclose(yy, y)

        for i in np.arange(3):
            xx, yy = gis.transform_proj(wgs84, wgs84, x, y)
        assert_allclose(xx, x)
        assert_allclose(yy, y)

        for i in np.arange(3):
            xx, yy = gis.transform_proj(wgs84, wgs84, x, y, nocopy=True)
        assert_allclose(xx, x)
        assert_allclose(yy, y)

        xx, yy = pyproj.transform(gis.check_crs('+init=epsg:26915'),
                                  gis.check_crs('+init=epsg:26915'), x, y)
        assert_allclose(xx, x, atol=1e-3)
        assert_allclose(yy, y, atol=1e-3)

        xx, yy = gis.transform_proj(gis.check_crs('+init=epsg:26915'),
                                    gis.check_crs('+init=epsg:26915'), x, y)
        assert_allclose(xx, x)
        assert_allclose(yy, y)
Example #2
0
    def test_comparisons(self):
        """See if the grids can compare themselves"""

        args = dict(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=wgs84)
        g1 = Grid(**args)
        self.assertEqual(g1.center_grid, g1.corner_grid)
        self.assertTrue(g1.center_grid.almost_equal(g1.center_grid))

        g2 = Grid(**args)
        self.assertEqual(g1, g2)
        self.assertTrue(g1.almost_equal(g2))

        args['dxdy'] = (1. + 1e-6, 1. + 1e-6)
        g2 = Grid(**args)
        self.assertNotEqual(g1, g2)
        self.assertTrue(g1.almost_equal(g2))

        # serialization
        d = g1.to_dict()
        rg = Grid.from_dict(d)
        self.assertEqual(g1, rg)
        d = g2.to_dict()
        rg = Grid.from_dict(d)
        self.assertEqual(g2, rg)
        self.assertNotEqual(g1, rg)
        self.assertTrue(g1.almost_equal(rg))
        g1.to_json('test.json')
        rg = Grid.from_json('test.json')
        os.remove('test.json')
        self.assertEqual(g1, rg)
        g2.to_json('test.json')
        rg = Grid.from_json('test.json')
        os.remove('test.json')
        self.assertEqual(g2, rg)
        self.assertNotEqual(g1, rg)
        self.assertTrue(g1.almost_equal(rg))

        args['proj'] = gis.check_crs('+init=epsg:26915')
        g2 = Grid(**args)
        self.assertNotEqual(g1, g2)
        self.assertFalse(g1.almost_equal(g2))

        # New instance, same proj
        args['proj'] = gis.check_crs('+init=epsg:26915')
        g1 = Grid(**args)
        self.assertEqual(g1, g2)
        self.assertTrue(g1.almost_equal(g2))
        # serialization
        d = g1.to_dict()
        rg = Grid.from_dict(d)
        self.assertEqual(g1, rg)
        self.assertTrue(g1.almost_equal(rg))
        g1.to_json('test.json')
        rg = Grid.from_json('test.json')
        os.remove('test.json')
        self.assertEqual(g1, rg)
        self.assertTrue(g1.almost_equal(rg))
Example #3
0
    def test_ij_to_crs(self):
        """Converting to projection"""

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:

            args = dict(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=proj)

            g = Grid(**args)
            exp_i, exp_j = np.meshgrid(np.arange(3), np.arange(3))
            r_i, r_j = g.ij_to_crs(exp_i, exp_j)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            proj_out = proj
            r_i, r_j = g.ij_to_crs(exp_i, exp_j, crs=proj_out)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)

            # The equivalents
            gc = g.corner_grid
            r_i, r_j = gc.ij_to_crs(exp_i + 0.5, exp_j + 0.5)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            gc = g.center_grid
            r_i, r_j = gc.ij_to_crs(exp_i, exp_j)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)

            args = dict(nxny=(3, 3), dxdy=(1, -1), x0y0=(0, 0), proj=proj)
            g = Grid(**args)
            exp_i, exp_j = np.meshgrid(np.arange(3), -np.arange(3))
            in_i, in_j = np.meshgrid(np.arange(3), np.arange(3))
            r_i, r_j = g.ij_to_crs(in_i, in_j)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            proj_out = proj
            r_i, r_j = g.ij_to_crs(in_i, in_j, crs=proj_out)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)

            # The equivalents
            gc = g.corner_grid
            r_i, r_j = gc.ij_to_crs(in_i, in_j)
            assert_allclose(exp_i - 0.5, r_i, atol=1e-03)
            assert_allclose(exp_j + 0.5, r_j, atol=1e-03)
            gc = g.center_grid
            r_i, r_j = gc.ij_to_crs(in_i, in_j)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)

            # if we take some random projection it wont work
            proj_out = pyproj.Proj(proj="utm", zone=10, datum='NAD27')
            r_i, r_j = g.ij_to_crs(exp_i, exp_j, crs=proj_out)
            self.assertFalse(np.allclose(exp_i, r_i))
            self.assertFalse(np.allclose(exp_j, r_j))

            # Raise
            self.assertRaises(ValueError, g.ij_to_crs, exp_i, exp_j, crs='ups')
Example #4
0
    def test_map_gridded_data(self):
        """Ok now the serious stuff starts with some fake data"""

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:

            nx, ny = (3, 4)
            data = np.arange(nx * ny).reshape((ny, nx))

            # Nearest Neighbor
            args = dict(nxny=(nx, ny), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            g = Grid(**args)
            odata = g.map_gridded_data(data, g)
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data, odata, atol=1e-03)

            # Out of the grid
            go = Grid(nxny=(nx, ny), dxdy=(1, 1), x0y0=(9, 9), proj=proj)
            odata = g.map_gridded_data(data, go)
            odata.set_fill_value(-999)
            self.assertTrue(odata.shape == data.shape)
            self.assertTrue(np.all(odata.mask))

            args = dict(nxny=(nx - 1, ny - 1),
                        dxdy=(1, 1),
                        x0y0=(0, 0),
                        proj=proj)
            ig = Grid(**args)
            odata = g.map_gridded_data(data[0:ny - 1, 0:nx - 1], ig)
            self.assertTrue(odata.shape == (ny, nx))
            assert_allclose(data[0:ny - 1, 0:nx - 1],
                            odata[0:ny - 1, 0:nx - 1],
                            atol=1e-03)
            assert_array_equal([True] * 3, odata.mask[ny - 1, :])

            data = np.arange(nx * ny).reshape((ny, nx)) * 1.2
            odata = g.map_gridded_data(data[0:ny - 1, 0:nx - 1], ig)
            self.assertTrue(odata.shape == (ny, nx))
            assert_allclose(data[0:ny - 1, 0:nx - 1],
                            odata[0:ny - 1, 0:nx - 1],
                            atol=1e-03)
            self.assertTrue(
                np.sum(np.isfinite(odata)) == ((ny - 1) * (nx - 1)))

            # Bilinear
            data = np.arange(nx * ny).reshape((ny, nx))
            exp_data = np.array([2., 3., 5., 6., 8., 9.]).reshape(
                (ny - 1, nx - 1))
            args = dict(nxny=(nx, ny), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            gfrom = Grid(**args)
            args = dict(nxny=(nx - 1, ny - 1),
                        dxdy=(1, 1),
                        x0y0=(0.5, 0.5),
                        proj=proj)
            gto = Grid(**args)
            odata = gto.map_gridded_data(data, gfrom, interp='linear')
            self.assertTrue(odata.shape == (ny - 1, nx - 1))
            assert_allclose(exp_data, odata, atol=1e-03)
Example #5
0
    def test_extent(self):

        # It should work exact same for any projection
        args = dict(nxny=(9, 9), dxdy=(1, 1), x0y0=(0, 0), proj=wgs84)
        g1 = Grid(**args)
        assert_allclose(g1.extent, g1.extent_in_crs(crs=g1.proj), atol=1e-3)

        args = dict(nxny=(9, 9),
                    dxdy=(30000, 30000),
                    x0y0=(0., 1577463),
                    proj=gis.check_crs('+init=epsg:26915'))
        g2 = Grid(**args)
        assert_allclose(g2.extent, g2.extent_in_crs(crs=g2.proj), atol=1e-3)

        exg = np.array(g2.extent_in_crs(crs=g1))
        exgx, exgy = g1.ij_to_crs(exg[[0, 1]], exg[[2, 3]], crs=wgs84)

        lon, lat = g2.corner_grid.ll_coordinates
        assert_allclose([np.min(lon), np.min(lat)], [exgx[0], exgy[0]],
                        rtol=0.1)

        p = g2.extent_as_polygon(crs=g2.proj)

        assert p.is_valid
        x, y = p.exterior.coords.xy
        assert_allclose([np.min(x), np.max(x),
                         np.min(y), np.max(y)], g2.extent)
Example #6
0
    def __init__(self, x, y, crs=wgs84, size_x=640, size_y=640, scale=1,
                 maptype='satellite', use_cache=True, **kwargs):
        """Initialize

        Parameters
        ----------
        x : array
          x coordinates of the points to include on the map
        y : array
          y coordinates of the points to include on the map
        crs : proj or Grid
          coordinate reference system of x, y
        size_x : int
          image size
        size_y : int
          image size
        scale : int
          image scaling factor
        maptype : str, default: 'satellite'
          'roadmap', 'satellite', 'hybrid', 'terrain'
        use_cache : bool, default: True
          store the downloaded image in the cache to avoid future downloads
        kwargs : **
          any keyword accepted by motionless.CenterMap (e.g. `key` for the API)
        """

        if 'zoom' in kwargs or 'center_ll' in kwargs:
            raise ValueError('incompatible kwargs.')

        # Transform to lonlat
        crs = gis.check_crs(crs)
        if isinstance(crs, pyproj.Proj):
            lon, lat = gis.transform_proj(crs, wgs84, x, y)
        elif isinstance(crs, Grid):
            lon, lat = crs.ij_to_crs(x, y, crs=wgs84)
        else:
            raise NotImplementedError()

        # surely not the smartest way to do but should be enough for now
        mc = (np.mean(lon), np.mean(lat))
        zoom = 20
        while zoom >= 0:
            grid = gis.googlestatic_mercator_grid(center_ll=mc, nx=size_x,
                                                  ny=size_y, zoom=zoom,
                                                  scale=scale)
            dx, dy = grid.transform(lon, lat, maskout=True)
            if np.any(dx.mask):
                zoom -= 1
            else:
                break

        GoogleCenterMap.__init__(self, center_ll=mc, size_x=size_x,
                                 size_y=size_y, zoom=zoom, scale=scale,
                                 maptype=maptype, use_cache=use_cache, **kwargs)
Example #7
0
 def __init__(self, file):
     self.nc = netCDF4.Dataset(file)
     proj = gis.check_crs(str(self.nc.proj4_str))
     x = self.nc.variables['x']
     y = self.nc.variables['y']
     dxdy = (x[1] - x[0], y[1] - y[0])
     nxny = (len(x), len(y))
     x0y0 = None
     if dxdy[1] > 0:
         x0y0 = (x[0], y[0])
     if dxdy[1] < 0:
         x0y0 = (x[0], y[0])
     self.grid = Grid(nxny=nxny, dxdy=dxdy, proj=proj, x0y0=x0y0)
Example #8
0
    def test_geometry(self):
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]
        from shapely.geometry import Point
        for proj in projs:
            g = Grid(nxny=(3, 3), dxdy=(1, 1), x0y0=(0.5, 0.5), proj=proj)
            gdf = g.to_geometry()
            self.assertEqual(len(gdf), 9)
            self.assertTrue(gdf.contains(Point(1.5, 1.5))[4])
            self.assertFalse(gdf.contains(Point(1.5, 1.5))[5])

        gdf = g.to_geometry(to_crs=wgs84)
        # This is now quite off
        self.assertFalse(gdf.contains(Point(1.5, 1.5))[4])
Example #9
0
    def __init__(self, x, y, crs=wgs84, size_x=640, size_y=640,
                 maptype='satellite', use_cache=True, **kwargs):
        """Initialize

        Parameters
        ----------
        x : array
          x coordinates of the points to include on the map
        y : array
          y coordinates of the points to include on the map
        crs : proj or Grid
          coordinate reference system of x, y
        size_x : int
          image size
        size_y : int
          image size
        maptype : str, default: 'satellite'
          'roadmap', 'satellite', 'hybrid', 'terrain'
        use_cache : bool, default: True
          store the downloaded image in the cache to avoid future downloads
        kwargs : **
          any keyword accepted by motionless.CenterMap (e.g. `key` for the API)
        """

        if 'zoom' in kwargs or 'center_ll' in kwargs:
            raise ValueError('incompatible kwargs.')

        # Transform to lonlat
        crs = gis.check_crs(crs)
        if isinstance(crs, pyproj.Proj):
            lon, lat = gis.transform_proj(crs, wgs84, x, y)
        elif isinstance(crs, Grid):
            lon, lat = crs.ij_to_crs(x, y, crs=wgs84)
        else:
            raise NotImplementedError()

        # surely not the smartest way to do but should be enough for now
        mc = (np.mean(lon), np.mean(lat))
        zoom = 20
        while zoom >= 0:
            grid = gis.googlestatic_mercator_grid(center_ll=mc, nx=size_x,
                                                  ny=size_y, zoom=zoom)
            dx, dy = grid.transform(lon, lat, maskout=True)
            if np.any(dx.mask):
                zoom -= 1
            else:
                break

        GoogleCenterMap.__init__(self, center_ll=mc, size_x=size_x,
                                 size_y=size_y, zoom=zoom, maptype=maptype,
                                 use_cache=use_cache, **kwargs)
Example #10
0
    def _check_data(self,
                    data=None,
                    crs=None,
                    interp='nearest',
                    overplot=False):
        """Interpolates the data to the map grid."""

        if crs is None:
            # try xarray
            # TODO: note that this might slow down the plotting a bit
            # if the data already matches the grid...
            try:
                crs = data.salem.grid
            except:
                pass

        data = np.ma.fix_invalid(np.squeeze(data))
        shp = data.shape
        if len(shp) != 2:
            raise ValueError('Data should be 2D.')

        crs = gis.check_crs(crs)
        if crs is None:
            # Reform case, but with a sanity check
            if not np.isclose(
                    shp[0] / shp[1], self.grid.ny / self.grid.nx, atol=1e-2):
                raise ValueError('Dimensions of data do not match the map.')

            # need to resize if not same
            if not ((shp[0] == self.grid.ny) and (shp[1] == self.grid.nx)):
                if interp.lower() == 'linear':
                    interp = 'bilinear'
                if interp.lower() == 'spline':
                    interp = 'cubic'
                # TODO: this does not work well with masked arrays
                data = imresize(data.filled(np.NaN),
                                (self.grid.ny, self.grid.nx),
                                interp=interp,
                                mode='F')
        elif isinstance(crs, Grid):
            # Remap
            if overplot:
                data = self.grid.map_gridded_data(data,
                                                  crs,
                                                  interp=interp,
                                                  out=self.data)
            else:
                data = self.grid.map_gridded_data(data, crs, interp=interp)
        else:
            raise ValueError('crs not understood')
        return data
Example #11
0
    def test_regrid(self):
        """New grids"""

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:

            kargs = [
                dict(nxny=(3, 2), dxdy=(1, 1), x0y0=(0, 0), proj=proj),
                dict(nxny=(3, 2), dxdy=(1, -1), x0y0=(0, 0), proj=proj),
                dict(nxny=(3, 2),
                     dxdy=(1, 1),
                     x0y0=(0, 0),
                     proj=proj,
                     pixel_ref='corner'),
                dict(nxny=(3, 2),
                     dxdy=(1, -1),
                     x0y0=(0, 0),
                     proj=proj,
                     pixel_ref='corner')
            ]

            for ka in kargs:
                g = Grid(**ka)

                rg = g.regrid()
                self.assertTrue(g == rg)

                rg = g.regrid(factor=3)
                assert_array_equal(g.extent, rg.extent)
                assert_array_equal(g.extent, rg.extent)

                bg = rg.regrid(factor=1 / 3)
                self.assertEqual(g, bg)

                gx, gy = g.center_grid.xy_coordinates
                rgx, rgy = rg.center_grid.xy_coordinates
                assert_allclose(gx, rgx[1::3, 1::3], atol=1e-7)
                assert_allclose(gy, rgy[1::3, 1::3], atol=1e-7)

                gx, gy = g.center_grid.ll_coordinates
                rgx, rgy = rg.center_grid.ll_coordinates
                assert_allclose(gx, rgx[1::3, 1::3], atol=1e-7)
                assert_allclose(gy, rgy[1::3, 1::3], atol=1e-7)

                nrg = g.regrid(nx=9)
                self.assertTrue(nrg == rg)

                nrg = g.regrid(ny=6)
                self.assertTrue(nrg == rg)
Example #12
0
    def test_to_dataset(self):
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:
            g = Grid(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            ds = g.to_dataset()
            self.assertTrue(g == ds.salem.grid)

            g = Grid(nxny=(3, 3),
                     dxdy=(1, 1),
                     x0y0=(0, 0),
                     proj=proj,
                     pixel_ref='corner')
            ds = g.to_dataset()
            self.assertTrue(g == ds.salem.grid)
Example #13
0
 def __init__(self, file):
     self.nc = netCDF4.Dataset(file)
     proj = gis.check_crs(str(self.nc.proj4_str))
     x = self.nc.variables['x']
     y = self.nc.variables['y']
     dxdy = (x[1]-x[0], y[1]-y[0])
     nxny = (len(x), len(y))
     ll_corner = None
     ul_corner = None
     if dxdy[1] > 0:
         ll_corner = (x[0], y[0])
     if dxdy[1] < 0:
         ul_corner = (x[0], y[0])
     self.grid = Grid(nxny=nxny, dxdy=dxdy, proj=proj,
                      ll_corner=ll_corner, ul_corner=ul_corner)
Example #14
0
    def test_same_proj(self):

        # this should work regardless of gdal or not:
        p1 = pyproj.Proj('+proj=utm +zone=15 +datum=NAD83 '
                         '+ellps=GRS80 +towgs84=0,0,0 +units=m +no_defs')
        p2 = pyproj.Proj('+proj=utm +zone=15 +datum=NAD83 +units=m +no_defs '
                         '+ellps=GRS80 +towgs84=0,0,0')
        self.assertTrue(gis.proj_is_same(p1, p2))

        # this needs gdal
        p1 = gis.check_crs('+init=epsg:26915')
        p2 = pyproj.Proj('+proj=utm +zone=15 +ellps=GRS80 +datum=NAD83 '
                         '+units=m +no_defs')
        if gis.has_gdal:
            self.assertTrue(gis.proj_is_same(p1, p2))
Example #15
0
    def test_xarray_support(self):
        # what happens if we use salem's funcs with xarray?
        import xarray as xr

        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:
            args = dict(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            g = Grid(**args)
            exp_i, exp_j = np.meshgrid(np.arange(3), np.arange(3))
            exp_i, exp_j = (xr.DataArray(exp_i, dims=['y', 'x']),
                            xr.DataArray(exp_j, dims=['y', 'x']))
            r_i, r_j = g.ij_to_crs(exp_i, exp_j)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            self.assertTrue(r_i.dims == exp_i.dims)

            # transform
            r_i, r_j = g.transform(exp_i, exp_j, crs=proj)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            # TODO: this doesn't work:
            # self.assertTrue(r_i.dims == exp_i.dims)

            # map
            nx, ny = (3, 4)
            data = np.arange(nx * ny).reshape((ny, nx))
            data = xr.DataArray(data,
                                coords={
                                    'y': np.arange(ny),
                                    'x': np.arange(nx)
                                },
                                dims=['y', 'x'])
            data.attrs = {'test': 'attr'}

            # Nearest Neighbor
            args = dict(nxny=(nx, ny), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            g = Grid(**args)
            odata = g.map_gridded_data(data, g)
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data, odata, atol=1e-03)

            # Transform can understand a grid
            data.attrs['pyproj_srs'] = g.proj.srs
            odata = g.map_gridded_data(data)
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data, odata, atol=1e-03)
Example #16
0
    def _check_data(self, data=None, crs=None, interp='nearest',
                    overplot=False):
        """Interpolates the data to the map grid."""

        if crs is None:
            # try xarray
            # TODO: note that this might slow down the plotting a bit
            # if the data already matches the grid...
            try:
                crs = data.salem.grid
            except:
                pass

        data = np.ma.fix_invalid(np.squeeze(data))
        shp = data.shape
        if len(shp) != 2:
            raise ValueError('Data should be 2D.')

        crs = gis.check_crs(crs)
        if crs is None:
            # Reform case, but with a sanity check
            if not np.isclose(shp[0] / shp[1], self.grid.ny / self.grid.nx,
                              atol=1e-2):
                raise ValueError('Dimensions of data do not match the map.')

            # need to resize if not same
            if not ((shp[0] == self.grid.ny) and (shp[1] == self.grid.nx)):
                if interp.lower() == 'linear':
                    interp = 'bilinear'
                if interp.lower() == 'spline':
                    interp = 'cubic'
                # TODO: this does not work well with masked arrays
                data = imresize(data.filled(np.NaN),
                                (self.grid.ny, self.grid.nx),
                                interp=interp, mode='F')
        elif isinstance(crs, Grid):
            # Remap
            if overplot:
                data = self.grid.map_gridded_data(data, crs, interp=interp,
                                                  out=self.data)
            else:
                data = self.grid.map_gridded_data(data, crs, interp=interp)
        else:
            raise ValueError('crs not understood')
        return data
Example #17
0
def _salem_grid_from_dataset(ds):
    """Seek for coordinates that Salem might have created.

    Current convention: x_coord, y_coord, pyproj_srs as attribute
    """

    # Projection
    try:
        proj = ds.pyproj_srs
    except AttributeError:
        proj = None
    proj = gis.check_crs(proj)
    if proj is None:
        return None

    # Do we have some standard names as variable?
    vns = ds.variables.keys()
    xc = utils.str_in_list(vns, utils.valid_names['x_dim'])
    yc = utils.str_in_list(vns, utils.valid_names['y_dim'])

    # Sometimes there are more than one coordinates, one of which might have
    # more dims (e.g. lons in WRF files): take the first one with ndim = 1:
    x = None
    for xp in xc:
        if len(ds.variables[xp].shape) == 1:
            x = xp
    y = None
    for yp in yc:
        if len(ds.variables[yp].shape) == 1:
            y = yp
    if (x is None) or (y is None):
        return None

    # OK, get it
    x = ds.variables[x][:]
    y = ds.variables[y][:]

    # Make the grid
    dx = x[1] - x[0]
    dy = y[1] - y[0]
    args = dict(nxny=(x.shape[0], y.shape[0]),
                proj=proj,
                dxdy=(dx, dy),
                x0y0=(x[0], y[0]))
    return gis.Grid(**args)
Example #18
0
def _salem_grid_from_dataset(ds):
    """Seek for coordinates that Salem might have created.

    Current convention: x_coord, y_coord, pyproj_srs as attribute
    """


    # Projection
    try:
        proj = ds.pyproj_srs
    except AttributeError:
        proj = None
    proj = gis.check_crs(proj)
    if proj is None:
        return None

    # Do we have some standard names as variable?
    vns = ds.variables.keys()
    xc = utils.str_in_list(vns, utils.valid_names['x_dim'])
    yc = utils.str_in_list(vns, utils.valid_names['y_dim'])

    # Sometimes there are more than one coordinates, one of which might have
    # more dims (e.g. lons in WRF files): take the first one with ndim = 1:
    x = None
    for xp in xc:
        if len(ds.variables[xp].shape) == 1:
            x = xp
    y = None
    for yp in yc:
        if len(ds.variables[yp].shape) == 1:
            y = yp
    if (x is None) or (y is None):
        return None

    # OK, get it
    x = ds.variables[x][:]
    y = ds.variables[y][:]

    # Make the grid
    dx = x[1]-x[0]
    dy = y[1]-y[0]
    args = dict(nxny=(x.shape[0], y.shape[0]), proj=proj, dxdy=(dx, dy))
    args['corner'] = (x[0], y[0])
    return gis.Grid(**args)
Example #19
0
    def test_stagg(self):
        """Staggered grids."""

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:
            args = dict(nxny=(3, 2),
                        dxdy=(1, 1),
                        x0y0=(0, 0),
                        proj=proj,
                        pixel_ref='corner')
            g = Grid(**args)
            x, y = g.xstagg_xy_coordinates
            assert_array_equal(x, np.array([[0, 1, 2, 3], [0, 1, 2, 3]]))
            assert_array_equal(
                y, np.array([[0.5, 0.5, 0.5, 0.5], [1.5, 1.5, 1.5, 1.5]]))
            xx, yy = g.corner_grid.xstagg_xy_coordinates
            assert_array_equal(x, xx)
            assert_array_equal(y, yy)
            xt, yt = x, y

            x, y = g.ystagg_xy_coordinates
            assert_array_equal(
                x, np.array([[0.5, 1.5, 2.5], [0.5, 1.5, 2.5], [0.5, 1.5,
                                                                2.5]]))
            assert_array_equal(y, np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]))
            xx, yy = g.corner_grid.ystagg_xy_coordinates
            assert_array_equal(x, xx)
            assert_array_equal(y, yy)

            if proj is wgs84:
                xx, yy = g.corner_grid.ystagg_ll_coordinates
                assert_allclose(x, xx)
                assert_allclose(y, yy)
                xx, yy = g.corner_grid.xstagg_ll_coordinates
                assert_allclose(xt, xx)
                assert_allclose(yt, yy)

                x, y = g.pixcorner_ll_coordinates
                assert_allclose(
                    x, np.array([[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]))
                assert_allclose(
                    y, np.array([[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]]))
Example #20
0
    def test_projplot(self):

        # this caused many problems on fabien's laptop.
        # this is just to be sure that on your system, everything is fine

        import pyproj
        import matplotlib.pyplot as plt
        from salem.gis import transform_proj, check_crs

        wgs84 = pyproj.Proj(proj='latlong', datum='WGS84')
        fig = plt.figure()
        plt.close()

        srs = '+units=m +proj=lcc +lat_1=29.0 +lat_2=29.0 +lat_0=29.0 +lon_0=89.8'

        proj_out = check_crs('+init=EPSG:4326')
        proj_in = pyproj.Proj(srs, preserve_units=True)

        lon, lat = transform_proj(proj_in, proj_out, -2235000, -2235000)
        np.testing.assert_allclose(lon, 70.75731, atol=1e-5)
Example #21
0
    def test_to_cartopy(self):

        import cartopy.crs as ccrs
        from salem import GeoNetcdf, GeoTiff

        grid = gis.mercator_grid(center_ll=(11.38, 47.26),
                                 extent=(2000000, 2000000))
        p = gis.proj_to_cartopy(grid.proj)
        assert isinstance(p, ccrs.TransverseMercator)
        fuzzy_proj_tester(grid.proj, pyproj.Proj(p.proj4_params))

        ds = GeoNetcdf(get_demo_file('wrfout_d01.nc'))
        p = gis.proj_to_cartopy(ds.grid.proj)
        assert isinstance(p, ccrs.LambertConformal)
        fuzzy_proj_tester(ds.grid.proj, pyproj.Proj(p.proj4_params))

        ds = GeoNetcdf(get_demo_file('wrf_mercator.nc'))
        p = gis.proj_to_cartopy(ds.grid.proj)
        assert isinstance(p, ccrs.Mercator)
        fuzzy_proj_tester(ds.grid.proj, pyproj.Proj(p.proj4_params))

        ds = GeoTiff(get_demo_file('himalaya.tif'))
        p = gis.proj_to_cartopy(ds.grid.proj)
        assert isinstance(p, ccrs.PlateCarree)

        ds = GeoTiff(get_demo_file('hef_roi.tif'))
        p = gis.proj_to_cartopy(ds.grid.proj)
        assert isinstance(p, ccrs.PlateCarree)

        p = gis.proj_to_cartopy(wgs84)
        assert isinstance(p, ccrs.PlateCarree)

        p = gis.proj_to_cartopy(pyproj.Proj('+proj=utm +zone=15'))
        assert isinstance(p, ccrs.UTM)

        # this needs gdal
        if gis.has_gdal:
            p = gis.proj_to_cartopy(gis.check_crs('+init=epsg:26915'))
            assert isinstance(p, ccrs.UTM)
Example #22
0
    def test_map_gridded_data_over(self):

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('epsg:26915')]

        for proj in projs:
            nx, ny = (4, 5)
            data = np.arange(nx * ny).reshape((ny, nx)).astype(np.float)

            in_data = data * np.NaN
            in_data[0, :] = 78

            # Nearest Neighbor
            args = dict(nxny=(nx, ny), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            g = Grid(**args)
            odata = g.map_gridded_data(data, g, out=data.copy())
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data, odata, atol=1e-03)

            odata = g.map_gridded_data(in_data, g, out=data.copy())
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data[1:, :], odata[1:, :], atol=1e-03)
            assert_allclose(odata[0, :], 78, atol=1e-03)

            # Bilinear
            odata = g.map_gridded_data(data,
                                       g,
                                       interp='linear',
                                       out=data.copy())
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data, odata, atol=1e-03)

            # Spline
            odata = g.map_gridded_data(data,
                                       g,
                                       interp='spline',
                                       out=data.copy())
            self.assertTrue(odata.shape == data.shape)
            assert_allclose(data, odata, atol=1e-03)
Example #23
0
    def _check_data(self,
                    data=None,
                    crs=None,
                    interp='nearest',
                    overplot=False):
        """Interpolates the data to the map grid."""

        if crs is None:
            # try xarray
            # TODO: note that this might slow down the plotting a bit
            # if the data already matches the grid...
            try:
                crs = data.salem.grid
            except:
                pass

        data = np.ma.fix_invalid(np.squeeze(data))
        shp = data.shape
        if len(shp) != 2:
            raise ValueError('Data should be 2D.')

        if crs is None:
            # Reform case, but with a sanity check
            if not np.isclose(
                    shp[0] / shp[1], self.grid.ny / self.grid.nx, atol=1e-2):
                raise ValueError('Dimensions of data do not match the map.')

            # need to resize if not same
            if not ((shp[0] == self.grid.ny) and (shp[1] == self.grid.nx)):

                # We convert to float for img resizing
                if data.dtype not in [np.float32, np.float64]:
                    data = data.astype(np.float64)

                if interp.lower() == 'nearest':
                    interp = 0
                elif interp.lower() == 'linear':
                    interp = 1
                elif interp.lower() == 'spline':
                    interp = 3
                if not has_skimage:
                    raise ImportError('Needs scikit-image to be installed.')
                with warnings.catch_warnings():
                    mess = "invalid value encountered in reduce"
                    warnings.filterwarnings("ignore", message=mess)
                    mess = ("Possible precision loss when converting from "
                            "int64 to float64")
                    warnings.filterwarnings("ignore", message=mess)
                    try:
                        data = imresize(data.filled(np.NaN),
                                        (self.grid.ny, self.grid.nx),
                                        order=interp,
                                        mode='edge',
                                        anti_aliasing=True)
                    except RuntimeError:
                        # For some order anti_aliasing doesnt work with 'edge'
                        data = imresize(data.filled(np.NaN),
                                        (self.grid.ny, self.grid.nx),
                                        order=interp,
                                        mode='edge',
                                        anti_aliasing=False)

            return data

        crs = gis.check_crs(crs, raise_on_error=True)
        if isinstance(crs, Grid):
            # Remap
            if overplot:
                data = self.grid.map_gridded_data(data,
                                                  crs,
                                                  interp=interp,
                                                  out=self.data)
            else:
                data = self.grid.map_gridded_data(data, crs, interp=interp)
        else:
            raise ValueError('crs should be a grid, not a proj')

        return data
Example #24
0
    def __init__(self,
                 x,
                 y,
                 crs=wgs84,
                 size_x=640,
                 size_y=640,
                 scale=1,
                 maptype='satellite',
                 use_cache=True,
                 **kwargs):
        """Initialize

        Parameters
        ----------
        x : array
          x coordinates of the points to include on the map
        y : array
          y coordinates of the points to include on the map
        crs : proj or Grid
          coordinate reference system of x, y
        size_x : int
          image size
        size_y : int
          image size
        scale : int
          image scaling factor. 1, 2. 2 is higher resolution but takes
          longer to download
        maptype : str, default: 'satellite'
          'roadmap', 'satellite', 'hybrid', 'terrain'
        use_cache : bool, default: True
          store the downloaded image in the cache to avoid future downloads
        kwargs : **
          any keyword accepted by motionless.CenterMap (e.g. `key` for the API)

        Notes
        -----
        To obtain the exact domain specified in `x` and `y` you may have to
        play with the `size_x` and `size_y` kwargs.
        """

        global API_KEY

        if 'zoom' in kwargs or 'center_ll' in kwargs:
            raise ValueError('incompatible kwargs.')

        # Transform to lonlat
        crs = gis.check_crs(crs)
        if isinstance(crs, pyproj.Proj):
            lon, lat = gis.transform_proj(crs, wgs84, x, y)
        elif isinstance(crs, Grid):
            lon, lat = crs.ij_to_crs(x, y, crs=wgs84)
        else:
            raise NotImplementedError()

        # surely not the smartest way to do but should be enough for now
        mc = (np.mean(lon), np.mean(lat))
        zoom = 20
        while zoom >= 0:
            grid = gis.googlestatic_mercator_grid(center_ll=mc,
                                                  nx=size_x,
                                                  ny=size_y,
                                                  zoom=zoom,
                                                  scale=scale)
            dx, dy = grid.transform(lon, lat, maskout=True)
            if np.any(dx.mask):
                zoom -= 1
            else:
                break

        if 'key' not in kwargs:
            if API_KEY is None:
                with open(utils.get_demo_file('.api_key'), 'r') as f:
                    API_KEY = f.read().replace('\n', '')
            kwargs['key'] = API_KEY

        GoogleCenterMap.__init__(self,
                                 center_ll=mc,
                                 size_x=size_x,
                                 size_y=size_y,
                                 zoom=zoom,
                                 scale=scale,
                                 maptype=maptype,
                                 use_cache=use_cache,
                                 **kwargs)
Example #25
0
def geogrid_simulator(fpath, do_maps=True, map_kwargs=None):
    """Emulates geogrid.exe, which is useful when defining new WRF domains.

    Parameters
    ----------
    fpath: str
       path to a namelist.wps file
    do_maps: bool
       if you want the simulator to return you maps of the grids as well
    map_kwargs: dict
       kwargs to pass to salem.Map()

    Returns
    -------
    (grids, maps) with:
        - grids: a list of Grids corresponding to the domains
          defined in the namelist
        - maps: a list of maps corresponding to the grids (if do_maps==True)
    """

    with open(fpath) as f:
        lines = f.readlines()

    pargs = dict()
    for l in lines:
        s = l.split('=')
        if len(s) < 2:
            continue
        s0 = s[0].strip().upper()
        s1 = list(filter(None, s[1].strip().replace('\n', '').split(',')))

        if s0 == 'PARENT_ID':
            parent_id = [int(s) for s in s1]
        if s0 == 'PARENT_GRID_RATIO':
            parent_ratio = [int(s) for s in s1]
        if s0 == 'I_PARENT_START':
            i_parent_start = [int(s) for s in s1]
        if s0 == 'J_PARENT_START':
            j_parent_start = [int(s) for s in s1]
        if s0 == 'E_WE':
            e_we = [int(s) for s in s1]
        if s0 == 'E_SN':
            e_sn = [int(s) for s in s1]
        if s0 == 'DX':
            dx = float(s1[0])
        if s0 == 'DY':
            dy = float(s1[0])
        if s0 == 'MAP_PROJ':
            map_proj = s1[0].replace("'", '').strip().upper()
        if s0 == 'REF_LAT':
            pargs['lat_0'] = float(s1[0])
        if s0 == 'REF_LON':
            pargs['ref_lon'] = float(s1[0])
        if s0 == 'TRUELAT1':
            pargs['lat_1'] = float(s1[0])
        if s0 == 'TRUELAT2':
            pargs['lat_2'] = float(s1[0])
        if s0 == 'STAND_LON':
            pargs['lon_0'] = float(s1[0])

    # Sometimes files are not complete
    pargs.setdefault('lon_0', pargs['ref_lon'])

    # define projection
    if map_proj == 'LAMBERT':
        pwrf = '+proj=lcc +lat_1={lat_1} +lat_2={lat_2} ' \
               '+lat_0={lat_0} +lon_0={lon_0} ' \
               '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        pwrf = pwrf.format(**pargs)
    elif map_proj == 'MERCATOR':
        pwrf = '+proj=merc +lat_ts={lat_1} +lon_0={lon_0} ' \
               '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        pwrf = pwrf.format(**pargs)
    elif map_proj == 'POLAR':
        pwrf = '+proj=stere +lat_ts={lat_1} +lat_0=90.0 +lon_0={lon_0} ' \
               '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        pwrf = pwrf.format(**pargs)
    else:
        raise NotImplementedError('WRF proj not implemented yet: '
                                  '{}'.format(map_proj))
    pwrf = gis.check_crs(pwrf)

    # get easting and northings from dom center (probably unnecessary here)
    e, n = pyproj.transform(wgs84, pwrf, pargs['ref_lon'], pargs['lat_0'])

    # LL corner
    nx, ny = e_we[0] - 1, e_sn[0] - 1
    x0 = -(nx - 1) / 2. * dx + e  # -2 because of staggered grid
    y0 = -(ny - 1) / 2. * dy + n

    # parent grid
    grid = gis.Grid(nxny=(nx, ny), x0y0=(x0, y0), dxdy=(dx, dy), proj=pwrf)

    # child grids
    out = [grid]
    for ips, jps, pid, ratio, we, sn in zip(i_parent_start, j_parent_start,
                                            parent_id, parent_ratio, e_we,
                                            e_sn):
        if ips == 1:
            continue
        ips -= 1
        jps -= 1
        we -= 1
        sn -= 1
        nx = we / ratio
        ny = sn / ratio
        if nx != (we / ratio):
            raise RuntimeError('e_we and ratios are incompatible: '
                               '(e_we - 1) / ratio must be integer!')
        if ny != (sn / ratio):
            raise RuntimeError('e_sn and ratios are incompatible: '
                               '(e_sn - 1) / ratio must be integer!')

        prevgrid = out[pid - 1]
        xx, yy = prevgrid.corner_grid.x_coord, prevgrid.corner_grid.y_coord
        dx = prevgrid.dx / ratio
        dy = prevgrid.dy / ratio
        grid = gis.Grid(nxny=(we, sn),
                        x0y0=(xx[ips], yy[jps]),
                        dxdy=(dx, dy),
                        pixel_ref='corner',
                        proj=pwrf)
        out.append(grid.center_grid)

    maps = None
    if do_maps:
        from salem import Map
        import shapely.geometry as shpg

        if map_kwargs is None:
            map_kwargs = {}

        maps = []
        for i, g in enumerate(out):
            m = Map(g, **map_kwargs)

            for j in range(i + 1, len(out)):
                cg = out[j]
                left, right, bottom, top = cg.extent

                s = np.array([(left, bottom), (right, bottom), (right, top),
                              (left, top)])
                l1 = shpg.LinearRing(s)
                m.set_geometry(l1,
                               crs=cg.proj,
                               linewidth=(len(out) - j),
                               zorder=5)

            maps.append(m)

    return out, maps
Example #26
0
def _wrf_grid_from_dataset(ds):
    """Get the WRF projection out of the file."""

    pargs = dict()
    if hasattr(ds, 'PROJ_ENVI_STRING'):
        # HAR and other TU Berlin files
        dx = ds.GRID_DX
        dy = ds.GRID_DY
        pargs['lat_1'] = ds.PROJ_STANDARD_PAR1
        pargs['lat_2'] = ds.PROJ_STANDARD_PAR2
        pargs['lat_0'] = ds.PROJ_CENTRAL_LAT
        pargs['lon_0'] = ds.PROJ_CENTRAL_LON
        pargs['center_lon'] = ds.PROJ_CENTRAL_LON
        if ds.PROJ_NAME in [
                'Lambert Conformal Conic', 'WRF Lambert Conformal'
        ]:
            proj_id = 1
        else:
            proj_id = 99  # pragma: no cover
    else:
        # Normal WRF file
        cen_lon = ds.CEN_LON
        cen_lat = ds.CEN_LAT
        dx = ds.DX
        dy = ds.DY
        pargs['lat_1'] = ds.TRUELAT1
        pargs['lat_2'] = ds.TRUELAT2
        pargs['lat_0'] = ds.MOAD_CEN_LAT
        pargs['lon_0'] = ds.STAND_LON
        pargs['center_lon'] = ds.CEN_LON
        proj_id = ds.MAP_PROJ

    if proj_id == 1:
        # Lambert
        p4 = '+proj=lcc +lat_1={lat_1} +lat_2={lat_2} ' \
             '+lat_0={lat_0} +lon_0={lon_0} ' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        p4 = p4.format(**pargs)
    elif proj_id == 2:
        # Polar stereo
        p4 = '+proj=stere +lat_ts={lat_1} +lon_0={lon_0} +lat_0=90.0' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        p4 = p4.format(**pargs)
    elif proj_id == 3:
        # Mercator
        p4 = '+proj=merc +lat_ts={lat_1} ' \
             '+lon_0={center_lon} ' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        p4 = p4.format(**pargs)
    else:
        raise NotImplementedError('WRF proj not implemented yet: '
                                  '{}'.format(proj_id))

    proj = gis.check_crs(p4)
    if proj is None:
        raise RuntimeError('WRF proj not understood: {}'.format(p4))

    # Here we have to accept xarray and netCDF4 datasets
    try:
        nx = len(ds.dimensions['west_east'])
        ny = len(ds.dimensions['south_north'])
    except AttributeError:
        # maybe an xarray dataset
        nx = ds.dims['west_east']
        ny = ds.dims['south_north']
    if hasattr(ds, 'PROJ_ENVI_STRING'):
        # HAR
        x0 = ds['west_east'][0]
        y0 = ds['south_north'][0]
    else:
        # Normal WRF file
        e, n = gis.transform_proj(wgs84, proj, cen_lon, cen_lat)
        x0 = -(nx - 1) / 2. * dx + e  # DL corner
        y0 = -(ny - 1) / 2. * dy + n  # DL corner
    grid = gis.Grid(nxny=(nx, ny), x0y0=(x0, y0), dxdy=(dx, dy), proj=proj)

    if tmp_check_wrf:
        #  Temporary asserts
        if 'XLONG' in ds.variables:
            # Normal WRF
            reflon = ds.variables['XLONG']
            reflat = ds.variables['XLAT']
        elif 'XLONG_M' in ds.variables:
            # geo_em
            reflon = ds.variables['XLONG_M']
            reflat = ds.variables['XLAT_M']
        elif 'lon' in ds.variables:
            # HAR
            reflon = ds.variables['lon']
            reflat = ds.variables['lat']
        else:
            raise RuntimeError("couldn't test for correct WRF lon-lat")

        if len(reflon.shape) == 3:
            reflon = reflon[0, :, :]
            reflat = reflat[0, :, :]
        mylon, mylat = grid.ll_coordinates

        atol = 5e-3 if proj_id == 2 else 1e-3
        check = np.isclose(reflon, mylon, atol=atol)
        if not np.alltrue(check):
            n_pix = np.sum(~check)
            maxe = np.max(np.abs(reflon - mylon))
            if maxe < (360 - atol):
                warnings.warn('For {} grid points, the expected accuracy ({}) '
                              'of our lons did not match those of the WRF '
                              'file. Max error: {}'.format(n_pix, atol, maxe))
        check = np.isclose(reflat, mylat, atol=atol)
        if not np.alltrue(check):
            n_pix = np.sum(~check)
            maxe = np.max(np.abs(reflat - mylat))
            warnings.warn('For {} grid points, the expected accuracy ({}) '
                          'of our lats did not match those of the WRF file. '
                          'Max error: {}'.format(n_pix, atol, maxe))

    return grid
Example #27
0
def _wrf_grid_from_dataset(ds):
    """Get the WRF projection out of the file."""

    pargs = dict()
    if hasattr(ds, 'PROJ_ENVI_STRING'):
        # HAR and other TU Berlin files
        dx = ds.GRID_DX
        dy = ds.GRID_DY
        pargs['lat_1'] = ds.PROJ_STANDARD_PAR1
        pargs['lat_2'] = ds.PROJ_STANDARD_PAR2
        pargs['lat_0'] = ds.PROJ_CENTRAL_LAT
        pargs['lon_0'] = ds.PROJ_CENTRAL_LON
        pargs['center_lon'] = ds.PROJ_CENTRAL_LON
        if ds.PROJ_NAME == 'Lambert Conformal Conic':
            proj_id = 1
        else:
            proj_id = 99  # pragma: no cover
    else:
        # Normal WRF file
        cen_lon = ds.CEN_LON
        cen_lat = ds.CEN_LAT
        dx = ds.DX
        dy = ds.DY
        pargs['lat_1'] = ds.TRUELAT1
        pargs['lat_2'] = ds.TRUELAT2
        pargs['lat_0'] = ds.MOAD_CEN_LAT
        pargs['lon_0'] = ds.STAND_LON
        pargs['center_lon'] = ds.CEN_LON
        proj_id = ds.MAP_PROJ

    if proj_id == 1:
        # Lambert
        p4 = '+proj=lcc +lat_1={lat_1} +lat_2={lat_2} ' \
             '+lat_0={lat_0} +lon_0={lon_0} ' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        p4 = p4.format(**pargs)
    elif proj_id == 3:
        # Mercator
        p4 = '+proj=merc +lat_ts={lat_1} ' \
             '+lon_0={center_lon} ' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        p4 = p4.format(**pargs)
    else:
        raise NotImplementedError('WRF proj not implemented yet: '
                                  '{}'.format(proj_id))

    proj = gis.check_crs(p4)
    if proj is None:
        raise RuntimeError('WRF proj not understood: {}'.format(p4))

    # Here we have to accept xarray and netCDF4 datasets
    try:
        nx = len(ds.dimensions['west_east'])
        ny = len(ds.dimensions['south_north'])
    except AttributeError:
        # maybe an xarray dataset
        nx = ds.dims['west_east']
        ny = ds.dims['south_north']
    if hasattr(ds, 'PROJ_ENVI_STRING'):
        # HAR
        x0 = ds.GRID_X00
        y0 = ds.GRID_Y00
    else:
        # Normal WRF file
        e, n = gis.transform_proj(wgs84, proj, cen_lon, cen_lat)
        x0 = -(nx-1) / 2. * dx + e  # DL corner
        y0 = -(ny-1) / 2. * dy + n  # DL corner
    grid = gis.Grid(nxny=(nx, ny), ll_corner=(x0, y0), dxdy=(dx, dy),
                    proj=proj)

    if tmp_check_wrf:
        #  Temporary asserts
        if 'XLONG' in ds.variables:
            # Normal WRF
            mylon, mylat = grid.ll_coordinates
            reflon = ds.variables['XLONG']
            reflat = ds.variables['XLAT']
            if len(reflon.shape) == 3:
                reflon = reflon[0, :, :]
                reflat = reflat[0, :, :]
            assert np.allclose(reflon, mylon, atol=1e-4)
            assert np.allclose(reflat, mylat, atol=1e-4)
        if 'lon' in ds.variables:
            # HAR
            mylon, mylat = grid.ll_coordinates
            reflon = ds.variables['lon']
            reflat = ds.variables['lat']
            if len(reflon.shape) == 3:
                reflon = reflon[0, :, :]
                reflat = reflat[0, :, :]
            assert np.allclose(reflon, mylon, atol=1e-4)
            assert np.allclose(reflat, mylat, atol=1e-4)

    return grid
Example #28
0
def geogrid_simulator(fpath, do_maps=True):
    """Emulates geogrid.exe, which is useful when defining new WRF domains.

    Parameters
    ----------
    fpath: str
       path to a namelist.wps file
    do_maps: bool
       if you want the simulator to return you maps of the grids as well

    Returns
    -------
    (grids, maps) with:
        - grids: a list of Grids corresponding to the domains
          defined in the namelist
        - maps: a list of maps corresponding to the grids (if do_maps==True)
    """

    with open(fpath) as f:
        lines = f.readlines()

    pargs = dict()
    for l in lines:
        s = l.split('=')
        if len(s) < 2:
            continue
        s0 = s[0].strip().upper()
        s1 = list(filter(None, s[1].strip().replace('\n', '').split(',')))

        if s0 == 'PARENT_ID':
            parent_id = [int(s) for s in s1]
        if s0 == 'PARENT_GRID_RATIO':
            parent_ratio = [int(s) for s in s1]
        if s0 == 'I_PARENT_START':
            i_parent_start = [int(s) for s in s1]
        if s0 == 'J_PARENT_START':
            j_parent_start = [int(s) for s in s1]
        if s0 == 'E_WE':
            e_we = [int(s) for s in s1]
        if s0 == 'E_SN':
            e_sn = [int(s) for s in s1]
        if s0 == 'DX':
            dx = float(s1[0])
        if s0 == 'DY':
            dy = float(s1[0])
        if s0 == 'MAP_PROJ':
            map_proj = s1[0].replace("'", '').strip().upper()
        if s0 == 'REF_LAT':
            pargs['lat_0'] = float(s1[0])
        if s0 == 'REF_LON':
            pargs['lon_0'] = float(s1[0])
        if s0 == 'TRUELAT1':
            pargs['lat_1'] = float(s1[0])
        if s0 == 'TRUELAT2':
            pargs['lat_2'] = float(s1[0])

    # define projection
    if map_proj == 'LAMBERT':
        pwrf = '+proj=lcc +lat_1={lat_1} +lat_2={lat_2} ' \
             '+lat_0={lat_0} +lon_0={lon_0} ' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        pwrf = pwrf.format(**pargs)
    elif map_proj == 'MERCATOR':
        pwrf = '+proj=merc +lat_ts={lat_1} ' \
             '+lon_0={lon_0} ' \
             '+x_0=0 +y_0=0 +a=6370000 +b=6370000'
        pwrf = pwrf.format(**pargs)
    else:
        raise NotImplementedError('WRF proj not implemented yet: '
                                  '{}'.format(map_proj))
    pwrf = gis.check_crs(pwrf)

    # get easting and northings from dom center (probably unnecessary here)
    e, n = pyproj.transform(wgs84, pwrf, pargs['lon_0'], pargs['lat_0'])

    # LL corner
    nx, ny = e_we[0]-1, e_sn[0]-1
    x0 = -(nx-1) / 2. * dx + e  # -2 because of staggered grid
    y0 = -(ny-1) / 2. * dy + n

    # parent grid
    grid = gis.Grid(nxny=(nx, ny), ll_corner=(x0, y0), dxdy=(dx, dy),
                    proj=pwrf)

    # child grids
    out = [grid]
    for ips, jps, pid, ratio, we, sn in zip(i_parent_start, j_parent_start,
                                            parent_id, parent_ratio,
                                            e_we, e_sn):
        if ips == 1:
            continue
        ips -= 1
        jps -= 1
        we -= 1
        sn -= 1
        nx = we / ratio
        ny = sn / ratio
        if nx != (we / ratio):
            raise RuntimeError('e_we and ratios are incompatible: '
                               '(e_we - 1) / ratio must be integer!')
        if ny != (sn / ratio):
            raise RuntimeError('e_sn and ratios are incompatible: '
                               '(e_sn - 1) / ratio must be integer!')

        prevgrid = out[pid - 1]
        xx, yy = prevgrid.corner_grid.x_coord, prevgrid.corner_grid.y_coord
        dx = prevgrid.dx / ratio
        dy = prevgrid.dy / ratio
        grid = gis.Grid(nxny=(we, sn),
                        ll_corner=(xx[ips], yy[jps]),
                        dxdy=(dx, dy),
                        pixel_ref='corner',
                        proj=pwrf)
        out.append(grid.center_grid)

    maps = None
    if do_maps:
        from salem import Map
        import shapely.geometry as shpg

        maps = []
        for i, g in enumerate(out):
            m = Map(g)

            for j in range(i+1, len(out)):
                cg = out[j]
                left, right, bottom, top = cg.extent

                s = np.array([(left, bottom), (right, bottom),
                              (right, top), (left, top)])
                l1 = shpg.LinearRing(s)
                m.set_geometry(l1, crs=cg.proj, linewidth=(len(out)-j))

            maps.append(m)

    return out, maps
Example #29
0
    def test_errors(self):
        """Check that errors are occurring"""

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                args = dict(nxny=(3, 3),
                            dxdy=(1, -1),
                            ll_corner=(0, 0),
                            proj=proj)
                self.assertRaises(ValueError, Grid, **args)
                args = dict(nxny=(3, 3),
                            dxdy=(-1, 0),
                            ul_corner=(0, 0),
                            proj=proj)
                self.assertRaises(ValueError, Grid, **args)
                args = dict(nxny=(3, 3), dxdy=(1, 1), proj=proj)
                self.assertRaises(ValueError, Grid, **args)
                args = dict(nxny=(3, -3),
                            dxdy=(1, 1),
                            ll_corner=(0, 0),
                            proj=proj)
                self.assertRaises(ValueError, Grid, **args)
                args = dict(nxny=(3, 3),
                            dxdy=(1, 1),
                            ll_corner=(0, 0),
                            proj=proj,
                            pixel_ref='areyoudumb')
                self.assertRaises(ValueError, Grid, **args)

                args = dict(nxny=(3, 3),
                            dxdy=(1, 1),
                            ll_corner=(0, 0),
                            proj=proj)
                g = Grid(**args)
                self.assertRaises(ValueError, g.transform, 0, 0, crs=None)
                self.assertRaises(ValueError, g.transform, 0, 0, crs='areyou?')
                self.assertRaises(ValueError, g.map_gridded_data,
                                  np.zeros((3, 3)), 'areyou?')
                self.assertRaises(ValueError, g.map_gridded_data, np.zeros(3),
                                  g)
                self.assertRaises(ValueError, g.map_gridded_data,
                                  np.zeros((3, 4)), g)
                self.assertRaises(ValueError,
                                  g.map_gridded_data,
                                  np.zeros((3, 3)),
                                  g,
                                  interp='youare')

        # deprecation warnings
        for proj in projs:
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
                args = dict(nxny=(3, 3),
                            dxdy=(1, -1),
                            corner=(0, 0),
                            proj=proj)
                Grid(**args)
                args = dict(nxny=(3, 3),
                            dxdy=(1, -1),
                            ul_corner=(0, 0),
                            proj=proj)
                Grid(**args)
                args = dict(nxny=(3, 3),
                            dxdy=(1, 1),
                            ll_corner=(0, 0),
                            proj=proj)
                Grid(**args)
                if python_version == 'py3':
                    self.assertEqual(len(w), 3)
Example #30
0
    def test_transform(self):
        """Converting to the grid"""

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:

            args = dict(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=proj)

            g = Grid(**args)
            exp_i, exp_j = np.meshgrid(np.arange(3), np.arange(3))
            r_i, r_j = g.transform(exp_i, exp_j, crs=proj)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            r_i, r_j = g.transform(exp_i, exp_j, crs=g)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            r_i, r_j = g.corner_grid.transform(exp_i, exp_j, crs=proj)
            assert_allclose(exp_i + 0.5, r_i, atol=1e-03)
            assert_allclose(exp_j + 0.5, r_j, atol=1e-03)
            r_i, r_j = g.corner_grid.transform(exp_i, exp_j, crs=g)
            assert_allclose(exp_i + 0.5, r_i, atol=1e-03)
            assert_allclose(exp_j + 0.5, r_j, atol=1e-03)

            args['pixel_ref'] = 'corner'
            g = Grid(**args)
            exp_i, exp_j = np.meshgrid(np.arange(3), np.arange(3))
            r_i, r_j = g.transform(exp_i, exp_j, crs=proj)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            r_i, r_j = g.transform(exp_i, exp_j, crs=g)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            r_i, r_j = g.corner_grid.transform(exp_i, exp_j, crs=proj)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            r_i, r_j = g.corner_grid.transform(exp_i, exp_j, crs=g)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            r_i, r_j = g.center_grid.transform(exp_i, exp_j, crs=proj)
            assert_allclose(exp_i - 0.5, r_i, atol=1e-03)
            assert_allclose(exp_j - 0.5, r_j, atol=1e-03)
            r_i, r_j = g.center_grid.transform(exp_i, exp_j, crs=g)
            assert_allclose(exp_i - 0.5, r_i, atol=1e-03)
            assert_allclose(exp_j - 0.5, r_j, atol=1e-03)
            ex = g.corner_grid.extent
            assert_allclose([0, 3, 0, 3], ex, atol=1e-03)
            assert_allclose(g.center_grid.extent,
                            g.corner_grid.extent,
                            atol=1e-03)

            # Masked
            xi = [-0.6, 0.5, 1.2, 2.9, 3.1, 3.6]
            yi = xi
            ex = [-1, 0, 1, 2, 3, 3]
            ey = ex
            r_i, r_j = g.corner_grid.transform(xi, yi, crs=proj)
            assert_allclose(xi, r_i, atol=1e-03)
            assert_allclose(yi, r_j, atol=1e-03)
            r_i, r_j = g.corner_grid.transform(xi, yi, crs=proj, nearest=True)
            assert_array_equal(ex, r_i)
            assert_array_equal(ey, r_j)
            r_i, r_j = g.center_grid.transform(xi, yi, crs=proj, nearest=True)
            assert_array_equal(ex, r_i)
            assert_array_equal(ey, r_j)
            ex = np.ma.masked_array(ex, mask=[1, 0, 0, 0, 1, 1])
            ey = ex
            r_i, r_j = g.center_grid.transform(xi,
                                               yi,
                                               crs=proj,
                                               nearest=True,
                                               maskout=True)
            assert_array_equal(ex, r_i)
            assert_array_equal(ey, r_j)
            assert_array_equal(ex.mask, r_i.mask)
            assert_array_equal(ey.mask, r_j.mask)
            r_i, r_j = g.corner_grid.transform(xi,
                                               yi,
                                               crs=proj,
                                               nearest=True,
                                               maskout=True)
            assert_array_equal(ex, r_i)
            assert_array_equal(ey, r_j)
            assert_array_equal(ex.mask, r_i.mask)
            assert_array_equal(ey.mask, r_j.mask)

            del args['pixel_ref']
            args['x0y0'] = (0, 0)
            args['dxdy'] = (1, -1)
            g = Grid(**args)
            in_i, in_j = np.meshgrid(np.arange(3), -np.arange(3))
            exp_i, exp_j = np.meshgrid(np.arange(3), np.arange(3))
            r_i, r_j = g.transform(in_i, in_j, crs=proj)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
            in_i, in_j = np.meshgrid(np.arange(3), np.arange(3))
            r_i, r_j = g.transform(in_i, in_j, crs=g)
            assert_allclose(exp_i, r_i, atol=1e-03)
            assert_allclose(exp_j, r_j, atol=1e-03)
Example #31
0
 def test_simple_dataset(self):
     # see if with is working
     with SimpleNcDataSet(get_demo_file('dem_wgs84.nc')) as nc:
         nc = SimpleNcDataSet(get_demo_file('dem_wgs84.nc'))
         grid_from = nc.grid
     self.assertTrue(gis.check_crs(grid_from))
Example #32
0
 def test_simple_dataset(self):
     # see if with is working
     with SimpleNcDataSet(get_demo_file('dem_wgs84.nc')) as nc:
         nc = SimpleNcDataSet(get_demo_file('dem_wgs84.nc'))
         grid_from = nc.grid
     self.assertTrue(gis.check_crs(grid_from))
Example #33
0
    def test_check_crs_log(self):

        assert gis.check_crs('wrong') is None
        with pytest.raises(ValueError):
            gis.check_crs('wrong', raise_on_error=True)
Example #34
0
    def test_constructor(self):

        # It should work exact same for any projection
        projs = [wgs84, gis.check_crs('+init=epsg:26915')]

        for proj in projs:
            args = dict(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            g = Grid(**args)
            self.assertTrue(isinstance(g, Grid))
            self.assertEqual(g.center_grid, g.corner_grid)

            # serialization
            d = g.to_dict()
            rg = Grid.from_dict(d)
            self.assertEqual(g, rg)
            g.to_json('test.json')
            rg = Grid.from_json('test.json')
            os.remove('test.json')
            self.assertEqual(g, rg)

            oargs = dict(nxny=(3, 3), dxdy=(1, 1), x0y0=(0, 0), proj=proj)
            og = Grid(**oargs)
            self.assertEqual(g, og)

            # very simple test
            exp_i, exp_j = np.meshgrid(np.arange(3), np.arange(3))
            i, j = g.ij_coordinates
            assert_allclose(i, exp_i)
            assert_allclose(j, exp_j)

            i, j = g.xy_coordinates
            assert_allclose(i, exp_i)
            assert_allclose(j, exp_j)

            if proj == projs[0]:
                i, j = g.ll_coordinates
                assert_allclose(i, exp_i)
                assert_allclose(j, exp_j)

            args['proj'] = 'dummy'
            self.assertRaises(ValueError, Grid, **args)

            args['proj'] = proj
            args['nxny'] = (1, -1)
            self.assertRaises(ValueError, Grid, **args)
            args['nxny'] = (3, 3)

            args['dxdy'] = (1, -1)
            args['ll_corner'] = args['x0y0']
            del args['x0y0']
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter('always')
                self.assertRaises(ValueError, Grid, **args)
                self.assertEqual(len(w), 1)
            args['x0y0'] = args['ll_corner']
            del args['ll_corner']

            # Center VS corner - multiple times because it was a bug
            assert_allclose(g.center_grid.xy_coordinates, g.xy_coordinates)
            assert_allclose(g.center_grid.center_grid.xy_coordinates,
                            g.xy_coordinates)
            assert_allclose(g.corner_grid.corner_grid.xy_coordinates,
                            g.corner_grid.xy_coordinates)

            ex = g.corner_grid.extent
            assert_allclose([-0.5, 2.5, -0.5, 2.5], ex)
            assert_allclose(g.center_grid.extent, g.corner_grid.extent)

            args['x0y0'] = (0, 0)

            g = Grid(**args)
            self.assertTrue(isinstance(g, Grid))

            oargs = dict(nxny=(3, 3), dxdy=(1, -1), x0y0=(0, 0), proj=proj)
            og = Grid(**oargs)
            self.assertEqual(g, og)

            # serialization
            d = og.to_dict()
            rg = Grid.from_dict(d)
            self.assertEqual(og, rg)

            # The simple test should work here too
            i, j = g.ij_coordinates
            assert_allclose(i, exp_i)
            assert_allclose(j, exp_j)

            # But the lonlats are the other way around:
            exp_x, exp_y = np.meshgrid(np.arange(3), -np.arange(3))
            x, y = g.xy_coordinates
            assert_allclose(x, exp_x)
            assert_allclose(y, exp_y)

            if proj == projs[0]:
                i, j = g.ll_coordinates
                assert_allclose(i, exp_x)
                assert_allclose(j, exp_y)

            # Center VS corner - multiple times because it was a bug
            assert_allclose(g.center_grid.xy_coordinates, g.xy_coordinates)
            assert_allclose(g.center_grid.center_grid.xy_coordinates,
                            g.xy_coordinates)
            assert_allclose(g.corner_grid.corner_grid.xy_coordinates,
                            g.corner_grid.xy_coordinates)

            ex = g.corner_grid.extent
            assert_allclose([-0.5, 2.5, -2.5, 0.5], ex)
            assert_allclose(g.center_grid.extent, g.corner_grid.extent)

            # The equivalents
            g = g.corner_grid
            i, j = g.ij_coordinates
            assert_allclose(i, exp_i)
            assert_allclose(j, exp_j)

            exp_x, exp_y = np.meshgrid(np.arange(3) - 0.5, -np.arange(3) + 0.5)
            x, y = g.xy_coordinates
            assert_allclose(x, exp_x)
            assert_allclose(y, exp_y)

            args = dict(nxny=(3, 2), dxdy=(1, 1), x0y0=(0, 0))
            g = Grid(**args)
            self.assertTrue(isinstance(g, Grid))
            self.assertTrue(g.xy_coordinates[0].shape == (2, 3))
            self.assertTrue(g.xy_coordinates[1].shape == (2, 3))