Exemple #1
0
def test_from_epsg():
    crs_dict = CRS.from_epsg(4326)
    assert crs_dict['init'].lower() == 'epsg:4326'

    # Test with invalid EPSG code
    with pytest.raises(ValueError):
        assert CRS.from_epsg(0)
Exemple #2
0
def test_issue_1446():
    """Confirm resolution of #1446"""
    g = transform_geom(
        CRS.from_epsg(4326),
        CRS.from_epsg(32610),
        {"type": "Point", "coordinates": (-122.51403808499907, 38.06106733107932)},
    )
    assert round(g["coordinates"][0], 1) == 542630.9
    assert round(g["coordinates"][1], 1) == 4212702.1
def main():
    samplefile = r'bxk1-d-ck.idf'
    tiffile = samplefile.replace('.idf', '.geotiff')
    dtype = rasterio.float64
    driver = 'AAIGrid'
    crs = CRS.from_epsg(28992)

    # read data from idf file
    idffile = idfpy.IdfFile(filepath=samplefile, mode='rb')
    geotransform = idffile.geotransform
    height = idffile.header['nrow']
    width = idffile.header['ncol']
    nodata = idffile.header['nodata']
    transform = Affine.from_gdal(*geotransform)

    # write data from idf file to geotiff with rasterio
    profile = {
        'width': width,
        'height': height,
        'count': 1,
        'dtype': dtype,
        'driver': driver,
        'crs': crs,
        'transform': transform,
        'nodata': nodata,
    }

    # the default profile would be sufficient for the example, however the profile dict shows how to make the export
    # profile
    idffile.to_raster(tiffile, **profile)
Exemple #4
0
def test_reproject_init_dest_nodata():
    """No pixels should transfer over"""
    crs = CRS.from_epsg(4326)
    transform = Affine.identity()
    source = np.zeros((1, 100, 100))
    destination = np.ones((1, 100, 100))
    reproject(
        source, destination, src_crs=crs, src_transform=transform,
        dst_crs=crs, dst_transform=transform,
        src_nodata=0, init_dest_nodata=False
    )
    assert destination.all()
Exemple #5
0
def test_linear_units_factor():
    """CRS linear units can be had"""
    assert CRS.from_epsg(3857).linear_units_factor[0] == 'metre'
    assert CRS.from_epsg(3857).linear_units_factor[1] == 1.0
    assert CRS.from_epsg(2261).linear_units_factor[0] == 'US survey foot'
    assert CRS.from_epsg(2261).linear_units_factor[1] == pytest.approx(0.3048006096012192)
    with pytest.raises(CRSError):
        CRS.from_epsg(4326).linear_units_factor
def feature_to_mercator(feature):
    '''Normalize feature and converts coords to 3857.

    Args:
      feature: geojson feature to convert to mercator geometry.
    '''
    # Ref: https://gist.github.com/dnomadb/5cbc116aacc352c7126e779c29ab7abe

    src_crs = CRS.from_epsg(4326)
    dst_crs = CRS.from_epsg(3857)

    geometry = feature['geometry']
    if geometry['type'] == 'Polygon':
        xys = (zip(*part) for part in geometry['coordinates'])
        xys = (list(zip(*transform(src_crs, dst_crs, *xy))) for xy in xys)

        yield {'coordinates': list(xys), 'type': 'Polygon'}

    elif geometry['type'] == 'MultiPolygon':
        for component in geometry['coordinates']:
            xys = (zip(*part) for part in component)
            xys = (list(zip(*transform(src_crs, dst_crs, *xy))) for xy in xys)

            yield {'coordinates': list(xys), 'type': 'Polygon'}
def example_reproject():
    import idfpy

    from matplotlib import pyplot as plt
    from rasterio import Affine
    from rasterio.crs import CRS
    from rasterio.warp import reproject, Resampling
    import numpy as np

    with idfpy.open('bxk1-d-ck.idf') as src:
        a = src.read(masked=True)
        nr, nc = src.header['nrow'], src.header['ncol']
        dx, dy = src.header['dx'], src.header['dy']
        src_transform = Affine.from_gdal(*src.geotransform)

    # define new grid transform (same extent, 10 times resolution)
    dst_transform = Affine.translation(src_transform.c, src_transform.f)
    dst_transform *= Affine.scale(dx / 10., -dy / 10.)

    # define coordinate system (here RD New)
    src_crs = CRS.from_epsg(28992)

    # initialize new data array
    b = np.empty((10*nr, 10*nc))

    # reproject using Rasterio
    reproject(
        source=a,
        destination=b,
        src_transform=src_transform,
        dst_transform=dst_transform,
        src_crs=src_crs,
        dst_crs=src_crs,
        resampling=Resampling.bilinear,
        )

    # result as masked array
    b = np.ma.masked_equal(b, a.fill_value)

    # plot images
    fig, axes = plt.subplots(nrows=2, ncols=1)
    axes[0].imshow(a.filled(np.nan))
    axes[0].set_title('bxk1 original')
    axes[1].imshow(b.filled(np.nan))
    axes[1].set_title('bxk1 resampled')
    plt.show()
Exemple #8
0
    def __init__(self, ul, crs, res, size, desc=None):
        self.ul = ul
        if isinstance(crs, six.string_types):
            self.crs = CRS.from_string(crs)
        elif isinstance(crs, int):
            self.crs = CRS.from_epsg(crs)
        else:
            self.crs = crs

        if not self.crs.is_valid:
            raise ValueError('Could not parse coordinate reference system '
                             'string to a valid projection ({})'.format(crs))

        self.crs_str = self.crs.to_string()
        self.res = res
        self.size = size
        self.desc = desc or 'unnamed'
        self._tiles = {}
Exemple #9
0
    def to_raster(self, fp=None, epsg=28992, driver='AAIGrid'):
        """export Idf to a geotiff"""
        self.check_read()

        if fp is None:
            fp = self.filepath.replace('.idf', '.geotiff')
            logging.warning('no filepath was given, exported to {fp}'.format(fp=fp))

        # set profile
        profile = {
            'width': self.header['ncol'],
            'height': self.header['nrow'],
            'transform': Affine.from_gdal(*self.geotransform),
            'nodata': self.header['nodata'],
            'count': 1,
            'dtype': rasterio.float64,
            'driver': driver,
            'crs': CRS.from_epsg(epsg),
        }

        logging.info('writing to {f:}'.format(f=fp))
        with rasterio.open(fp, 'w', **profile) as dst:
            dst.write(self.masked_data.astype(profile['dtype']), 1)
    def query(self,
              range_subset=['TMEAN'],
              subsets={},
              bbox=[],
              datetime_=None,
              format_='json',
              **kwargs):
        """
        Extract data from collection collection
        :param range_subset: variable
        :param subsets: dict of subset names with lists of ranges
        :param bbox: bounding box [minx,miny,maxx,maxy]
        :param datetime_: temporal (datestamp or extent)
        :param format_: data format of output
        :returns: coverage data as dict of CoverageJSON or native format
        """

        args = {'indexes': None}
        shapes = []

        if all([
                self._coverage_properties['x_axis_label'] in subsets,
                self._coverage_properties['y_axis_label'] in subsets,
                len(bbox) > 0
        ]):
            msg = 'bbox and subsetting by coordinates are exclusive'
            LOGGER.warning(msg)
            raise ProviderQueryError(msg)

        if len(bbox) > 0:
            minx, miny, maxx, maxy = bbox

            crs_src = CRS.from_epsg(4326)
            crs_dest = self._data.crs

            if crs_src == crs_dest:
                LOGGER.debug('source bbox CRS and data CRS are the same')
                shapes = [{
                    'type':
                    'Polygon',
                    'coordinates': [[
                        [minx, miny],
                        [minx, maxy],
                        [maxx, maxy],
                        [maxx, miny],
                        [minx, miny],
                    ]]
                }]
            else:
                LOGGER.debug('source bbox CRS and data CRS are different')
                LOGGER.debug('reprojecting bbox into native coordinates')

                temp_geom_min = {"type": "Point", "coordinates": [minx, miny]}
                temp_geom_max = {"type": "Point", "coordinates": [maxx, maxy]}

                min_coord = rasterio.warp.transform_geom(
                    crs_src, crs_dest, temp_geom_min)
                minx2, miny2 = min_coord['coordinates']

                max_coord = rasterio.warp.transform_geom(
                    crs_src, crs_dest, temp_geom_max)
                maxx2, maxy2 = max_coord['coordinates']

                LOGGER.debug('Source coordinates: {}'.format(
                    [minx, miny, maxx, maxy]))
                LOGGER.debug('Destination coordinates: {}'.format(
                    [minx2, miny2, maxx2, maxy2]))

                shapes = [{
                    'type':
                    'Polygon',
                    'coordinates': [[
                        [minx2, miny2],
                        [minx2, maxy2],
                        [maxx2, maxy2],
                        [maxx2, miny2],
                        [minx2, miny2],
                    ]]
                }]

        elif (self._coverage_properties['x_axis_label'] in subsets
              and self._coverage_properties['y_axis_label'] in subsets):
            LOGGER.debug('Creating spatial subset')

            x = self._coverage_properties['x_axis_label']
            y = self._coverage_properties['y_axis_label']

            shapes = [{
                'type':
                'Polygon',
                'coordinates': [[[subsets[x][0], subsets[y][0]],
                                 [subsets[x][0], subsets[y][1]],
                                 [subsets[x][1], subsets[y][1]],
                                 [subsets[x][1], subsets[y][0]],
                                 [subsets[x][0], subsets[y][0]]]]
            }]

        if range_subset[0].upper() != 'TMEAN':
            var = range_subset[0].upper()
            try:
                self.data = self.get_file_list(var)[-1]
            except IndexError as err:
                LOGGER.error(err)
                raise ProviderQueryError(err)

        if 'season' in subsets:
            seasonal = subsets['season']

            try:
                if len(seasonal) > 1:
                    msg = 'multiple seasons are not supported'
                    LOGGER.error(msg)
                    raise ProviderQueryError(msg)
                elif seasonal != ['DJF']:
                    season = str(seasonal[0])
                    self.data = self.data.replace('DJF', season)

            except Exception as err:
                LOGGER.error(err)
                raise ProviderQueryError(err)

        if datetime_ and 'trend' in self.data:
            msg = 'Datetime is not supported for trend'
            LOGGER.error(msg)
            raise ProviderQueryError(msg)

        date_file_list = False

        if datetime_:
            if '/' not in datetime_:
                if 'month' in self.data:
                    month = search('_{:d}-{:d}.tif', self.data)
                    period = '{}-{}'.format(month[0], str(month[1]).zfill(2))
                    self.data = self.data.replace(str(month), str(datetime_))
                else:
                    period = search('_{:d}.tif', self.data)[0]
                self.data = self.data.replace(str(period), str(datetime_))
            else:
                date_file_list = self.get_file_list(range_subset[0].upper(),
                                                    datetime_)
                args['indexes'] = list(range(1, len(date_file_list) + 1))

        if not os.path.isfile(self.data):
            msg = 'No such file'
            LOGGER.error(msg)
            raise ProviderQueryError(msg)

        with rasterio.open(self.data) as _data:
            LOGGER.debug('Creating output coverage metadata')
            out_meta = _data.meta

            if self.options is not None:
                LOGGER.debug('Adding dataset options')
                for key, value in self.options.items():
                    out_meta[key] = value

            if shapes:  # spatial subset
                try:
                    LOGGER.debug('Clipping data with bbox')
                    out_image, out_transform = rasterio.mask.mask(
                        _data,
                        filled=False,
                        shapes=shapes,
                        crop=True,
                        indexes=None)
                except ValueError as err:
                    LOGGER.error(err)
                    raise ProviderQueryError(err)

                out_meta.update({
                    'driver': self.native_format,
                    'height': out_image.shape[1],
                    'width': out_image.shape[2],
                    'transform': out_transform
                })
            else:  # no spatial subset
                LOGGER.debug('Creating data in memory with band selection')
                out_image = _data.read(indexes=[1])

            if bbox:
                out_meta['bbox'] = [bbox[0], bbox[1], bbox[2], bbox[3]]
            elif shapes:
                out_meta['bbox'] = [
                    subsets[x][0], subsets[y][0], subsets[x][1], subsets[y][1]
                ]
            else:
                out_meta['bbox'] = [
                    _data.bounds.left, _data.bounds.bottom, _data.bounds.right,
                    _data.bounds.top
                ]

            out_meta['units'] = _data.units

            self.filename = self.data.split('/')[-1]
            if 'trend' not in self.data and datetime_:
                self.filename = self.filename.split('_')
                self.filename[-1] = '{}.tif'.format(datetime_.replace(
                    '/', '-'))
                self.filename = '_'.join(self.filename)

            # CovJSON output does not support multiple bands yet
            # Only the first timestep is returned
            if format_ == 'json':
                if date_file_list:
                    err = 'Date range not yet supported for CovJSON output'
                    LOGGER.error(err)
                    raise ProviderQueryError(err)
                else:
                    LOGGER.debug('Creating output in CoverageJSON')
                    out_meta['bands'] = args['indexes']
                    return self.gen_covjson(out_meta, out_image)
            else:
                if date_file_list:
                    LOGGER.debug('Serializing data in memory')
                    with MemoryFile() as memfile:

                        out_meta.update(count=len(date_file_list))

                        with memfile.open(**out_meta) as dest:
                            for id, layer in enumerate(date_file_list,
                                                       start=1):
                                with rasterio.open(layer) as src1:
                                    if shapes:  # spatial subset
                                        try:
                                            LOGGER.debug('Clipping data')
                                            out_image, out_transform = \
                                                rasterio.mask.mask(
                                                    src1,
                                                    filled=False,
                                                    shapes=shapes,
                                                    crop=True,
                                                    indexes=1)
                                        except ValueError as err:
                                            LOGGER.error(err)
                                            raise ProviderQueryError(err)
                                    else:
                                        out_image = src1.read(indexes=1)
                                    dest.write_band(id, out_image)

                        # return data in native format
                        LOGGER.debug('Returning data in native format')
                        return memfile.read()
                else:
                    LOGGER.debug('Serializing data in memory')
                    with MemoryFile() as memfile:
                        with memfile.open(**out_meta) as dest:
                            dest.write(out_image)

                        # return data in native format
                        LOGGER.debug('Returning data in native format')
                        return memfile.read()
Exemple #11
0
def test_linear_units():
    """CRS linear units can be had"""
    assert CRS.from_epsg(3857).linear_units == 'metre'
    assert CRS.from_epsg(2261).linear_units == 'US survey foot'
    assert CRS.from_epsg(4326).linear_units == 'unknown'
Exemple #12
0
def test_to_wkt__env_version():
    with Env(OSR_WKT_FORMAT="WKT2_2018"):
        assert CRS.from_epsg(4326).to_wkt().startswith('GEOGCRS["WGS 84",')
Exemple #13
0
def test_equality_from_epsg(epsg_code):
    assert CRS.from_epsg(epsg_code) == CRS.from_epsg(epsg_code)
Exemple #14
0
def test_crs_hash_unequal():
    """hashes of non-equivalent CRS are not equal"""
    assert hash(CRS.from_epsg(3857)) != hash(CRS.from_epsg(4326))
Exemple #15
0
def test_crs_hash():
    """hashes of equivalent CRS are equal"""
    assert hash(CRS.from_epsg(3857)) == hash(CRS.from_epsg(3857))
Exemple #16
0
# coding=utf-8
from __future__ import absolute_import, division

import re

from marblecutter import render
from rasterio.crs import CRS

from .formats import Skadi

HALF_ARC_SEC = (1 / 3600) * .5
SHAPE = (3601, 3601)
SKADI_CRS = CRS.from_epsg(4326)
SKADI_FORMAT = Skadi()
SKADI_TILE_NAME_PATTERN = re.compile('^([NS])([0-9]{2})([EW])([0-9]{3})$')


def _bbox(x, y):
    return ((x - 180) - HALF_ARC_SEC, (y - 90) - HALF_ARC_SEC,
            (x - 179) + HALF_ARC_SEC, (y - 89) + HALF_ARC_SEC)


def _parse_skadi_tile(tile_name):
    m = SKADI_TILE_NAME_PATTERN.match(tile_name)
    if m:
        y = int(m.group(2))
        x = int(m.group(4))
        if m.group(1) == 'S':
            y = -y
        if m.group(3) == 'W':
            x = -x
Exemple #17
0
def make_tarama_mask(point_list, utm_zone, buff=0, TA_dir='TA'):
    """Generate a mask using the gps coordinates of the captures

    This command follows the execution of tarama, after which a mask is normally
    created interactively by the user

    Args:
        point_list (list): List of (shapely.Point, str) tuples. See ``dir_to_points``
        utm_zone (int): Utm zone of the project
        buffer (float): optional buffer to extend or reduce masked area around
           the convex hull of the point list
        TA_dir (str): tarama dir relative to current directory. Defaults to ``'TA'``
    """
    # Build study area polygon
    src_crs = CRS.from_epsg(4326)
    dst_crs = CRS(proj='utm', zone=utm_zone, ellps='WGS84', units='m')
    feature_list = [mapping(x[0]) for x in point_list]
    feature_list_proj = [
        transform_geom(src_crs, dst_crs, x) for x in feature_list
    ]
    point_list_proj = [shape(x) for x in feature_list_proj]
    study_area = MultiPoint(point_list_proj).convex_hull.buffer(buff)

    # Retrieve Affine transform and shape from TA dir
    root = ET.parse(os.path.join(TA_dir, 'TA_LeChantier.xml')).getroot()
    x_ori, y_ori = [
        float(x) for x in root.find('OriginePlani').text.split(' ')
    ]
    x_res, y_res = [
        float(x) for x in root.find('ResolutionPlani').text.split(' ')
    ]
    arr_shape = tuple(
        reversed([int(x) for x in root.find('NombrePixels').text.split(' ')]))
    aff = Affine(x_res, 0, x_ori, 0, y_res, y_ori)

    # Rasterize study area to template raster
    arr = rasterize(shapes=[(study_area, 255)],
                    out_shape=arr_shape,
                    fill=0,
                    transform=aff,
                    default_value=255,
                    dtype=rasterio.uint8)

    # Write mask to raster
    meta = {
        'driver': 'GTiff',
        'dtype': 'uint8',
        'width': arr_shape[1],
        'height': arr_shape[0],
        'count': 1,
        'crs': dst_crs,
        'transform': aff
    }
    filename = os.path.join(TA_dir, 'TA_LeChantier_Masq.tif')
    with rasterio.open(filename, 'w', **meta) as dst:
        dst.write(arr, 1)

    # Create associated xml file
    xml_content = """<?xml version="1.0" ?>
<FileOriMnt>
     <NameFileMnt>%s</NameFileMnt>
     <NombrePixels>%d %d</NombrePixels>
     <OriginePlani>0 0</OriginePlani>
     <ResolutionPlani>1 1</ResolutionPlani>
     <OrigineAlti>0</OrigineAlti>
     <ResolutionAlti>1</ResolutionAlti>
     <Geometrie>eGeomMNTFaisceauIm1PrCh_Px1D</Geometrie>
</FileOriMnt>""" % (filename, arr_shape[0], arr_shape[1])

    xml_filename = os.path.join(TA_dir, 'TA_LeChantier_Masq.xml')
    with open(xml_filename, 'w') as dst:
        dst.write(xml_content)
Exemple #18
0

def uninvertable_reproject_params():
    return ReprojectParams(
        left=-120,
        bottom=30,
        right=-80,
        top=70,
        width=80,
        height=80,
        src_crs=CRS.from_epsg(4326),
        dst_crs=CRS.from_epsg(26836),
    )


WGS84_crs = CRS.from_epsg(4326)


def test_transform_src_crs_none():
    with pytest.raises(CRSError):
        transform(None, WGS84_crs, [], [])


def test_transform_dst_crs_none():
    with pytest.raises(CRSError):
        transform(WGS84_crs, None, [], [])


def test_transform_bounds_src_crs_none():
    with pytest.raises(CRSError):
        transform_bounds(None, WGS84_crs, 0, 0, 0, 0)
Exemple #19
0
def _write_quicklook(
    rgb: Sequence[Path],
    dest_path: Path,
    resampling: Resampling,
    static_range: Tuple[int, int],
    percentile_range: Tuple[int, int] = (2, 98),
    input_geobox: GridSpec = None,
) -> GridSpec:
    """
    Write an intensity-scaled wgs84 image using the given files as bands.
    """
    if input_geobox is None:
        with rasterio.open(rgb[0]) as ds:
            input_geobox = GridSpec.from_rio(ds)

    out_crs = CRS.from_epsg(4326)
    (
        reprojected_transform,
        reprojected_width,
        reprojected_height,
    ) = calculate_default_transform(
        input_geobox.crs,
        out_crs,
        input_geobox.shape[1],
        input_geobox.shape[0],
        *input_geobox.bounds,
    )
    reproj_grid = GridSpec((reprojected_height, reprojected_width),
                           reprojected_transform,
                           crs=out_crs)
    ql_write_args = dict(
        driver="GTiff",
        dtype="uint8",
        count=len(rgb),
        width=reproj_grid.shape[1],
        height=reproj_grid.shape[0],
        transform=reproj_grid.transform,
        crs=reproj_grid.crs,
        nodata=0,
        tiled="yes",
    )

    # Only set blocksize on larger imagery; enables reduced resolution processing
    if reproj_grid.shape[0] > 512:
        ql_write_args["blockysize"] = 512
    if reproj_grid.shape[1] > 512:
        ql_write_args["blockxsize"] = 512

    with rasterio.open(dest_path, "w", **ql_write_args) as ql_ds:
        ql_ds: DatasetWriter

        # Calculate combined nodata mask
        valid_data_mask = numpy.ones(input_geobox.shape, dtype="bool")
        calculated_range = read_valid_mask_and_value_range(
            valid_data_mask, _iter_images(rgb), percentile_range)

        for band_no, (image, nodata) in enumerate(_iter_images(rgb), start=1):
            reprojected_data = numpy.zeros(reproj_grid.shape,
                                           dtype=numpy.uint8)
            reproject(
                rescale_intensity(
                    image,
                    image_null_mask=~valid_data_mask,
                    in_range=(static_range or calculated_range),
                    out_range=(1, 255),
                    out_dtype=numpy.uint8,
                ),
                reprojected_data,
                src_crs=input_geobox.crs,
                src_transform=input_geobox.transform,
                src_nodata=0,
                dst_crs=reproj_grid.crs,
                dst_nodata=0,
                dst_transform=reproj_grid.transform,
                resampling=resampling,
                num_threads=2,
            )
            ql_ds.write(reprojected_data, band_no)
            del reprojected_data

    return reproj_grid
Exemple #20
0
def test_from_user_input_custom_crs_class():
    """Support comparison to foreign objects that provide to_wkt()"""
    assert CRS.from_user_input(CustomCRS()) == CRS.from_epsg(4326)
Exemple #21
0
def test_equals_different_type(other):
    """Comparison to non-CRS objects is False"""
    assert CRS.from_epsg(4326) != other
Exemple #22
0
def test_environ_patch(gdalenv, monkeypatch):
    """PROJ_LIB is patched when rasterio._crs is imported"""
    monkeypatch.delenv('GDAL_DATA', raising=False)
    monkeypatch.delenv('PROJ_LIB', raising=False)
    with env_ctx_if_needed():
        assert CRS.from_epsg(4326) != CRS(units='m', proj='aeqd', ellps='WGS84', datum='WGS84', lat_0=-17.0, lon_0=-44.0)
Exemple #23
0
# coding=utf-8
from __future__ import absolute_import

import numpy as np

from rasterio import warp
from rasterio.crs import CRS

from .. import Bounds, PixelCollection, crop, get_extent, get_resolution

WGS84_CRS = CRS.from_epsg(4326)


class Transformation:
    buffer = 0

    def __init__(self, collar=0):
        self.collar = int(collar)

    def expand(self, bounds, shape):
        buffer = self.buffer
        collar = self.collar
        effective_buffer = buffer + collar

        if effective_buffer == 0:
            return bounds, shape, (0, 0, 0, 0)

        resolution = get_resolution(bounds, shape)

        # apply buffer
        bounds_orig = bounds
Exemple #24
0
        meta = inds.meta.copy()
        rasterio.warp.transform(crs0, inds.crs, [y], [x])
        a = rasterio.warp.transform(crs0, inds.crs, [y], [x])
        xPixel, yPixel = pixel_location = inv_transform * (a[0][0], a[1][0])
        print(pixel_location)
        # print(count_sliding_window(inds.read(1)))
        for window, transform in get_tiles(inds, tile_width, tile_height):
            print(window)
            meta['transform'] = transform
            meta['width'], meta['height'] = window.width, window.height
            outpath = os.path.join(
                out_folder,
                output_filename.format(int(window.col_off),
                                       int(window.row_off)))
            if ((xPixel > window.col_off) &
                (xPixel < window.col_off + window.width) &
                (yPixel > window.row_off) &
                (yPixel < window.row_off + window.height)):
                with rio.open(outpath, 'w', **meta) as outds:
                    outds.write(inds.read(window=window))


crs0 = CRS.from_epsg(4326)
for folder in os.listdir(queryDir):
    print(folder)
    imgName, xs, ys = get_info(folder)
    for x, y in zip(xs, ys):
        selectInterestArea(imgName + '.jp2', x, y)

# selectInterestArea('T47PQQ_20200506T033529_TCI.jp2',12.679944,101.005028)
def test_issue1131():
    """Confirm that we don't run out of memory"""
    transform, w, h = calculate_default_transform(CRS.from_epsg(4326), CRS.from_epsg(3857), 455880, 454450, 13.0460235139, 42.6925552354, 13.2511695428, 42.8970561511)
    assert (w, h) == (381595, 518398)
def test_failure_point_shp(tmp_path):
    """
    Ensure that hedley_2005() raises an Exception if
    the shapefile does not contain any Polygon geometries
    """
    g = deglint.GlintCorr(odc_meta_file, sub_product)

    hedley_dir = tmp_path / "HEDLEY"
    hedley_dir.mkdir()

    # ------------------------------------------- #
    # Test 1: create Points and save to shapefile #
    # ------------------------------------------- #
    point_shp = hedley_dir / "aus_capital_cities.shp"
    # Name, lon (deg. East), lat (deg. North)
    capital_arr = [
        ["PER", 115.8605, -31.9505],
        ["DAR", 130.8456, -12.4634],
        ["ADE", 138.6007, -34.9285],
        ["CAN", 149.1300, -35.2809],
        ["SYD", 151.2093, -33.8688],
        ["BRI", 153.0251, -27.4698],
        ["HOB", 147.3272, -42.8821],
        ["MEL", 144.9631, -37.8136],
    ]
    schema = {"geometry": "Point", "properties": {"name": "str"}}

    with collection(
            point_shp,
            mode="w",
            driver="ESRI Shapefile",
            schema=schema,
            crs=CRS.from_epsg(4326),
    ) as shp:
        for cap in capital_arr:
            shp.write({
                "properties": {
                    "name": cap[0]
                },
                "geometry": mapping(Point(cap[1], cap[2])),
            })
    with pytest.raises(Exception) as excinfo:
        g.hedley_2005(
            vis_bands=["3"],
            corr_band="6",
            roi_shpfile=point_shp,
            odir=hedley_dir,
            water_val=5,
            plot=False,
        )
    assert "input shapefile does not have any 'Polygon' geometry" in str(
        excinfo)

    # ------------------------------------------------- #
    # Test 2: create a LineString and save to shapefile #
    # ------------------------------------------------- #
    linestr_shp = hedley_dir / "Perth_to_Canberra_line.shp"

    # Name, lon (deg. East), lat (deg. North)
    perth = [115.8605, -31.9505]
    canbr = [149.1300, -35.2809]

    gls = LineString([Point(perth[0], perth[1]), Point(canbr[0], canbr[1])])

    schema = {"geometry": "LineString", "properties": {"name": "str"}}
    with collection(
            linestr_shp,
            mode="w",
            driver="ESRI Shapefile",
            schema=schema,
            crs=CRS.from_epsg(4326),
    ) as shp:
        shp.write({
            "properties": {
                "name": "Perth_to_Canberra"
            },
            "geometry": mapping(gls),
        })
    with pytest.raises(Exception) as excinfo:
        g.hedley_2005(
            vis_bands=["3"],
            corr_band="6",
            roi_shpfile=linestr_shp,
            odir=hedley_dir,
            water_val=5,
            plot=False,
        )
    assert "input shapefile does not have any 'Polygon' geometry" in str(
        excinfo)
Exemple #27
0
def test_from_epsg_overflow():
    with pytest.raises(CRSError):
        # the argument is large enough to cause an overflow in Cython
        CRS.from_epsg(1111111111111111111111)
Exemple #28
0
    def __init__(self,
                 array,
                 bands,
                 crs,
                 transform,
                 nodataval,
                 driver="GTiff",
                 rio_ds=None):
        import rasterio
        import affine
        from rasterio.crs import CRS

        self._array = array
        self._bands = bands

        meta = {"driver": driver, "nodata": nodataval}

        # create metadata dictionary
        if array.dtype in Raster.FLOAT32:
            dtype = "float32"
        elif array.dtype in Raster.FLOAT64:
            dtype = "float64"
        elif array.dtype in Raster.INT8:
            dtype = "int8"
        elif array.dtype in Raster.INT16:
            dtype = "int16"
        elif array.dtype in Raster.INT32:
            dtype = "int32"
        elif array.dtype in Raster.INT64:
            dtype = "int64"
        else:
            raise TypeError("dtype cannot be determined from Raster")

        meta['dtype'] = dtype

        if isinstance(crs, CRS):
            pass
        elif isinstance(crs, int):
            crs = CRS.from_epsg(crs)
        elif isinstance(crs, str):
            crs = CRS.from_string(crs)
        else:
            TypeError("crs type not understood, provide an epsg or proj4")

        meta['crs'] = crs

        count, height, width = array.shape
        meta['count'] = count
        meta['height'] = height
        meta['width'] = width

        if not isinstance(transform, affine.Affine):
            raise TypeError("Transform must be defined by an Affine object")

        meta['transform'] = transform

        self._meta = meta
        self._dataset = None
        self.__arr_dict = {
            self._bands[b]: arr
            for b, arr in enumerate(self._array)
        }

        self.__xcenters = None
        self.__ycenters = None

        if isinstance(rio_ds, rasterio.io.DatasetReader):
            self._dataset = rio_ds
Exemple #29
0
def test_to_wkt__version(version):
    assert CRS.from_epsg(4326).to_wkt(
        version=version).startswith('GEOGCRS["WGS 84",')
Exemple #30
0
def ex_crs(request):
    return CRS.from_epsg(request.param)
Exemple #31
0
def test_to_crs_int(code):
    assert convert.to_crs(code) == CRS.from_epsg(code)
Exemple #32
0
def test_to_crs_dict():
    crs = CRS.from_epsg(4326)
    assert convert.to_crs(dict(crs)) == crs
Exemple #33
0
def test_crs_copy():
    """CRS can be copied"""
    assert copy.copy(CRS.from_epsg(3857)).wkt.startswith(
        'PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"'
    )
Exemple #34
0
def test_to_crs_CRS():
    # should just return same object
    crs = CRS.from_epsg(4326)
    assert convert.to_crs(crs) is crs
Exemple #35
0
 def to_wkt(self):
     return CRS.from_epsg(4326).to_wkt()
Exemple #36
0
from haversine import haversine
from rasterio import transform, warp, windows
from rasterio._err import CPLE_OutOfMemoryError
from rasterio.crs import CRS
from rasterio.enums import ColorInterp, MaskFlags
from rasterio.features import geometry_mask
from rasterio.transform import Affine, from_bounds
from rasterio.vrt import WarpedVRT
from rasterio.warp import Resampling, transform_geom

from . import mosaic
from .stats import Timer
from .utils import Bounds, PixelCollection

EARTH_RADIUS = 6378137
WEB_MERCATOR_CRS = CRS.from_epsg(3857)
WGS84_CRS = CRS.from_epsg(4326)
LOG = logging.getLogger(__name__)

EXTENTS = {
    str(WEB_MERCATOR_CRS): (
        -math.pi * EARTH_RADIUS,
        -math.pi * EARTH_RADIUS,
        math.pi * EARTH_RADIUS,
        math.pi * EARTH_RADIUS,
    ),
    str(WGS84_CRS): (
        math.degrees(-math.pi),
        math.degrees(-math.pi / 2),
        math.degrees(math.pi),
        math.degrees(math.pi / 2),
Exemple #37
0
def test_equality_from_epsg(epsg_code):
    assert CRS.from_epsg(epsg_code) == CRS.from_epsg(epsg_code)
Exemple #38
0
def _describe_file(filepath):
    """
    Helper function to describe a geospatial data
    First checks if a sidecar mcf file is available, if so uses that
    if not, script will parse the file to retrieve some info from the file

    :param filepath: path to file

    :returns: `dict` of GeoJSON item
    """

    content = {
        'bbox': None,
        'geometry': None,
        'properties': {}
    }

    mcf_file = '{}.yml'.format(os.path.splitext(filepath)[0])

    if os.path.isfile(mcf_file):
        try:
            from pygeometa.core import read_mcf, MCFReadError
            from pygeometa.schemas.stac import STACItemOutputSchema

            md = read_mcf(mcf_file)
            stacjson = STACItemOutputSchema.write(STACItemOutputSchema, md)
            stacdata = loads(stacjson)
            for k, v in stacdata.items():
                content[k] = v
        except ImportError:
            LOGGER.debug('pygeometa not found')
        except MCFReadError as err:
            LOGGER.warning('MCF error: {}'.format(err))
    else:
        LOGGER.debug('No mcf found at: {}'.format(mcf_file))

    if content['geometry'] is None and content['bbox'] is None:
        try:
            import rasterio
            from rasterio.crs import CRS
            from rasterio.warp import transform_bounds
        except ImportError as err:
            LOGGER.warning('rasterio not found')
            LOGGER.warning(err)
            return content

        try:
            import fiona
        except ImportError as err:
            LOGGER.warning('fiona not found')
            LOGGER.warning(err)
            return content

        try:  # raster
            LOGGER.debug('Testing raster data detection')
            d = rasterio.open(filepath)
            content['bbox'] = [
                d.bounds.left,
                d.bounds.bottom,
                d.bounds.right,
                d.bounds.top
            ]
            content['geometry'] = {
                'type': 'Polygon',
                'coordinates': [[
                    [d.bounds.left, d.bounds.bottom],
                    [d.bounds.left, d.bounds.top],
                    [d.bounds.right, d.bounds.top],
                    [d.bounds.right, d.bounds.bottom],
                    [d.bounds.left, d.bounds.bottom]
                ]]
            }
            for k, v in d.tags(1).items():
                content['properties'][k] = v
        except rasterio.errors.RasterioIOError:
            LOGGER.debug('Testing vector data detection')
            d = fiona.open(filepath)
            scrs = CRS(d.crs)
            if scrs.to_epsg() is not None and scrs.to_epsg() != 4326:
                tcrs = CRS.from_epsg(4326)
                bnds = transform_bounds(scrs, tcrs,
                                        d.bounds[0], d.bounds[1],
                                        d.bounds[2], d.bounds[3])
                content['properties']['projection'] = scrs.to_epsg()
            else:
                bnds = d.bounds

            if d.schema['geometry'] not in [None, 'None']:
                content['bbox'] = [
                    bnds[0],
                    bnds[1],
                    bnds[2],
                    bnds[3]
                ]
                content['geometry'] = {
                    'type': 'Polygon',
                    'coordinates': [[
                        [bnds[0], bnds[1]],
                        [bnds[0], bnds[3]],
                        [bnds[2], bnds[3]],
                        [bnds[2], bnds[1]],
                        [bnds[0], bnds[1]]
                    ]]
                }

            for k, v in d.schema['properties'].items():
                content['properties'][k] = v

        if d.driver == 'ESRI Shapefile':
            id_ = os.path.splitext(os.path.basename(filepath))[0]
            content['assets'] = {}
            for suffix in ['shx', 'dbf', 'prj', 'shp.xml']:
                content['assets'][suffix] = {
                    'href': './{}.{}'.format(id_, suffix)
                }
    return content
Exemple #39
0
def test_linear_units():
    """CRS linear units can be had"""
    assert CRS.from_epsg(3857).linear_units == 'metre'
    assert CRS.from_epsg(2261).linear_units == 'US survey foot'
    assert CRS.from_epsg(4326).linear_units == 'unknown'
Exemple #40
0
TILE_3_NAME = "world.tif"
TILE_3_PATH = os.path.join(os.path.dirname(__file__), "fixtures", TILE_3_NAME)
TILE_4_NAME = "01N_001E.tif"
TILE_4_PATH = os.path.join(os.path.dirname(__file__), "fixtures", TILE_4_NAME)


########### World.tif
geotransform = (-180.0, 1.0, 0.0, 90.0, 0.0, -1.0)
data = np.random.randint(20, size=(180, 360)).astype("uint8")
profile = {
    "driver": "GTiff",
    "height": 180,
    "width": 360,
    "count": 1,
    "dtype": "uint8",
    "crs": CRS.from_epsg(4326),
    "transform": Affine.from_gdal(*geotransform),
}

with rasterio.open(TILE_3_PATH, "w", **profile) as dst:
    dst.write(data, 1)

############ 01N_001E.tif
geotransform = (1.0, 0.00025, 0.0, 1.0, 0.0, -0.00025)
data = np.random.randint(5, size=(4000, 4000)).astype("uint8")
profile = {
    "driver": "GTiff",
    "height": 4000,
    "width": 4000,
    "count": 1,
    "dtype": "uint8",
Exemple #41
0
def test_crs_copy():
    """CRS can be copied"""
    assert copy.copy(CRS.from_epsg(3857)).wkt.startswith('PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"')
Exemple #42
0
def clip(
    ctx,
    files,
    output,
    bounds,
    like,
    driver,
    nodata,
    projection,
    overwrite,
    creation_options,
    with_complement,
):
    """Clips a raster using projected or geographic bounds.

    The values of --bounds are presumed to be from the coordinate
    reference system of the input dataset unless the --geographic option
    is used, in which case the values may be longitude and latitude
    bounds. Either JSON, for example "[west, south, east, north]", or
    plain text "west south east north" representations of a bounding box
    are acceptable.

    If using --like, bounds will automatically be transformed to match
    the coordinate reference system of the input.

    Datasets with non-rectilinear geo transforms (i.e. with rotation
    and/or shear) may not be cropped using this command. They must be
    processed with rio-warp.

    Examples
    --------
    $ rio clip input.tif output.tif --bounds xmin ymin xmax ymax

    $ rio clip input.tif output.tif --like template.tif

    """
    from rasterio.warp import transform_bounds

    with ctx.obj['env']:

        output, files = resolve_inout(files=files, output=output, overwrite=overwrite)
        input = files[0]

        with rasterio.open(input) as src:
            if not src.transform.is_rectilinear:
                raise click.BadParameter(
                    "Non-rectilinear rasters (i.e. with rotation or shear) cannot be clipped"
                )

            if bounds:
                if projection == 'geographic':
                    bounds = transform_bounds(CRS.from_epsg(4326), src.crs, *bounds)
                if disjoint_bounds(bounds, src.bounds):
                    raise click.BadParameter('must overlap the extent of '
                                             'the input raster',
                                             param='--bounds',
                                             param_hint='--bounds')
            elif like:
                with rasterio.open(like) as template_ds:
                    bounds = template_ds.bounds
                    if template_ds.crs != src.crs:
                        bounds = transform_bounds(template_ds.crs, src.crs,
                                                  *bounds)

                    if disjoint_bounds(bounds, src.bounds):
                        raise click.BadParameter('must overlap the extent of '
                                                 'the input raster',
                                                 param='--like',
                                                 param_hint='--like')

            else:
                raise click.UsageError('--bounds or --like required')

            bounds_window = src.window(*bounds)

            if not with_complement:
                bounds_window = bounds_window.intersection(
                    Window(0, 0, src.width, src.height)
                )

            # Get the window with integer height
            # and width that contains the bounds window.
            out_window = bounds_window.round_lengths()

            height = int(out_window.height)
            width = int(out_window.width)

            out_kwargs = src.profile

            if driver:
                out_kwargs["driver"] = driver

            if nodata is not None:
                out_kwargs["nodata"] = nodata

            out_kwargs.update({
                'height': height,
                'width': width,
                'transform': src.window_transform(out_window)})

            out_kwargs.update(**creation_options)

            if "blockxsize" in out_kwargs and int(out_kwargs["blockxsize"]) > width:
                del out_kwargs["blockxsize"]
                logger.warning(
                    "Blockxsize removed from creation options to accomodate small output width"
                )
            if "blockysize" in out_kwargs and int(out_kwargs["blockysize"]) > height:
                del out_kwargs["blockysize"]
                logger.warning(
                    "Blockysize removed from creation options to accomodate small output height"
                )

            with rasterio.open(output, "w", **out_kwargs) as out:
                out.write(
                    src.read(
                        window=out_window,
                        out_shape=(src.count, height, width),
                        boundless=True,
                        masked=True,
                    )
                )

                if MaskFlags.per_dataset in src.mask_flag_enums[0]:
                    out.write_mask(
                        src.read_masks(
                            window=out_window,
                            out_shape=(src.count, height, width),
                            boundless=True,
                        )[0]
                    )
Exemple #43
0
def test_crs_hash_unequal():
    """hashes of non-equivalent CRS are not equal"""
    assert hash(CRS.from_epsg(3857)) != hash(CRS.from_epsg(4326))
Exemple #44
0
@pytest.mark.parametrize("other", ["", 4.2, 0])
def test_equals_different_type(other):
    """Comparison to non-CRS objects is False"""
    assert CRS.from_epsg(4326) != other


def test_from_user_input_custom_crs_class():
    """Support comparison to foreign objects that provide to_wkt()"""
    assert CRS.from_user_input(CustomCRS()) == CRS.from_epsg(4326)


@pytest.mark.parametrize(
    "crs_obj",
    [
        CRS.from_user_input("http://www.opengis.net/def/crs/EPSG/0/4326"),
        CRS.from_epsg(4326),
    ],
)
def test_epsg_treats_as_latlong(crs_obj):
    """EPSG treats this CRS as lat, lon (see also PR #1943)."""
    assert epsg_treats_as_latlong(crs_obj)


@pytest.mark.parametrize("crs_obj", [
    CRS.from_user_input("http://www.opengis.net/def/crs/OGC/1.3/CRS84"),
    CRS.from_user_input("http://www.opengis.net/def/crs/EPSG/0/2193"),
    CRS.from_epsg(3857),
    CRS.from_epsg(32618),
])
def test_epsg_treats_as_latlong_not(crs_obj):
    """EPSG does not treat this CRS as lat, lon (see also PR #1943)."""
Exemple #45
0
def _to_crs_epsg(value):
    return CRS.from_epsg(value)
Exemple #46
0
def test_crs_hash():
    """hashes of equivalent CRS are equal"""
    assert hash(CRS.from_epsg(3857)) == hash(CRS.from_epsg(3857))