Beispiel #1
0
 def test_wgs84_invariance(self):
     lats = [-10, 0, 10]
     lons = [-170, 0, 100]
     wgs84_epsg = WGS84_LATLON_EPSG
     xs, ys = utils.reproject_latlons(lats, lons, epsg=wgs84_epsg)
     assert lats == ys
     assert lons == xs
Beispiel #2
0
 def test_only_one_projection_format_can_be_provided(self):
     with pytest.raises(ValueError):
         lats = [-10, 0, 10]
         lons = [-170, 0, 100]
         xs, ys = utils.reproject_latlons(
             lats, lons, epsg=WGS84_LATLON_EPSG, wkt=WGS84_LATLON_WKT
         )
Beispiel #3
0
 def test_utm_conversion(self):
     lats = [10.5]
     lons = [120.8]
     epsg = 32651
     xs, ys = utils.reproject_latlons(lats, lons, epsg=epsg)
     x = 259212
     y = 1161538
     assert np.allclose(x, xs)
     assert np.allclose(y, ys)
Beispiel #4
0
    def location_paths(self, lats, lons):
        """File corresponding to each location.

        Args:
            lats, lons: Lists of locations.

        Returns:
            List of filenames, same length as locations.
        """
        lats = np.asarray(lats)
        lons = np.asarray(lons)

        # Convert to filename projection.
        xs, ys = utils.reproject_latlons(lats, lons, epsg=self.filename_epsg)

        # Find corresponding tile.
        filenames = self._location_to_tile_corner(xs, ys,
                                                  self.filename_tile_size)
        paths = [self._tile_lookup.get(f) for f in filenames]

        return paths
Beispiel #5
0
    def location_paths(self, lats, lons):
        """File corresponding to each location.

        Args:
            lats, lons: Lists of locations.

        Returns:
            List of filenames, same length as locations.
        """
        lats = np.asarray(lats)
        lons = np.asarray(lons)

        # Convert to filename projection.
        xs, ys, = utils.reproject_latlons(lats, lons, epsg=self.filename_epsg)

        # Use to look up.
        filenames = self.__class__._location_to_tile_name(
            xs, ys, self.filename_tile_size, self.ns_fixed_width,
            self.ew_fixed_width)
        paths = [self._tile_lookup.get(f) for f in filenames]

        return paths
Beispiel #6
0
def _get_elevation_from_path(lats, lons, path, interpolation):
    """Read values at locations in a raster.

    Args:
        lats, lons: Arrays of latitudes/longitudes.
        path: GDAL supported raster location.
        interpolation: method name string.

    Returns:
        z_all: List of elevations, same length as lats/lons.
    """
    z_all = []
    interpolation = INTERPOLATION_METHODS.get(interpolation)
    lons = np.asarray(lons)
    lats = np.asarray(lats)

    try:
        with rasterio.open(path) as f:
            if f.crs is None:
                msg = "Dataset has no coordinate reference system."
                msg += f" Check the file '{path}' is a geo raster."
                msg += " Otherwise you'll have to add the crs manually with a tool like gdaltranslate."
                raise InputError(msg)

            try:
                if f.crs.is_epsg_code:
                    xs, ys = utils.reproject_latlons(lats,
                                                     lons,
                                                     epsg=f.crs.to_epsg())
                else:
                    xs, ys = utils.reproject_latlons(lats,
                                                     lons,
                                                     wkt=f.crs.to_wkt())
            except ValueError:
                raise InputError(
                    "Unable to transform latlons to dataset projection.")

            # Check bounds.
            oob_indices = _validate_points_lie_within_raster(
                xs, ys, lats, lons, f.bounds, f.res)
            rows, cols = tuple(f.index(xs, ys, op=_noop))

            # Offset by 0.5 to convert from center coords (provided by
            # f.index) to ul coords (expected by f.read).
            rows = np.array(rows) - 0.5
            cols = np.array(cols) - 0.5

            # Because of floating point precision, indices may slightly exceed
            # array bounds. Because we've checked the locations are within the
            # file bounds,  it's safe to clip to the array shape.
            rows = rows.clip(0, f.height - 1)
            cols = cols.clip(0, f.width - 1)

            # Read the locations, using a 1x1 window. The `masked` kwarg makes
            # rasterio replace NODATA values with np.nan. The `boundless` kwarg
            # forces the windowed elevation to be a 1x1 array, even when it all
            # values are NODATA.
            for i, (row, col) in enumerate(zip(rows, cols)):
                if i in oob_indices:
                    z_all.append(None)
                    continue
                window = rasterio.windows.Window(col, row, 1, 1)
                z_array = f.read(
                    indexes=1,
                    window=window,
                    resampling=interpolation,
                    out_dtype=float,
                    boundless=True,
                    masked=True,
                )
                z = np.ma.filled(z_array, np.nan)[0][0]
                z_all.append(z)

    # Depending on the file format, when rasterio finds an invalid projection
    # of file, it might load it with a None crs, or it might throw an error.
    except rasterio.RasterioIOError as e:
        if "not recognized as a supported file format" in str(e):
            msg = f"Dataset file '{path}' not recognised as a geo raster."
            msg += " Check that the file has projection information with gdalsrsinfo,"
            msg += " and that the file is not corrupt."
            raise InputError(msg)
        raise e

    return z_all
Beispiel #7
0
 def test_no_projection_provided(self):
     with pytest.raises(ValueError):
         lats = [10.5]
         lons = [120.8]
         xs, ys = utils.reproject_latlons(lats, lons)
Beispiel #8
0
 def test_bad_epsg(self):
     with pytest.raises(ValueError):
         lats = [10.5]
         lons = [120.8]
         epsg = 0
         xs, ys = utils.reproject_latlons(lats, lons, epsg=epsg)
Beispiel #9
0
 def test_cache_gets_populated(self):
     lats = [10.5]
     lons = [120.8]
     assert NAD83_WKT not in utils._TRANSFORMER_CACHE
     utils.reproject_latlons(lats, lons, wkt=NAD83_WKT)
     assert NAD83_WKT in utils._TRANSFORMER_CACHE