Exemplo n.º 1
0
def getTransform(xvar=None, x=None, y=None, lcheck=True):
    ''' generate an affine transformation from xarray coordinate axes '''
    from rasterio.transform import Affine # to generate Affine transform
    
    if isinstance(xvar,(xr.DataArray,xr.Dataset)):
        x,y = getGeoCoords(xvar, lraise=True)
    elif xvar:
        raise TypeError('Can only infer GeoTransform from xarray Dataset or DataArray - not from {}.'.format(xvar))
    
    # check X-axis
    if isinstance(x,xr.DataArray): x = x.data
    if not isinstance(x,np.ndarray): 
        raise TypeError(x)
    diff_x = np.diff(x); dx = diff_x.min()
    if lcheck and not np.isclose(dx, diff_x.max(), rtol=1.e-2): 
        raise ValueError("X-axis is not regular: {} - {}".format(dx, diff_x.max()))
    
    # check Y-axis
    if isinstance(y,xr.DataArray): y = y.data
    if not isinstance(y,np.ndarray): 
        raise TypeError(y)
    diff_y = np.diff(y); dy = diff_y.min()
    if lcheck and not np.isclose(dy, diff_y.max(), rtol=1.e-2): 
        raise ValueError("Y-axis is not regular. {} - {}".format(dy, diff_y.max()))
    
    # generate transform
    return Affine.from_gdal(x[0]-dx/2.,dx,0.,y[0]-dy/2.,0.,dy), (len(x),len(y))
Exemplo n.º 2
0
def rasterizeShapes(pshapes, geodict, all_touched=True):
    """
    Rasterizing a shape

    Args:
        pshapes: Sequence of orthographically projected shapes.
        geodict: Mapio geodictionary.
        all_touched: Turn pixel "on" if shape touches pixel, otherwise turn it
            on if the center of the pixel is contained within the shape. Note
            that the footprint of the shape is inflated and the amount of
            inflation depends on the pixel size if all_touched=True.

    Returns:
        Rasterio grid.
    """
    outshape = (geodict.ny, geodict.nx)
    txmin = geodict.xmin - geodict.dx / 2.0
    tymax = geodict.ymax + geodict.dy / 2.0
    transform = Affine.from_gdal(txmin, geodict.dx, 0.0, tymax, 0.0,
                                 -geodict.dy)
    imgs = rasterio.features.rasterize(pshapes,
                                       out_shape=outshape,
                                       fill=0.0,
                                       transform=transform,
                                       all_touched=all_touched,
                                       default_value=1.0)
    return imgs
Exemplo n.º 3
0
def getTransform(xvar=None, x=None, y=None, lcheck=True):
    ''' generate an affine transformation from xarray coordinate axes '''
    from rasterio.transform import Affine # to generate Affine transform
    
    if isinstance(xvar,(xr.DataArray,xr.Dataset,nc.Dataset)):
        x,y = getGeoCoords(xvar, lraise=True)
    elif xvar is None and isinstance(x,(xr.DataArray,nc.Variable)) and isinstance(y,(xr.DataArray,nc.Variable)):
        pass # x and y axes are supplied directly
    elif xvar:
        raise TypeError('Can only infer GeoTransform from xarray Dataset or DataArray or netCDF4 Dataset\n - not from {}.'.format(xvar))
    
    # check X-axis
    if isinstance(x,xr.DataArray): x = x.data
    elif isinstance(x,nc.Variable): x = x[:]
    if not isinstance(x,np.ndarray): 
        raise TypeError(x)
    diff_x = np.diff(x); dx = diff_x.min()
    if lcheck and not np.isclose(dx, diff_x.max(), rtol=1.e-2): 
        raise ValueError("X-axis is not regular: {} - {}".format(dx, diff_x.max()))
    
    # check Y-axis
    if isinstance(y,xr.DataArray): y = y.data
    elif isinstance(y,nc.Variable): y = y[:]
    if not isinstance(y,np.ndarray): 
        raise TypeError(y)
    diff_y = np.diff(y); dy = diff_y.min()
    if lcheck and not np.isclose(dy, diff_y.max(), rtol=1.e-2): 
        raise ValueError("Y-axis is not regular. {} - {}".format(dy, diff_y.max()))
    
    # generate transform
    return Affine.from_gdal(x[0]-dx/2.,dx,0.,y[0]-dy/2.,0.,dy), (len(x),len(y))
Exemplo n.º 4
0
def rasterizeShapes(pshapes,geodict):
    outshape = (geodict.ny,geodict.nx)
    txmin = geodict.xmin - geodict.dx/2.0
    tymax = geodict.ymax + geodict.dy/2.0
    transform = Affine.from_gdal(txmin,geodict.dx,0.0,tymax,0.0,-geodict.dy)
    img = rasterio.features.rasterize(pshapes,out_shape=outshape,fill=0.0,transform=transform,
                                      all_touched=True,default_value=1.0)
    return img
Exemplo n.º 5
0
def geopandas_to_raster(gpd_frame, raster_file, gpd_column, geo_grid: GeoGrid,
                        datatype, all_touched):
    """ Write geopandas data frame to raster

    :param gpd_frame:
    :param raster_file:
    :param gpd_column:
    :param geo_grid: GeoGrid instance
    :param datatype: data type ('uint8', 'float32', etc.)
    :param all_touched:
    :return:
    """

    # _ = _create_raster_file(raster_file, geo_grid, geo_crs, 0)

    # Open temp raster file with rasterio and copy metadata
    # raster_fcn = rasterio.open(raster_temp_file.name)
    # meta = raster_fcn.meta.copy()
    # meta.update(compress='lzw')

    with rasterio.open(
            raster_file,
            'w',
            driver="GTiff",
            width=geo_grid.num_x,
            height=geo_grid.num_y,
            count=1,
            dtype=datatype,
            crs=gpd_frame.crs,
            transform=Affine.from_gdal(*geo_grid.geo_transform)) as out:

        # this is where we create a generator of geom, value pairs to use in rasterizing
        shapes = (
            (geom, value)
            for geom, value in zip(gpd_frame.geometry, gpd_frame[gpd_column]))

        burned = features.rasterize(
            shapes=shapes,
            fill=0,
            out_shape=(geo_grid.num_y, geo_grid.num_x),
            dtype=datatype,
            transform=Affine.from_gdal(*geo_grid.geo_transform),
            all_touched=all_touched)
        out.write_band(1, burned)

    return 0
Exemplo n.º 6
0
def rasterizeShapes(pshapes, geodict):
    outshape = (geodict.ny, geodict.nx)
    txmin = geodict.xmin - geodict.dx / 2.0
    tymax = geodict.ymax + geodict.dy / 2.0
    transform = Affine.from_gdal(txmin, geodict.dx, 0.0, tymax, 0.0,
                                 -geodict.dy)
    img = rasterio.features.rasterize(pshapes,
                                      out_shape=outshape,
                                      fill=0.0,
                                      transform=transform,
                                      all_touched=True,
                                      default_value=1.0)
    return img
Exemplo n.º 7
0
def get_rasterio_datasets(array_proj: List[Tuple[Union[np.ndarray, int], Dict]],
                          mask_value: Optional[int] = 0,
                          force_output_shape: Optional[Tuple[int, int, int]] = (1, 1, 1),
                          force_output_type: Optional[str] = "int32") -> List[rasterio.io.DatasetReader]:
    """transform numpy arrays (containing projection data) to rasterio datasets
        it works only with 3D arrays
    """
    all_data_sets = []
    expected_arr_shapes = set([arr[0].shape for arr in array_proj if isinstance(arr[0], np.ndarray)])
    if not expected_arr_shapes:
        expected_arr_shapes = [force_output_shape]
    expected_arr_shape = list(expected_arr_shapes)[0]
    expected_arr_types = set([arr[0].dtype for arr in array_proj if isinstance(arr[0], np.ndarray)])
    if not expected_arr_types:
        expected_arr_types = [force_output_type]
    expected_arr_type = list(expected_arr_types)[0]

    for index, new_array in enumerate(array_proj):
        array = new_array[0]
        if isinstance(array, int):
            array = np.full(expected_arr_shape, mask_value, dtype=expected_arr_type)

        proj = new_array[-1]["projection"]
        geo_transform = new_array[-1]["geo_transform"]

        if index == 0:
            epsg_code = proj.GetAttrValue("AUTHORITY", 1)

        transform = Affine.from_gdal(*geo_transform)
        array_ordered = np.moveaxis(array, -1, 0)
        array_ordered_shape = array_ordered.shape

        if len(array_ordered_shape) != 3:
            raise ValueError("array's must be 3D")
        else:
            height = array_ordered_shape[1]
            width = array_ordered_shape[2]
            count = array_ordered_shape[0]
        with MemoryFile() as memfile:
            with memfile.open(driver='GTiff',
                              height=height,
                              width=width,
                              count=count,
                              dtype=array.dtype,
                              crs="EPSG:{}".format(epsg_code),
                              transform=transform) as dataset:
                dataset.write(array_ordered)
            all_data_sets.append(memfile.open())
    return all_data_sets
def ReadRasterWindow(rasterDs, roiCnrs = None, ovwLevel = None):
    geoTransform = np.array(rasterDs.GetGeoTransform())
    if ovwLevel is not None:  # adjust the geotransform to be for larger pixels
        geoTransform[1] = geoTransform[1] * (2. ** (ovwLevel+1))
        geoTransform[5] = geoTransform[5] * (2. ** (ovwLevel+1))
    affine = Affine.from_gdal(*geoTransform)

    if roiCnrs is None:
        origin = np.int32([0, 0])
        counts = np.int32([rasterDs.XSize, rasterDs.YSize])
    else:
        roiPlCnrs = np.array(~affine * roiCnrs.transpose()).transpose()
        origin = np.min(roiPlCnrs, axis=0)
        counts = np.max(roiPlCnrs, axis=0) - origin
        # print 'origin: ' + str(origin)
        # print 'counts: ' + str(counts)
        origin = np.int32(np.round(origin))  # only round after counts calc
        counts = np.int32(np.round(counts))
        if ovwLevel is not None:
            band = rasterDs.GetRasterBand(1).GetOverview(ovwLevel)
        else:
            band = rasterDs.GetRasterBand(1)
        rasterSize = np.array([band.XSize, band.YSize])
        # Note A - it is possible that the ROI extends past the image boundary due to rounding - fix this below
        mask = (origin + counts) > rasterSize
        counts[mask] = (rasterSize - origin)[mask]
        # print 'origin: ' + str(origin)
        # print 'counts: ' + str(counts)

    rasterRoi = np.zeros([counts[1], counts[0], rasterDs.RasterCount], dtype=np.float32)
    for b in range(0, rasterDs.RasterCount):
        if ovwLevel is not None:
            band = rasterDs.GetRasterBand(b + 1).GetOverview(ovwLevel)
        else:
            band = rasterDs.GetRasterBand(b + 1)
        bandArray = band.ReadAsArray(origin[0], origin[1], counts[0], counts[1], None, None, gdal.GDT_Float32)
        rasterRoi[:, :, b] = bandArray

    # use last band to get mask - assume mask same for all bands
    rasterMask = band.GetMaskBand().ReadAsArray(origin[0], origin[1], counts[0], counts[1])
    return rasterRoi, rasterMask  #, origin, counts
Exemplo n.º 9
0
    def execute(self, service_id):
        svc = Service.objects.get(name=service_id)
        var = Variable.objects.get(service_id=svc.id)
        data_path = svc.data_path
        with netCDF4.Dataset(os.path.join(SERVICE_DATA_ROOT, data_path), 'r') as nc:
            data = nc.variables[var.name][:].astype('uint8')

        height, width = data.shape
        ex = var.full_extent
        x_step = (ex.xmax - ex.xmin) / width
        y_step = (ex.ymax - ex.ymin) / height
        transform = Affine.from_gdal(ex.xmin, x_step, 0, ex.ymax, 0, -y_step)
        dtype = np.uint8
        nodata = 128

        if not settings.DATASET_DOWNLOAD_DIR.exists():
            settings.DATASET_DOWNLOAD_DIR.mkdir()

        fd, filename = tempfile.mkstemp(dir=str(settings.DATASET_DOWNLOAD_DIR), suffix='.zip')
        os.close(fd)
        os.chmod(filename, S_IRUSR | S_IWUSR | S_IRGRP)

        with zipfile.ZipFile(filename, mode='w') as zf:
            tif_data = BytesIO()

            with rasterio.Env(GDAL_TIFF_INTERNAL_MASK=True):
                opts = dict(
                    driver='GTiff', height=height, width=width, crs=var.projection, transform=transform, count=1,
                    dtype=dtype, nodata=nodata
                )
                with rasterio.open(tif_data, 'w', **opts) as dst:
                    dst.write(np.array(data, dtype=dtype), 1)
                    dst.write_mask(np.logical_not(data.mask))

                zf.writestr('SST Results/results.tif', tif_data.getvalue(), compress_type=zipfile.ZIP_DEFLATED)
                zf.writestr(
                    'SST Results/README.txt', render_to_string('txt/download_readme.txt', {}),
                    compress_type=zipfile.ZIP_DEFLATED
                )

        return os.path.basename(filename)
def ProjectionFromConfig():
    ncols, nrows = (1416, 1051)
    profile = {
        "driver":
        "GTiff",
        "height":
        nrows,
        "width":
        ncols,
        "count":
        1,
        "dtype":
        np.float32,
        "crs":
        'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,\
            AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],\
            UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]]GEOGCS["WGS 84",\
            DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],\
            AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],\
            AUTHORITY["EPSG","4326"]]GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,\
            298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],\
            UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]]',
        "transform":
        Affine.from_gdal(
            24.150733709000065,
            0.008334173612994345,
            0,
            12.23635188000003,
            0,
            -0.008331170202664108,
        ),
        "nodata":
        -9999.0,
    }

    return profile