Beispiel #1
0
def write_quicklook(raster, filename, downfactor=4):
    """
    write a JPG preview
    :param raster: raster (rasterio image)
    :param filename: path to the output preview
    :param downfactor: downsampling factor
    """
    profile = raster.profile

    # update size in profile
    newwidth = int(raster.width / downfactor)
    newheight = int(raster.height / downfactor)

    try:
        aff = raster.affine
        newaffine = rasterio.Affine(aff.a / downfactor, aff.b, aff.c, aff.d,
                                    aff.e / downfactor, aff.f)

        profile.update(dtype=rasterio.uint8,
                       count=3,
                       compress='lzw',
                       driver='JPEG',
                       width=newwidth,
                       height=newheight,
                       transform=newaffine,
                       affine=newaffine)

    # depend on rasterio version
    except AttributeError:
        aff = raster.transform
        newaffine = rasterio.Affine(aff.a / downfactor, aff.b, aff.c, aff.d,
                                    aff.e / downfactor, aff.f)

        profile.update(dtype=rasterio.uint8,
                       count=3,
                       compress='lzw',
                       driver='JPEG',
                       width=newwidth,
                       height=newheight,
                       transform=newaffine)

    # write raster
    with rasterio.open(filename, 'w', **profile) as dst:
        for n in range(3):
            if raster.count == 1:
                band = raster.read(1,
                                   out_shape=(int(raster.height / downfactor),
                                              int(raster.width / downfactor)))
            else:
                band = raster.read(n + 1,
                                   out_shape=(int(raster.height / downfactor),
                                              int(raster.width / downfactor)))

            band = normalize(band)
            dst.write(band, n + 1)
def test_data():
    test_data_pan = np.array([(np.random.rand(60, 60) * 255).astype(np.uint8)])
    test_data_pan = test_data_pan[0]
    test_data_rgb = np.array([(np.random.rand(30, 30) * 255).astype(np.uint8)
                              for i in range(3)])
    test_data_src_aff = rasterio.Affine(2.0, 0.0, 0.0, 0.0, -2.0, 0.0)
    test_data_src_crs = {'init': 'EPSG:3857'}
    test_data_dst_aff = rasterio.Affine(1.0, 0.0, 0.0, 0.0, -1.0, 0.0)
    test_data_dst_crs = {'init': 'EPSG:3857'}

    return test_data_pan, test_data_rgb, test_data_src_aff,\
        test_data_src_crs, test_data_dst_aff, test_data_dst_crs
Beispiel #3
0
    def read_hdf5(self, file_data):
        """Read centroids attributes from hdf5.

        Parameters
        ----------
        file_data : str or h5
            If string, path to read data. If h5 object, the datasets will be read from there.
        """
        if isinstance(file_data, (str, Path)):
            LOGGER.info('Reading %s', file_data)
            data = h5py.File(file_data, 'r')
        else:
            data = file_data
        self.clear()
        crs = DEF_CRS
        if data.get('crs'):
            crs = u_coord.to_crs_user_input(data.get('crs')[0])
        if data.get('lat') and data.get('lat').size:
            self.set_lat_lon(np.array(data.get('lat')), np.array(data.get('lon')), crs)
        elif data.get('latitude') and data.get('latitude').size:
            self.set_lat_lon(np.array(data.get('latitude')), np.array(data.get('longitude')), crs)
        else:
            centr_meta = data.get('meta')
            self.meta['crs'] = crs
            for key, value in centr_meta.items():
                if key != 'transform':
                    self.meta[key] = value[0]
                else:
                    self.meta[key] = rasterio.Affine(*value)
        for centr_name in data.keys():
            if centr_name not in ('crs', 'lat', 'lon', 'meta'):
                setattr(self, centr_name, np.array(data.get(centr_name)))
        if isinstance(file_data, str):
            data.close()
Beispiel #4
0
    def set_raster_from_pix_bounds(self, xf_lat, xo_lon, d_lat, d_lon, n_lat,
                                   n_lon, crs=DEF_CRS):
        """Set raster metadata (meta attribute) from pixel border data

        Parameters
        ----------
        xf_lat : float
            upper latitude (top)
        xo_lon : float
            left longitude
        d_lat : float
            latitude step (negative)
        d_lon : float
            longitude step (positive)
        n_lat : int
            number of latitude points
        n_lon : int
            number of longitude points
        crs : dict() or rasterio.crs.CRS, optional
            CRS. Default: DEF_CRS
        """
        self.__init__()
        self.meta = {
            'dtype': 'float32',
            'width': n_lon,
            'height': n_lat,
            'crs': crs,
            'transform': rasterio.Affine(d_lon, 0.0, xo_lon, 0.0, d_lat, xf_lat),
        }
def calculate_coverage(overlaps, dimensions, bounds):

    # get dimensions of coverage raster
    mminx, mminy, mmaxx, mmaxy = bounds

    y_count, x_count = dimensions

    # determine pixel width and height for transform
    width = (mmaxx - mminx) / x_count
    height = (mminy - mmaxy) / y_count  # should be negative

    # Affine(a, b, c, d, e, f) where:
    # a = width of a pixel
    # b = row rotation (typically zero)
    # c = x-coordinate of the upper-left corner of the upper-left pixel
    # d = column rotation (typically zero)
    # e = height of a pixel (typically negative)
    # f = y-coordinate of the of the upper-left corner of the upper-left pixel
    # ref: http://www.perrygeo.com/python-affine-transforms.html
    transform = rasterio.Affine(width, 0, mminx, 0, height, mmaxy)

    coverage = np.zeros(dimensions, dtype=np.uint16)
    for overlap in overlaps:
        if not overlap.is_empty:
            # rasterize overlap vector, transforming to coverage raster
            # pixels inside overlap have a value of 1, others have a value of 0
            overlap_raster = rfeatures.rasterize([sgeom.mapping(overlap)],
                                                 fill=0,
                                                 default_value=1,
                                                 out_shape=dimensions,
                                                 transform=transform)

            # add overlap raster to coverage raster
            coverage += overlap_raster
    return coverage
Beispiel #6
0
    def __init__(self, config, root_dir, threshold=100):
        self.path = root_dir
        self.config = config
        self.overlap = config['overlap']
        self.window = config['window']
        self.transform = get_transform(config['transform'], config['resize'])
        self.identity = rasterio.Affine(1, 0, 0, 0, 1, 0)
        self.phase = config['phase']
        self.cache_dir = config['cache_dir']
        if self.phase == 'train' or self.phase == 'val':
            self.csv = pd.read_csv(self.path + '/train.csv', index_col=[0])
            self.threshold = threshold
        else:
            self.csv = None
        self.x, self.y,self.masks,self.slices, self.files  = [], [], [], [], []
        self.shape = {}
        if self.cache_dir:
            if self.check_cache():
                self.load_cache()
            else:
                os.system(f'mkdir -p {self.cache_dir}')
                self.build_cache()
        else:
            self.build_slices()

        self.len = len(self.slices)
        self.as_tensor = T.Compose([
            T.ToTensor(),
            T.Normalize([0.625, 0.448, 0.688], [0.131, 0.177, 0.101]),
        ])
def crop(src_img, src_affine, n):
    """Crop a given image from each direction according to a given number of
    pixels. Also calculate a new Affine transformation.

    Parameters
    ----------
    src_img : numpy 2d array
        Source image as a 2d numpy array.
    src_affine : Affine
        Source Affine object.
    n : int
        Number of pixels cropped from each direction.

    Returns
    -------
    dst_img : numpy 2d array
        Output cropped image.
    dst_affine : Affine
        Updated affine.
    """
    nrows, ncols = src_img.shape
    dst_img = src_img[n:nrows - n, n:ncols - n]
    a, b, c, d, e, f, _, _, _ = src_affine
    c += a * n
    f -= a * n
    dst_affine = rasterio.Affine(a, b, c, d, e, f)
    return dst_img, dst_affine
Beispiel #8
0
    def export_prediction_to_tif(self, out_file_path, prediction):
        """

        :param out_file_path:
        :param prediction: a np-array where second dim indicate n-channels
        :return:
        """

        #Check if map-info is available
        if self.map_info is None:
            class MissingMapInfoException(Exception): pass
            raise MissingMapInfoException()

        #Compute geo-meta data
        geo = self.map_info['transform']
        transf = rasterio.Affine(geo[1], geo[2], geo[0], geo[4], geo[5], geo[3])
        crs = {'init': self.map_info['cs_code']}

        #Write to file
        with rasterio.open(out_file_path, "w", driver="GTiff", compress="lzw", bigtiff="YES",
                           height=prediction.shape[0], width=prediction.shape[1], count=prediction.shape[2],
                           dtype=prediction.dtype,
                           crs=crs, transform=transf) as out_file:

            for band_no in range(0, prediction.shape[2]):
                out_file.write(prediction[:,:,band_no], band_no + 1)
        print('Exported predictions to', out_file_path)
Beispiel #9
0
def write_geotiff_prediction(image, jsonFile, aoi):
    with open(jsonFile, ) as file:
        mixer = json.load(file)

        transform = mixer['projection']['affine']['doubleMatrix']
        crs = mixer['projection']['crs']
        ppr = mixer['patchesPerRow']
        tp = mixer['totalPatches']
        rows = int(tp / ppr)

    if image.ndim < 3:
        image = np.expand_dims(image, axis=-1)

    affine = rio.Affine(transform[0], transform[1], transform[2], transform[3],
                        transform[4], transform[5])

    with rio.open(f'{aoi}.tif',
                  'w',
                  driver='GTiff',
                  width=image.shape[1],
                  height=image.shape[0],
                  count=image.shape[2],
                  dtype=image.dtype,
                  crs=crs,
                  transform=affine) as dst:
        dst.write(np.transpose(image, (2, 0, 1)))
def mask_to_polygons_layer(mask, eopatch, tolerance):

    all_polygons = []
    bbox = eopatch.bbox
    size_x = eopatch.meta_info['size_x']
    size_y = eopatch.meta_info['size_y']

    vx = bbox.min_x
    vy = bbox.max_y
    cx = (bbox.max_x - bbox.min_x) / size_x
    cy = (bbox.max_y - bbox.min_y) / size_y

    for shape, value in features.shapes(mask.astype(np.int16),
                                        mask=(mask == 1),
                                        transform=rasterio.Affine(
                                            cx, 0.0, vx, 0.0, -cy, vy)):
        return shapely.geometry.shape(shape).simplify(tolerance, False)
        all_polygons.append(shapely.geometry.shape(shape))

    all_polygons = shapely.geometry.MultiPolygon(all_polygons)
    if not all_polygons.is_valid:
        all_polygons = all_polygons.buffer(0)
        if all_polygons.type == 'Polygon':
            all_polygons = shapely.geometry.MultiPolygon([all_polygons])
    return all_polygons
Beispiel #11
0
def data_array_to_rasterio(xr_data, output_file=None, tag=None, fmt='GTiff', metadata=None):
    """Write xarray DataArray to file using rasterio.
    """
    extensions = {
        'GTiff': '.tif',
    }
    output_file = output_file or os.path.join(whitebox_temp_dir, str(tag) + extensions[fmt])
    metadata = metadata or dict()

    shape = xr_data.shape
    if len(shape) == 2:
        shape = (1, *shape)

    count, height, width = shape
    bands = 1 if count == 1 else np.arange(count) + 1

    metadata.update(
        driver=fmt,
        height=height,
        width=width,
        dtype=str(xr_data.dtype),
        count=count,
    )

    if 'transform' in xr_data.attrs:
        metadata['transform'] = rasterio.Affine(*xr_data.attrs['transform'][:6])

    if 'crs' in xr_data.attrs:
        metadata['crs'] = rasterio.crs.CRS.from_string(xr_data.attrs['crs'])

    with rasterio.open(output_file, 'w', **metadata) as output:
        output.write(xr_data.values.astype(metadata['dtype']), bands)

    return output_file
Beispiel #12
0
def pad_extent(src, src_transform, dst_transform, src_crs, dst_crs, **kwargs):
    """
    Pad the extent of `src` by an equivalent of one cell of the target raster.

    This ensures that the array is large enough to not be treated as nodata in
    all cells of the destination raster. If src.ndim > 2, the function expects
    the last two dimensions to be y,x.
    Additional keyword arguments are used in `np.pad()`.
    """
    if src.size == 0:
        return src, src_transform

    left, top, right, bottom = *(src_transform * (0, 0)), *(src_transform *
                                                            (1, 1))
    covered = transform_bounds(src_crs, dst_crs, left, bottom, right, top)
    covered_res = min(abs(covered[2] - covered[0]),
                      abs(covered[3] - covered[1]))
    pad = int(dst_transform[0] // covered_res * 1.1)

    kwargs.setdefault('mode', 'constant')

    if src.ndim == 2:
        return rio.pad(src, src_transform, pad, **kwargs)

    npad = ((0, 0), ) * (src.ndim - 2) + ((pad, pad), (pad, pad))
    padded = np.pad(src, npad, **kwargs)
    transform = list(src_transform)
    transform[2] -= pad * transform[0]
    transform[5] -= pad * transform[4]
    return padded, rio.Affine(*transform[:6])
Beispiel #13
0
    def resample_by_raster(self):
        '''
        ### Resampling raster by another raster
            Input: two rasters directories (one to be resampled and another for base)
        '''   
        with rasterio.open(self.__raster_base) as base:
            profile = base.meta.copy()
            height = base.shape[0]
            width = base.shape[1]

            # Resolution output image transform
            xres = int((base.bounds.right  - base.bounds.left) /width)
            yres = int((base.bounds.top  - base.bounds.bottom ) / height )

            # Affine
            transform = rasterio.Affine(xres, base.transform.b, base.transform.c,
                                        base.transform.d, -yres, base.transform.f)

            # Getting the original raster profile and updating with new information
            profile.update(transform=transform, driver='GTiff', height=height, width=width, 
                            crs=base.crs, count=base.count, nodata= np.nan, dtype='float32' )
                                
        with rasterio.open(self.__raster, 'r+') as tif:
            # Reading raster to resample it
            data = tif.read(out_shape=(int(tif.count), int(height), int(width)),
                            resampling=rasterio.enums.Resampling.average)

            # Writing a new raster
            output = self.__raster[:-4] + f'_R{xres}_.tif'

        with rasterio.open(output, 'w', **profile) as dst:
            dst.write(data)

        return data
Beispiel #14
0
    def reproject_band(self, band, src_transform, bbox):
        # shift dst_transform
        # bbox --> (left, bottom, right, top)
        assert self.out_res in ["10", "30", "20", "60"
                                ], "output resolution must be 10, 20, 30 or 60"

        transform_out_res = self.transform_dict[self.out_res][0]

        dst_transform = rasterio.Affine(
            transform_out_res.a, transform_out_res.b,
            bbox[0] if transform_out_res.a > 0 else bbox[2],
            transform_out_res.d, transform_out_res.e,
            bbox[3] if transform_out_res.e < 0 else bbox[1])

        window_read = windows.from_bounds(*bbox, dst_transform)
        shape_new = tuple([int(round(s)) for s in windows.shape(window_read)])
        data_new_proj = np.ndarray(shape=shape_new, dtype=band.dtype)

        reproject(band,
                  data_new_proj,
                  src_transform=src_transform,
                  src_crs=self.crs,
                  dst_transform=dst_transform,
                  dst_crs=self.crs,
                  resampling=Resampling.cubic_spline)

        return data_new_proj
Beispiel #15
0
def resample_profile(m, scale):
    """
    Creates a rasterio profile with the dimensions resampled by a factor

    Parameters
    ----------
    m : str, rasterio profile
        location of the map or rasterio profile
    scale : float
        factor with which height and width will be multiplied

    Returns
    -------
    rasterio profile
    """
    if isinstance(m, str):
        with rio.open(m) as ref_map:
            profile = ref_map.profile
    elif isinstance(m, rio.profiles.Profile):
        profile = copy.deepcopy(m)
    else:
        raise TypeError("M should be a filepath or rasterio profile")

    transform = profile['transform']
    new_transform = rio.Affine(transform[0] / scale, transform[1],
                               transform[2], transform[3],
                               transform[4] / scale, transform[5])

    profile.update({
        'transform': new_transform,
        'width': int(profile['width'] * scale),
        'height': int(profile['height'] * scale)
    })
    return profile
Beispiel #16
0
def mask_to_polygons(mask, xmax, ymin, threshold=0.5, tolerance=1):
    all_polygons = []

    mask[mask >= threshold] = 1
    mask[mask < threshold] = 0

    for shape, _ in rasterio.features.shapes(mask.astype(np.int16),
                                             mask=(mask == 1),
                                             transform=rasterio.Affine(
                                                 1.0, 0, 0, 0, 1.0, 0)):
        all_polygons.append(shapely.geometry.shape(shape))

    all_polygons = shapely.geometry.MultiPolygon(all_polygons)

    # Transform from pixel coordinates to grid coordinates
    height, width = mask.shape
    all_polygons = shapely.affinity.scale(all_polygons,
                                          xfact=xmax / (width),
                                          yfact=ymin / (height),
                                          origin=(0, 0, 0))

    # simplify the geometry of the masks
    # FIXME: magic constant. 2.7*1e-6 is size of one pixel in grid coordinates
    all_polygons = all_polygons.simplify(tolerance * 2.7 * 1e-6,
                                         preserve_topology=True)

    if not all_polygons.is_valid:
        all_polygons = all_polygons.buffer(0)

    # Sometimes buffer() converts a simple Multipolygon to just a Polygon,
    # need to keep it a Multi throughout
    if all_polygons.type == 'Polygon':
        all_polygons = shapely.geometry.MultiPolygon([all_polygons])

    return all_polygons
    def __init__(self, image_path, sz=256, scale=1, saturation_threshold=40):

        self.scale = scale
        self.s_th = saturation_threshold  # saturation blancking threshold
        self.p_th = 1000 * (
            sz // 256)**2  # threshold for the minimum number of pixels
        scale_transform = rasterio.Affine(1, 0, 0, 0, 1, 0)

        self.data = rasterio.open(os.path.join(image_path),
                                  transform=scale_transform,
                                  num_threads='all_cpus')
        # some images have issues with their format
        # and must be saved correctly before reading with rasterio
        if self.data.count != 3:
            subdatasets = self.data.subdatasets
            self.layers = []
            if len(subdatasets) > 0:
                for i, subdataset in enumerate(subdatasets, 0):
                    self.layers.append(rasterio.open(subdataset))

        self.shape = self.data.shape

        self.width = self.shape[1]
        self.height = self.shape[0]
        self.sz = sz

        print(f"image loader for {image_path} created")
        print(f"original image size = {self.width} x {self.height}")
def mask_to_polygons(mask,
                     epsilon=1,
                     min_area=1.,
                     engine='opencv',
                     buffer_amount=0.001):
    #    print('Mask toi polygon')
    # __author__ = Konstantin Lopuhin
    # https://www.kaggle.com/lopuhin/dstl-satellite-imagery-feature-detection/full-pipeline-demo-poly-pixels-ml-poly

    # first, find contours with cv2: it's much faster than shapely
    if engine == 'opencv':
        # TODO check this shit. Тут добавил >=0.5 чтобы обойти кривые маски в файле (без бинаризации)
        image, contours, hierarchy = cv2.findContours(
            ((mask >= 0.5) * 255).astype(np.uint8), cv2.RETR_CCOMP,
            cv2.CHAIN_APPROX_TC89_KCOS)
        # create approximate contours to have reasonable submission size
        approx_contours = [
            cv2.approxPolyDP(cnt, epsilon, True) for cnt in contours
        ]
        if not contours:
            return MultiPolygon()
        # now messy stuff to associate parent and child contours
        cnt_children = defaultdict(list)
        child_contours = set()
        assert hierarchy.shape[0] == 1
        # http://docs.opencv.org/3.1.0/d9/d8b/tutorial_py_contours_hierarchy.html
        for idx, (_, _, _, parent_idx) in enumerate(hierarchy[0]):
            if parent_idx != -1:
                child_contours.add(idx)
                cnt_children[parent_idx].append(approx_contours[idx])
        # create actual polygons filtering by area (removes artifacts)
        all_polygons = []
        for idx, cnt in enumerate(approx_contours):
            if idx not in child_contours and cv2.contourArea(cnt) >= min_area:
                assert cnt.shape[1] == 1
                poly = Polygon(shell=cnt[:, 0, :],
                               holes=[
                                   c[:, 0, :]
                                   for c in cnt_children.get(idx, [])
                                   if cv2.contourArea(c) >= min_area
                               ])
                all_polygons.append(poly)
                # approximating polygons might have created invalid ones, fix them
    else:
        all_polygons = []
        for shape, value in features.shapes(mask.astype(np.int16),
                                            mask=(mask == 1),
                                            transform=rasterio.Affine(
                                                1.0, 0, 0, 0, 1.0, 0)):
            all_polygons.append(shapely.geometry.shape(shape))

    all_polygons = MultiPolygon(all_polygons)
    if True:  # not all_polygons.is_valid:
        all_polygons = all_polygons.buffer(buffer_amount)
        # Sometimes buffer() converts a simple Multipolygon to just a Polygon,
        # need to keep it a Multi throughout
        if all_polygons.type == 'Polygon':
            all_polygons = MultiPolygon([all_polygons])
    return all_polygons
def get_transform_and_shape(bounds, res, out_logging):
    if out_logging:
        _logger.info("Stage 2/5: Get transform and shape")
    left, bottom = [(b // res) * res for b in bounds[:2]]
    right, top = [(b // res + 1) * res for b in bounds[2:]]
    shape = int((top - bottom) // res), int((right - left) / res)
    transform = rio.Affine(res, 0, left, 0, -res, top)
    return transform, shape
Beispiel #20
0
def _as_transform(x, y):
    lx, rx = x[[0, -1]]
    ly, uy = y[[0, -1]]

    dx = float(rx - lx) / float(len(x) - 1)
    dy = float(uy - ly) / float(len(y) - 1)

    return rio.Affine(dx, 0, lx - dx / 2, 0, dy, ly - dy / 2)
Beispiel #21
0
def geotransform_to_affine(geot):
    """
    Convert GDAL geo transform to affine, which is used more commonly
    for specifying the configuration of raster datasets in newer 
    frameworks like rasterio
    """
    c, a, b, f, d, e = list(geot)
    return rio.Affine(a, b, c, d, e, f)
Beispiel #22
0
    def append(self, centr):
        """Append raster or points.

        Parameters
        ----------
        centr : Centroids
            If it's a raster, it needs to have the same `meta` attribute.
            If it's of non-raster form, it's geometry needs to have the same CRS.
        """
        if self.meta and centr.meta:
            LOGGER.debug('Appending raster')
            if centr.meta['crs'] != self.meta['crs']:
                LOGGER.error('Different CRS not accepted.')
                raise ValueError
            if self.meta['transform'][0] != centr.meta['transform'][0] \
               or self.meta['transform'][4] != centr.meta['transform'][4]:
                LOGGER.error('Different raster resolutions.')
                raise ValueError
            left = min(self.total_bounds[0], centr.total_bounds[0])
            bottom = min(self.total_bounds[1], centr.total_bounds[1])
            right = max(self.total_bounds[2], centr.total_bounds[2])
            top = max(self.total_bounds[3], centr.total_bounds[3])
            crs = self.meta['crs']
            width = (right - left) / self.meta['transform'][0]
            height = (bottom - top) / self.meta['transform'][4]
            self.meta = {
                'dtype':
                'float32',
                'width':
                width,
                'height':
                height,
                'crs':
                crs,
                'transform':
                rasterio.Affine(self.meta['transform'][0], 0.0, left, 0.0,
                                self.meta['transform'][4], top),
            }
            self.lat, self.lon = np.array([]), np.array([])
        else:
            LOGGER.debug('Appending points')
            if not u_coord.equal_crs(centr.geometry.crs, self.geometry.crs):
                LOGGER.error('Different CRS not accepted.')
                raise ValueError
            self.lat = np.append(self.lat, centr.lat)
            self.lon = np.append(self.lon, centr.lon)
            self.meta = dict()

        # append all 1-dim variables
        for (var_name, var_val), centr_val in zip(self.__dict__.items(),
                                                  centr.__dict__.values()):
            if isinstance(var_val, np.ndarray) and var_val.ndim == 1 and \
            var_name not in ('lat', 'lon'):
                setattr(
                    self, var_name,
                    np.append(var_val, centr_val).astype(var_val.dtype,
                                                         copy=False))
Beispiel #23
0
def padded_transform_and_shape(bounds, res):
    """
    Get the (transform, shape) tuple of a raster with resolution `res` and
    bounds `bounds`.
    """
    left, bottom = [(b // res) * res for b in bounds[:2]]
    right, top = [(b // res + 1) * res for b in bounds[2:]]
    shape = int((top - bottom) / res), int((right - left) / res)
    return rio.Affine(res, 0, left, 0, -res, top), shape
Beispiel #24
0
def test__vrt_transform(LAYER):
    tile = RasterSrcTile("10N_010E", LAYER.grid, LAYER)

    transform, width, height = tile._vrt_transform(9.1, 9.1, 9.2, 9.2)

    assert transform.almost_equals(
        rasterio.Affine(0.00025, 0, 9.1, 0, -0.00025, 9.2))
    assert isclose(width, 400)
    assert isclose(height, 400)
Beispiel #25
0
def to_geotiff(ncf, out_folder):
    # startdate = dt.datetime.strptime(ncf.datetime, ncf_time_format)

    product = 'precip_probability' if 'precip_probability' in ncf.variables else 'precip_intensity'
    import os
    if product == 'precip_probability':
        out_folder = os.path.join(out_folder, 'nowcast')
    elif product == 'precip_intensity':
        out_folder = os.path.join(out_folder, 'prec_intensity')
        if not os.path.exists(out_folder):
            os.mkdir(out_folder)

    n, h, w = ncf.variables[product].shape

    Xmin = ncf.variables["xc"][0]
    Xmax = ncf.variables["xc"][-1]
    Ymin = ncf.variables["yc"][0]
    Ymax = ncf.variables["yc"][-1]

    affine = rasterio.Affine((Xmax - Xmin) / w, 0, Xmin, 0, (Ymin - Ymax) / h,
                             Ymax)

    data = get_data(ncf, data_var=product)
    for key in data:
        data[key][:] = data[key][::-1, :]

        datetime = dt.datetime.strptime(key, ncf_time_format)
        if product == 'precip_intensity':
            pr = 'prec_intensity'
        else:
            pr = 'nowcast'
        filename = out_folder + "/{}_".format(pr) + dt.datetime.strftime(
            datetime, "%Y%m%d_%H%M") + ".tiff"
        import os
        filename = os.path.realpath(filename)
        if not os.path.exists(os.path.dirname(filename)):
            os.mkdir(os.path.dirname(filename))
        print(filename)
        img_data = convert_probability_to_byte(
            data[key]
        ) if product == 'precip_probability' else convert_precipitation_to_byte(
            values=data[key].data)
        dtype = np.uint8 if product == 'precip_probability' else np.float32
        with rasterio.open(filename,
                           'w',
                           driver='GTiff',
                           height=h,
                           width=w,
                           count=1,
                           dtype=dtype,
                           crs=ncf.projection,
                           nodata=255,
                           transform=affine) as ncfile:
            ncfile.write_band(1, img_data)
        update(datetime, ncf.projection,
               (-w * 2 * 1000, -h * 2 * 1000, w * 2 * 1000, h * 2 * 1000), pr)
Beispiel #26
0
 def transform(self):
     """Get the affine transform of the cutout. """
     return rio.Affine(
         self.dx,
         0,
         self.coords["x"].values[0] - self.dx / 2,
         0,
         self.dy,
         self.coords["y"].values[0] - self.dy / 2,
     )
Beispiel #27
0
 def transform_r(self):
     """Get the affine transform of the cutout with reverse y-order."""
     return rio.Affine(
         self.dx,
         0,
         self.coords["x"].values[0] - self.dx / 2,
         0,
         -self.dy,
         self.coords["y"].values[-1] + self.dy / 2,
     )
Beispiel #28
0
def regrid_PS2EASE(data):

    src_rcrs = rcrs.from_string(NSIDCNorthPolarStereo_crs.proj4_init)
    #src_rcrs = rcrs.from_string('+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs')

    dst_rcrs = rcrs.from_string(EASE_crs.proj4_init)
    #dst_rcrs = rcrs.from_string('+proj=laea +lat_0=90 +lon_0=0 +x_0=0 +y_0=0 +a=6371228 +b=6371228 +units=m +no_defs')

    # Get shape of source grid
    source_height, source_width = data.shape

    # Define source affine transformation
    src_transform = rasterio.Affine(
        NSIDCNorthPolarStereo_25km['pixel_width'],  # pixel width
        0.,  # row rotation
        NSIDCNorthPolarStereo_25km['bounds'][0],  # Left coordinate
        0.,  # Column rotation
        -1 * NSIDCNorthPolarStereo_25km['pixel_height'],  # pixel height
        NSIDCNorthPolarStereo_25km['bounds'][3])

    # Define destination affine transformation
    dst_transform = rasterio.Affine(
        dst_proj['pixel_width'],  # pixel width
        0.,  # row rotation
        dst_proj['bounds'][0],  # Left coordinate
        0.,  # Column rotation
        -1 * dst_proj['pixel_height'],  # pixel height
        dst_proj['bounds'][3])
    #Initialize the destination arrays
    data_ease = np.empty(dst_size, dtype=float)
    #do reprojection
    warp.reproject(source=data.astype(float),
                   src_crs=src_rcrs,
                   src_nodata=np.nan,
                   src_transform=src_transform,
                   destination=data_ease,
                   dst_transform=dst_transform,
                   dst_crs=dst_rcrs,
                   dst_nodata=np.nan,
                   SOURCE_EXTRA=0,
                   resampling=warp.Resampling.nearest)
    return (data_ease)
Beispiel #29
0
def mask_to_polygons_via_shapely(mask):
    all_polygons = []
    for shape, value in rasterio.features.shapes(mask,
                                                 mask,
                                                 connectivity=4,
                                                 transform=rasterio.Affine(
                                                     1.0, 0, 0, 0, 1.0, 0)):
        all_polygons.append(shapely.geometry.shape(shape))
    mp = shapely.geometry.MultiPolygon(all_polygons)
    mp = make_valid(mp)
    return mp
Beispiel #30
0
    def get_image_and_mask(self, tile_geometry, debug_base_file_name=None):

        km2_to_m2 = 1000.0 * 1000.0
        surface_area_m2 = tile_geometry.area * km2_to_m2

        min_tile_e = int(tile_geometry.bounds[0])
        min_tile_n = int(tile_geometry.bounds[1])
        max_tile_e = int(tile_geometry.bounds[2])
        max_tile_n = int(tile_geometry.bounds[3])

        image_bgr = self.download_image(max_tile_e, max_tile_n, min_tile_e,
                                        min_tile_n)

        # [a, b, d, e, xoff, yoff]
        # x' = a * x + b * y + xoff
        # y' = d * x + e * y + yoff
        m = [
            self.__final_tile_size, 0, 0, self.__final_tile_size,
            -min_tile_e * self.__final_tile_size,
            -min_tile_n * self.__final_tile_size
        ]
        affine_geometry = affine_transform(tile_geometry, m)

        min_x = floor(affine_geometry.bounds[0])
        min_y = floor(affine_geometry.bounds[1])
        max_x = floor(affine_geometry.bounds[2])
        max_y = floor(affine_geometry.bounds[3])

        max_y_vertically_flipped = image_bgr.shape[0] - 1 - min_y
        min_y_vertically_flipped = image_bgr.shape[0] - 1 - max_y

        affine = rasterio.Affine(1, 0, min_x, 0, -1, max_y)

        pixels_within_geometry = geometry_mask(
            [affine_geometry],
            (max_y_vertically_flipped - min_y_vertically_flipped + 1,
             max_x - min_x + 1),
            affine,
            invert=True)

        image_bgri_cropped = image_bgr[
            min_y_vertically_flipped:max_y_vertically_flipped + 1,
            min_x:max_x + 1, :]

        tile_file_name = None

        if debug_base_file_name is not None:
            centre_point = tile_geometry.centroid
            tile_code = tile_eastings_and_northings_to_tile_code(
                centre_point.x, centre_point.y)
            tile_file_name = debug_base_file_name + '-' + tile_code

        return image_bgri_cropped, pixels_within_geometry, surface_area_m2, tile_file_name