Esempio n. 1
0
def masknetcdf(netcdf_filename, shp_filename, cl_field=None):
    if cl_field == None:
        # If no field is provided, assume first part of file name is the field to use
        head, tail = os.path.split(netcdf_filename)
        cl_field = tail.split(".")[0]

    # Open dataset
    data_source = gdal.Open(netcdf_filename)
    # Number of columns of each layer
    cols = data_source.RasterXSize
    #Number of rows of each layer
    rows = data_source.RasterYSize
    # Number of bands of each layer
    nbands = data_source.RasterCount
    # Year of the netcdf file
    year = int(netcdf_filename.split('.')[-2])

    #========================================
    # Importing data by bands as a dictionary
    #========================================
    datach = {}
    # First day of the year as reference
    yearc = str(year) + "-01-01"
    # Converting year in a datatime object
    fi_date = datetime.datetime.strptime(yearc, "%Y-%m-%d").date()
    # For loop of the layers that contains the netcdf file
    for i in range(1, nbands + 1):
        index_date = fi_date + datetime.timedelta(days=i - 1)
        in_band = data_source.GetRasterBand(i)
        # Converting default nan in np.na
        in_band_wnan = in_band.ReadAsArray()
        in_band_wnan[in_band_wnan == -9.9692100e+36] = np.nan
        datach[index_date.strftime("%Y-%m-%d")] = in_band_wnan

    #====================================
    # Parameters of transformation
    #====================================
    x = 0.5 * cols - rows
    delta_Lon = 360 / cols
    delta_Lat = 180 / (rows + x)
    if x == 0:
        LonUpper_Left = 0
        LatUpper_Left = 90
    else:
        LonUpper_Left = -delta_Lon / 2
        LatUpper_Left = delta_Lat * (rows / 2)
    gt = [LonUpper_Left, delta_Lon, 0, LatUpper_Left, 0, -delta_Lat]
    # Inverse affine transformation
    inv_gt = gdal.InvGeoTransform(gt)
    inv_gt

    #=====================================================================
    # Importing shapefile and transforming coordinates to rows and columns
    #=====================================================================
    # Calling driver
    driver = ogr.GetDriverByName('ESRI Shapefile')
    # Open dataset
    datasource1 = driver.Open(shp_filename, 1)
    # Get layer
    layer = datasource1.GetLayer()
    # Get number of features
    fc = layer.GetFeatureCount()
    # Creating lists for rows, columns and time index
    xt_p = []
    yt_p = []
    dayc = []
    for fea in layer:
        # Time
        a = fea.GetField("timestamp")[0:10]
        dayc.append(a)
        # Coord
        pt = fea.geometry()
        # Transforming coord
        xt, yt = gdal.ApplyGeoTransform(inv_gt, pt.GetX(), pt.GetY())
        xt_p.append(xt)
        yt_p.append(yt)

    #=================================
    # Extracting values by time
    #=================================
    # Converting list of days to array
    array_indexday = np.array(dayc)
    # Creating a vector of nan values
    value = np.zeros(fc)
    value[value == 0] = np.nan
    # For loop to extract values by time
    for j in np.unique(dayc):
        # Condition about the year of interest
        year_d = datetime.datetime.strptime(j, "%Y-%m-%d").year
        if year_d == year:
            # Match day of the features with the day of the band array
            index = np.where(array_indexday == j)[0].tolist()
            in_band = datach[j]
            # Extracting values of the layer that correspond to certain time
            for k in range(0, len(index)):
                data = in_band[int(yt_p[index[k]]), int(xt_p[index[k]])]
                value[index[k]] = data
        else:
            continue

    #============================
    # Loading values to shapefile
    #============================
    # Calling the shapefile again but in edition version (1)
    driver = ogr.GetDriverByName('ESRI Shapefile')
    datasource2 = driver.Open(shp_filename, 1)
    layer2 = datasource2.GetLayer()
    # Reset index
    datasource2.SyncToDisk()
    # List of the fields of the shapefile
    schema = []
    ldefn = layer2.GetLayerDefn()
    for n in range(ldefn.GetFieldCount()):
        fdefn = ldefn.GetFieldDefn(n)
        schema.append(fdefn.name)
    # So, if the field exists this function updates the field, otherwise, it will create
    # A new field with the specified name
    if np.any(np.array(schema) == cl_field):
        i = 0
        # For loop quering the existency of the value for certain period
        for fe in layer2:
            year_2 = datetime.datetime.strptime(dayc[i], "%Y-%m-%d").year
            if year_2 == year:
                fe.SetField(cl_field, value[i])
                layer2.SetFeature(fe)
            i = i + 1
    else:
        # Creating the the new field
        new_field = ogr.FieldDefn(cl_field, ogr.OFTReal)
        layer2.CreateField(new_field)
        i = 0
        for fe in layer2:
            fe.SetField(cl_field, value[i])
            layer2.SetFeature(fe)
            i = i + 1
    # Destroy data source shapefile
    datasource1.Destroy()
    datasource2.Destroy()
    # Close source netcdf
    data_source = None
    del value
    print(f"Done! Year: {year}; Field {cl_field}")
Esempio n. 2
0
def gdallocationinfo(filename_or_ds: PathOrDS,
                     x: ArrayOrScalarLike, y: ArrayOrScalarLike,
                     srs: CoordinateTransformationOrSRS = None,
                     axis_order: Optional[OAMS_AXIS_ORDER] = None,
                     open_options: Optional[dict] = None,
                     ovr_idx: Optional[int] = None,
                     band_nums: Optional[Sequence[int]] = None,
                     inline_xy_replacement: bool = False,
                     return_ovr_pixel_line: bool = False,
                     transform_round_digits: Optional[float] = None,
                     allow_xy_outside_extent: bool = True,
                     pixel_offset: Real = -0.5, line_offset: Real = -0.5,
                     resample_alg=gdalconst.GRIORA_NearestNeighbour,
                     quiet_mode: bool = True,
                     ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
    ds = open_ds(filename_or_ds, open_options=open_options)
    filename = filename_or_ds if is_path_like(filename_or_ds) else ''
    if ds is None:
        raise Exception(f'Could not open {filename}.')
    if not isinstance(x, ArrayLike.__args__):
        x = [x]
    if not isinstance(y, ArrayLike.__args__):
        y = [y]
    if len(x) != len(y):
        raise Exception(f'len(x)={len(x)} should be the same as len(y)={len(y)}')
    point_count = len(x)

    dtype = np.float64
    if not isinstance(x, np.ndarray) or not isinstance(y, np.ndarray):
        x = np.array(x, dtype=dtype)
        y = np.array(y, dtype=dtype)
        inline_xy_replacement = True

    if srs is None:
        srs = LocationInfoSRS.PixelLine

    # Build Spatial Reference object based on coordinate system, fetched from the opened dataset
    if srs != LocationInfoSRS.PixelLine:
        if srs != LocationInfoSRS.SameAsDS_SRS:
            ds_srs = ds.GetSpatialRef()
            ct = None
            if isinstance(srs, osr.CoordinateTransformation):
                ct = srs
            else:
                if srs == LocationInfoSRS.SameAsDS_SRS_GeogCS:
                    points_srs = ds_srs.CloneGeogCS()
                else:
                    points_srs = get_srs(srs, axis_order=axis_order)
                ct = get_transform(points_srs, ds_srs)
            if ct is not None:
                if not inline_xy_replacement:
                    x = x.copy()
                    y = y.copy()
                    inline_xy_replacement = True
                transform_points(ct, x, y)
                if transform_round_digits is not None:
                    x.round(transform_round_digits, out=x)
                    y.round(transform_round_digits, out=y)

        # Read geotransform matrix and calculate corresponding pixel coordinates
        geotransform = ds.GetGeoTransform()
        inv_geotransform = gdal.InvGeoTransform(geotransform)
        if inv_geotransform is None:
            raise Exception("Failed InvGeoTransform()")

        # can we inline this transformation ?
        x, y = \
            (inv_geotransform[0] + inv_geotransform[1] * x + inv_geotransform[2] * y), \
            (inv_geotransform[3] + inv_geotransform[4] * x + inv_geotransform[5] * y)
        inline_xy_replacement = True

    xsize, ysize = ds.RasterXSize, ds.RasterYSize
    bands = get_bands(ds, band_nums, ovr_idx=ovr_idx)
    ovr_xsize, ovr_ysize = bands[0].XSize, bands[0].YSize
    pixel_fact, line_fact = (ovr_xsize / xsize, ovr_ysize / ysize) if ovr_idx else (1, 1)
    bnd_count = len(bands)

    shape = (bnd_count, point_count)
    np_dtype, np_dtype = GDALTypeCodeAndNumericTypeCodeFromDataSet(ds)
    results = np.empty(shape=shape, dtype=np_dtype)

    check_outside = not quiet_mode or not allow_xy_outside_extent
    if check_outside and (np.any(x < 0) or np.any(x >= xsize) or np.any(y < 0) or np.any(y >= ysize)):
        msg = 'Passed coordinates are not in dataset extent!'
        if not allow_xy_outside_extent:
            raise Exception(msg)
        elif not quiet_mode:
            print(msg)

    if pixel_fact == 1:
        pixels_q = x
    elif return_ovr_pixel_line:
        x *= pixel_fact
        pixels_q = x
    else:
        pixels_q = x * pixel_fact

    if line_fact == 1:
        lines_q = y
    elif return_ovr_pixel_line:
        y *= line_fact
        lines_q = y
    else:
        lines_q = y * line_fact

    buf_xsize = buf_ysize = 1
    buf_type, typecode = GDALTypeCodeAndNumericTypeCodeFromDataSet(ds)
    buf_obj = np.empty([buf_ysize, buf_xsize], dtype=typecode)

    for idx, (pixel, line) in enumerate(zip(pixels_q, lines_q)):
        for bnd_idx, band in enumerate(bands):
            if BandRasterIONumPy(band, 0, pixel-0.5, line-0.5, 1, 1, buf_obj, buf_type, resample_alg, None, None) == 0:
                results[bnd_idx][idx] = buf_obj[0][0]

    is_scaled, scales, offsets = get_scales_and_offsets(bands)
    if is_scaled:
        for bnd_idx, (scale, offset) in enumerate(zip(scales, offsets)):
            results[bnd_idx] = results[bnd_idx] * scale + offset

    return x, y, results
Esempio n. 3
0
# opened dataset
if coordtype_georef:
    X = longitude
    Y = latitude
else:
    srs = osr.SpatialReference()
    srs.ImportFromWkt(ds.GetProjection())

    srsLatLong = srs.CloneGeogCS()
    # Convert from (longitude,latitude) to projected coordinates
    ct = osr.CoordinateTransformation(srsLatLong, srs)
    (X, Y, height) = ct.TransformPoint(longitude, latitude)

# Read geotransform matrix and calculate corresponding pixel coordinates
geomatrix = ds.GetGeoTransform()
(success, inv_geometrix) = gdal.InvGeoTransform(geomatrix)
x = int(inv_geometrix[0] + inv_geometrix[1] * X + inv_geometrix[2] * Y)
y = int(inv_geometrix[3] + inv_geometrix[4] * X + inv_geometrix[5] * Y)

if display_xy:
    print('x=%d, y=%d' % (x, y))

if x < 0 or x >= ds.RasterXSize or y < 0 or y >= ds.RasterYSize:
    print('Passed coordinates are not in dataset extent')
    sys.exit(1)

res = ds.ReadAsArray(x, y, 1, 1)
if len(res.shape) == 2:
    print(res[0][0])
else:
    for val in res:
Esempio n. 4
0
def main(argv):
    display_xy = False
    coordtype_georef = False
    longitude = None
    latitude = None
    filename = None

    # =============================================================================
    # Parse command line arguments.
    # =============================================================================
    i = 1
    while i < len(argv):
        arg = argv[i]

        if arg == '-coordtype=georef':
            coordtype_georef = True

        elif arg == '-display_xy':
            display_xy = True

        elif longitude is None:
            longitude = float(arg)

        elif latitude is None:
            latitude = float(arg)

        elif filename is None:
            filename = arg

        else:
            return Usage()

        i = i + 1

    if longitude is None:
        return Usage()
    if latitude is None:
        return Usage()
    if filename is None:
        filename()

    # Open input dataset
    ds = gdal.Open(filename, gdal.GA_ReadOnly)
    if ds is None:
        print('Cannot open %s' % filename)
        return 1

    # Build Spatial Reference object based on coordinate system, fetched from the
    # opened dataset
    if coordtype_georef:
        X = longitude
        Y = latitude
    else:
        srs = osr.SpatialReference()
        srs.ImportFromWkt(ds.GetProjection())

        srsLatLong = srs.CloneGeogCS()
        # Convert from (longitude,latitude) to projected coordinates
        ct = osr.CoordinateTransformation(srsLatLong, srs)
        (X, Y, height) = ct.TransformPoint(longitude, latitude)

    # Read geotransform matrix and calculate corresponding pixel coordinates
    geomatrix = ds.GetGeoTransform()
    (success, inv_geometrix) = gdal.InvGeoTransform(geomatrix)
    x = int(inv_geometrix[0] + inv_geometrix[1] * X + inv_geometrix[2] * Y)
    y = int(inv_geometrix[3] + inv_geometrix[4] * X + inv_geometrix[5] * Y)

    if display_xy:
        print('x=%d, y=%d' % (x, y))

    if x < 0 or x >= ds.RasterXSize or y < 0 or y >= ds.RasterYSize:
        print('Passed coordinates are not in dataset extent')
        return 1

    res = ds.ReadAsArray(x, y, 1, 1)
    if len(res.shape) == 2:
        print(res[0][0])
    else:
        for val in res:
            print(val[0][0])

    return 0
Esempio n. 5
0
def sample_data(time_domain_mask_list, predictor_lookup, sample_rate,
                edge_index, sample_point_vector_path):
    """Sample data stack.

    All input rasters are aligned.

    Args:
        response_path (str): path to response raster
        predictor_lookup (dict): dictionary with keys 'predictor' and
            'time_predictor'. 'time_predictor' are either a tuple of rasters
            or a single multiband raster with indexes that conform to the
            bands in ``response_path``.
        edge_index (int): this is the edge raster in the predictor stack
            that should be used to randomly select samples from.


    """
    raster_info = pygeoprocessing.get_raster_info(
        predictor_lookup['predictor'][0][0])
    inv_gt = gdal.InvGeoTransform(raster_info['geotransform'])

    raster_srs = osr.SpatialReference()
    raster_srs.ImportFromWkt(raster_info['projection_wkt'])
    raster_srs.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)

    gpkg_driver = gdal.GetDriverByName('GPKG')
    sample_point_vector = gpkg_driver.Create(sample_point_vector_path, 0, 0, 0,
                                             gdal.GDT_Unknown)
    sample_point_layer = sample_point_vector.CreateLayer(
        'sample_points', raster_srs, ogr.wkbPoint)
    sample_point_layer.StartTransaction()

    LOGGER.info(f'building sample data')
    predictor_band_nodata_list = []
    raster_list = []
    # simple lookup to map predictor band/nodata to a list
    for predictor_path, nodata in predictor_lookup['predictor']:
        predictor_raster = gdal.OpenEx(predictor_path, gdal.OF_RASTER)
        raster_list.append(predictor_raster)
        predictor_band = predictor_raster.GetRasterBand(1)

        if nodata is None:
            nodata = predictor_band.GetNoDataValue()
        predictor_band_nodata_list.append((predictor_band, nodata))

    # create a dictionary that maps time index to list of predictor band/nodata
    # values, will be used to create a stack of data with the previous
    # collection and one per timestep on this one
    time_predictor_lookup = collections.defaultdict(list)
    for payload in predictor_lookup['time_predictor']:
        # time predictors could either be a tuple of rasters or a single
        # raster with multiple bands
        if isinstance(payload, tuple):
            time_predictor_path, nodata = payload
            time_predictor_raster = gdal.OpenEx(time_predictor_path,
                                                gdal.OF_RASTER)
            raster_list.append(time_predictor_raster)
            for index in range(time_predictor_raster.RasterCount):
                time_predictor_band = time_predictor_raster.GetRasterBand(
                    index + 1)
                if nodata is None:
                    nodata = time_predictor_band.GetNoDataValue()
                time_predictor_lookup[index].append(
                    (time_predictor_band, nodata))
        elif isinstance(payload, list):
            for index, (time_predictor_path, nodata) in enumerate(payload):
                time_predictor_raster = gdal.OpenEx(time_predictor_path,
                                                    gdal.OF_RASTER)
                raster_list.append(time_predictor_raster)
                time_predictor_band = time_predictor_raster.GetRasterBand(1)
                if nodata is None:
                    nodata = time_predictor_band.GetNoDataValue()
                time_predictor_lookup[index].append(
                    (time_predictor_band, nodata))
        else:
            raise ValueError(f'expected str or tuple but got {payload}')
    mask_band_list = []
    for time_domain_mask_raster_path in time_domain_mask_list:
        mask_raster = gdal.OpenEx(time_domain_mask_raster_path, gdal.OF_RASTER)
        raster_list.append(mask_raster)
        mask_band = mask_raster.GetRasterBand(1)
        mask_band_list.append(mask_band)

    # build up an array of predictor stack
    response_raster = gdal.OpenEx(predictor_lookup['response'], gdal.OF_RASTER)
    raster_list.append(response_raster)

    y_list = []
    x_vector = None
    i = 0
    last_time = time.time()
    total_pixels = predictor_raster.RasterXSize * predictor_raster.RasterYSize
    for offset_dict in pygeoprocessing.iterblocks(
        (predictor_lookup['response'], 1),
            offset_only=True,
            largest_block=2**20):
        if time.time() - last_time > 5.0:
            n_pixels_processed = offset_dict[
                'xoff'] + offset_dict['yoff'] * predictor_raster.RasterXSize
            LOGGER.info(
                f"processed {100*n_pixels_processed/total_pixels:.3f}% so far ({n_pixels_processed}) (x/y {offset_dict['xoff']}/{offset_dict['yoff']}) y_list size {len(y_list)}"
            )
            last_time = time.time()
        predictor_stack = []  # N elements long
        valid_array = numpy.ones(
            (offset_dict['win_ysize'], offset_dict['win_xsize']), dtype=bool)
        # load all the regular predictors
        for predictor_band, predictor_nodata in predictor_band_nodata_list:
            predictor_array = predictor_band.ReadAsArray(**offset_dict)
            if predictor_nodata is not None:
                valid_array &= predictor_array != predictor_nodata
            predictor_stack.append(predictor_array)

        if not numpy.any(valid_array):
            continue

        # load the time based predictors
        for index, time_predictor_band_nodata_list in \
                time_predictor_lookup.items():
            if index > MAX_TIME_INDEX:
                break
            mask_array = mask_band_list[index].ReadAsArray(**offset_dict)
            valid_time_array = valid_array & (mask_array == 1)
            predictor_time_stack = []
            predictor_time_stack.extend(predictor_stack)
            for predictor_index, (predictor_band, predictor_nodata) in \
                    enumerate(time_predictor_band_nodata_list):
                predictor_array = predictor_band.ReadAsArray(**offset_dict)
                if predictor_nodata is not None:
                    valid_time_array &= predictor_array != predictor_nodata
                predictor_time_stack.append(predictor_array)

            # load the time based responses
            response_band = response_raster.GetRasterBand(index + 1)
            response_nodata = response_band.GetNoDataValue()
            response_array = response_band.ReadAsArray(**offset_dict)
            if response_nodata is not None:
                valid_time_array &= response_array != response_nodata

            if not numpy.any(valid_time_array):
                break

            sample_mask = numpy.random.rand(
                numpy.count_nonzero(valid_time_array)) < sample_rate

            X2D, Y2D = numpy.meshgrid(range(valid_time_array.shape[1]),
                                      range(valid_time_array.shape[0]))

            for i, j in zip((X2D[valid_time_array])[sample_mask],
                            (Y2D[valid_time_array])[sample_mask]):

                sample_point = ogr.Feature(sample_point_layer.GetLayerDefn())
                sample_geom = ogr.Geometry(ogr.wkbPoint)
                x, y = gdal.ApplyGeoTransform(inv_gt,
                                              i + 0.5 + offset_dict['xoff'],
                                              j + 0.5 + offset_dict['yoff'])
                sample_geom.AddPoint(x, y)
                sample_point.SetGeometry(sample_geom)
                sample_point_layer.CreateFeature(sample_point)

            # all of response_time_stack and response_array are valid, clip and add to set
            local_x_list = []
            # each element in array should correspond with an element in y
            for array in predictor_time_stack:
                local_x_list.append((array[valid_time_array])[sample_mask])
            if x_vector is None:
                x_vector = numpy.array(local_x_list)
            else:
                local_x_vector = numpy.array(local_x_list)
                # THE LAST ELEMENT IS THE FLOW ACCUMULATION THAT I WANT LOGGED
                x_vector = numpy.append(x_vector, local_x_vector, axis=1)
            y_list.extend(list(
                (response_array[valid_time_array])[sample_mask]))

        i += 1
    y_vector = numpy.array(y_list)
    LOGGER.debug(f'got all done {x_vector.shape} {y_vector.shape}')
    sample_point_layer.CommitTransaction()
    return (x_vector.T).astype(numpy.float32), (y_vector.astype(numpy.float32))
Esempio n. 6
0
"""Demo of how to use pandas to multiply one table by another."""
import os

from osgeo import gdal
from osgeo import ogr
from osgeo import osr
import pandas

# Justin said this was his reference
esa_lulc_geotransform = (-180.0, 30 * 0.0027777778, 0.0, 90.0, 0.0,
                         30 * -0.0027777778)
esa_n_cols = 129600 // 30
inv_gt = gdal.InvGeoTransform(esa_lulc_geotransform)

base_table_path = '1_test_data.csv'
lasso_table_path = 'lasso_interacted_not_forest_gs1to100_params.csv'

print('reading')
base_table_df = pandas.read_csv(base_table_path)
lasso_df = pandas.read_csv(lasso_table_path)

target_df = pandas.DataFrame()

gpkg_driver = ogr.GetDriverByName('GPKG')
base_id = os.path.basename(os.path.splitext(base_table_path)[0])
vector = gpkg_driver.CreateDataSource(f'{base_id}.gpkg')
wgs84_srs = osr.SpatialReference()
wgs84_srs.ImportFromEPSG(4326)
layer = vector.CreateLayer(base_id, wgs84_srs, geom_type=ogr.wkbPoint)
layer_def = layer.GetLayerDefn()
    def make_raster(self, zoom):

        #----------------------------

        # adjust raster extents to tile boundaries
        tile_ul, tile_lr = self.corner_tiles(zoom)
        ld('base_raster')
        ld('tile_ul', tile_ul, 'tile_lr', tile_lr)
        ul_c = self.tile_bounds(tile_ul)[0]
        lr_c = self.tile_bounds(tile_lr)[1]
        ul_pix = self.tile_pixbounds(tile_ul)[0]
        lr_pix = self.tile_pixbounds(tile_lr)[1]

        # base zoom level raster size
        dst_xsize = lr_pix[0] - ul_pix[0]
        dst_ysize = lr_pix[1] - ul_pix[1]

        ld('target Upper Left', self.bounds[0], ul_c,
           self.proj2geog.transform([self.bounds[0], ul_c]))
        ld('target Lower Right', self.bounds[1], lr_c,
           self.proj2geog.transform([self.bounds[1], lr_c]))

        # create VRT for base image warp

        # generate warp transform
        src_geotr = self.src_ds.GetGeoTransform()
        src_proj = txt2proj4(self.src_ds.GetProjection())
        gcp_proj = None

        if not self.options.tps and src_geotr and src_geotr != (0.0, 1.0, 0.0,
                                                                0.0, 0.0, 1.0):
            ok, src_igeotr = gdal.InvGeoTransform(src_geotr)
            assert ok
            src_transform = '%s\n%s' % (warp_src_geotr % src_geotr,
                                        warp_src_igeotr % src_igeotr)
        else:
            gcps = self.src_ds.GetGCPs()
            assert gcps, 'Neither geotransform, nor gpcs are in the source file %s' % self.src

            gcp_lst = [(g.Id, g.GCPPixel, g.GCPLine, g.GCPX, g.GCPY, g.GCPZ)
                       for g in gcps]
            ld('src_proj', self.src_ds.GetProjection(), 'gcp_proj',
               self.src_ds.GetGCPProjection())
            gcp_proj = txt2proj4(self.src_ds.GetGCPProjection())
            if src_proj and gcp_proj != src_proj:
                coords = GdalTransformer(SRC_SRS=gcp_proj,
                                         DST_SRS=src_proj).transform(
                                             [g[3:6] for g in gcp_lst])
                gcp_lst = [tuple(p[:3] + c) for p, c in zip(gcp_lst, coords)]

            gcp_txt = '\n'.join((gcp_templ % g for g in gcp_lst))
            #src_transform = warp_src_gcp_transformer % (0, gcp_txt)
            src_transform = warp_src_tps_transformer % gcp_txt

        res = self.zoom2res(zoom)
        #ul_ll, lr_ll = self.coords2longlat([ul_c, lr_c])
        ld('max_zoom', zoom, 'size', dst_xsize, dst_ysize, '-tr', res[0],
           res[1], '-te', ul_c[0], lr_c[1], lr_c[0], ul_c[1], '-t_srs',
           self.proj_srs)
        dst_geotr = (ul_c[0], res[0], 0.0, ul_c[1], 0.0, res[1])
        ok, dst_igeotr = gdal.InvGeoTransform(dst_geotr)
        assert ok
        dst_transform = '%s\n%s' % (warp_dst_geotr % dst_geotr,
                                    warp_dst_igeotr % dst_igeotr)

        # generate warp options
        warp_options = []

        def w_option(name, value):  # warp options template
            return '    <Option name="%s">%s</Option>' % (name, value)

        warp_options.append(w_option('INIT_DEST', 'NO_DATA'))

        # generate cut line
        if self.options.cut or self.options.cutline:
            cut_wkt = self.get_cutline()
        else:
            cut_wkt = None
        if cut_wkt:
            warp_options.append(w_option('CUTLINE', cut_wkt))
            if self.options.blend_dist:
                warp_options.append(
                    w_option('CUTLINE_BLEND_DIST', self.options.blend_dist))

        src_bands = self.src_ds.RasterCount
        ld('src_bands', src_bands)

        # process nodata info
        src_nodata = None
        if self.options.src_nodata:
            src_nodata = map(int, self.options.src_nodata.split(','))
            assert len(src_nodata
                       ) == src_bands, 'Nodata must match the number of bands'
            if src_bands > 1:
                warp_options.append(w_option('UNIFIED_SRC_NODATA', 'YES'))
        dst_nodata = None
        if self.palette is not None:
            dst_nodata = [self.transparency]
        ld('nodata', src_nodata, dst_nodata)

        # src raster bands mapping
        vrt_bands = []
        wo_BandList = []
        for i in range(src_bands):
            vrt_bands.append(warp_band % (i + 1, '/'))
            if src_nodata or dst_nodata:
                band_mapping_info = warp_band_mapping_nodata % (
                    warp_band_src_nodata %
                    (src_nodata[i], 0) if src_nodata else '',
                    warp_band_dst_nodata %
                    (dst_nodata[i], 0) if dst_nodata else '')
            else:
                band_mapping_info = '/'
            wo_BandList.append(warp_band_mapping %
                               (i + 1, i + 1, band_mapping_info))

        if src_bands < 4 and self.palette is None:
            vrt_bands.append(warp_band %
                             (src_bands + 1, warp_band_color % 'Alpha'))

        vrt_text = warp_vrt % {
            'xsize':
            dst_xsize,
            'ysize':
            dst_ysize,
            'srs':
            self.proj_srs,
            'geotr':
            geotr_templ % dst_geotr,
            'band_list':
            '\n'.join(vrt_bands),
            'blxsize':
            abs(self.tile_dim[0]),
            'blysize':
            abs(self.tile_dim[1]),
            'wo_ResampleAlg':
            self.base_resampling,
            'wo_src_path':
            cgi.escape(self.src_path, quote=True),
            'warp_options':
            '\n'.join(warp_options),
            'wo_src_srs':
            gcp_proj if gcp_proj else src_proj,
            'wo_dst_srs':
            self.proj_srs,
            'wo_src_transform':
            src_transform,
            'wo_dst_transform':
            dst_transform,
            'wo_BandList':
            '\n'.join(wo_BandList),
            'wo_DstAlphaBand':
            warp_dst_alpha_band %
            (src_bands + 1) if src_bands < 4 and self.palette is None else '',
            'wo_Cutline': (warp_cutline % cut_wkt) if cut_wkt else '',
        }

        temp_vrt = os.path.join(self.dest,
                                self.base + '.tmp.vrt')  # auxilary VRT file
        self.temp_files.append(temp_vrt)
        with open(temp_vrt, 'w') as f:
            f.write(vrt_text.encode('utf-8'))

        # warp base raster
        base_ds = gdal.Open(vrt_text, GA_ReadOnly)
        self.progress()

        # close datasets in a proper order
        del self.src_ds

        # create base_image raster
        self.base_img = BaseImg(base_ds, ul_pix, self.transparency)
Esempio n. 8
0
@author: Stadnicki Mateusz
"""

from osgeo import ogr, gdal
import math

min_width = math.inf
max_width = -math.inf

dem = gdal.Open("lubelskie.tif")
band = dem.GetRasterBand(1)
miasta = ogr.Open("miasta.shp")

open_gt = dem.GetGeoTransform()
transform = gdal.InvGeoTransform(open_gt)

array = band.ReadAsArray()
warstwa = miasta.GetLayer()

for lokalizacje in warstwa:
    geom = lokalizacje.GetGeometryRef()

    x = geom.GetX()
    y = geom.GetY()

    kolumna, wiersz = gdal.ApplyGeoTransform(transform, x, y)
    kolumna = int(kolumna)
    wiersz = int(wiersz)
    wysokosc = array[wiersz, kolumna]
Esempio n. 9
0
    in_band = in_ds.GetRasterBand(1)
    # nodata = in_band.GetNoDataValue()
    num_pixels_x_bnd = int(in_band.XSize)
    num_pixels_y_bnd = int(in_band.YSize)
    # print("Pixels X %d Pixels Y %d" % (num_pixels_x_bnd, num_pixels_y_bnd))

    # ATTENZIONE GetGeoTransform dal file aperto con Open non da GetRasterBand
    parametri_geotransform = in_ds.GetGeoTransform()
    origine_x = int(parametri_geotransform[0])
    origine_y = int(parametri_geotransform[3])
    print("Origine X %d Origine Y %d" % (origine_x, origine_y))
    print("Pixelsize X %d Pixelsize Y %d" %
          (parametri_geotransform[1], parametri_geotransform[5]))

    geotransform_inversa = gdal.InvGeoTransform(parametri_geotransform)
    # Converte coordinate in pixel
    conversion_pixel = gdal.ApplyGeoTransform(geotransform_inversa, 250000,
                                              4500000)

    # Converte pixel in coordinate
    conversion_coords = gdal.ApplyGeoTransform(parametri_geotransform,
                                               origine_taglio_x,
                                               origine_taglio_y)
    xoff, yoff = map(int, conversion_pixel)
    geo_transform = (conversion_coords[0], parametri_geotransform[1], 0,
                     conversion_coords[1], 0, parametri_geotransform[5]
                     )  # complete random/arbitrary numbers

    in_data = in_band.ReadAsArray(origine_taglio_x, origine_taglio_y,
                                  offset_taglio_x,
Esempio n. 10
0
def min_max_heights_from_bbx(im, lon_m, lon_M, lat_m, lat_M, rpc):
    """
    Compute min, max heights from bounding box

    Args:
        im: path to an image file
        lon_m, lon_M, lat_m, lat_M: bounding box

    Returns:
        hmin, hmax: min, max heights
    """

    # open image
    dataset = gdal.Open(im)

    # get lon/lat to im projection conversion
    new_cs = osr.SpatialReference()
    new_cs.ImportFromWkt(dataset.GetProjectionRef())
    old_cs = osr.SpatialReference()
    old_cs.ImportFromEPSG(4326)
    lonlat_to_im = osr.CoordinateTransformation(old_cs, new_cs)

    # convert lon/lat to im projection
    lon = np.linspace(lon_m, lon_M, 2)
    lat = np.linspace(lat_m, lat_M, 2)
    lonv, latv = np.meshgrid(lon, lat)
    lonlatalt = zip(np.ravel(lonv),
                    np.ravel(latv),
                    np.zeros(np.shape(np.ravel(lonv))))
    x_im_proj, y_im_proj, __ = (zip(*lonlat_to_im.TransformPoints([a for a in lonlatalt])))
    x_im_proj = np.array(x_im_proj)
    y_im_proj = np.array(y_im_proj)

    # convert im projection to pixel
    forward = dataset.GetGeoTransform()
    reverse = gdal.InvGeoTransform(forward)
    px = reverse[0] + x_im_proj * reverse[1] + y_im_proj * reverse[2]
    py = reverse[3] + x_im_proj * reverse[4] + y_im_proj * reverse[5]
    nb_elts = len(px)

    # get footprint
    [px_min, px_max, py_min, py_max] = map(int, [np.amin(px),
                                                 np.amax(px)+1,
                                                 np.amin(py),
                                                 np.amax(py)+1])

    # limits of im extract
    x, y, w, h = px_min, py_min, px_max - px_min + 1, py_max - py_min + 1
    sizex = dataset.RasterXSize
    sizey = dataset.RasterYSize
    x0 = min(max(0, x), sizex-1)
    y0 = min(max(0, y), sizey-1)
    w -= (x0-x)
    h -= (y0-y)
    w = max(0, w)
    w = min(w, sizex - 1 - x0)
    h = max(0, h)
    h = min(h, sizey - 1 - y0)

    # get value for each pixel
    if (w != 0) and (h != 0):
        band = dataset.GetRasterBand(1)
        array = band.ReadAsArray(x0, y0, w, h).astype(float)
        array[array == -32768] = np.nan
        hmin = np.nanmin(array)
        hmax = np.nanmax(array)

        if cfg['exogenous_dem_geoid_mode'] is True:
            geoid = geographiclib.geoid_above_ellipsoid((lat_m + lat_M)/2, (lon_m + lon_M)/2)
            hmin += geoid
            hmax += geoid
        return hmin, hmax
    else:
        print("WARNING: rpc_utils.min_max_heights_from_bbx: access window out of range")
        print("returning coarse range from rpc")
        return altitude_range_coarse(rpc, cfg['rpc_alt_range_scale_factor'])
Esempio n. 11
0
    # (X, Y, height) = ct.TransformPoint(lon, lat)
    #
    # geomatrix = ds.GetGeoTransform()
    # inv_geometrix = gdal.InvGeoTransform(geomatrix)
    # x = int(inv_geometrix[0] + inv_geometrix[1] * X + inv_geometrix[2] * Y)
    # y = int(inv_geometrix[3] + inv_geometrix[4] * X + inv_geometrix[5] * Y)

    # --
    # src = osr.SpatialReference()
    # src.SetWellKnownGeogCS("WGS84")
    #
    # projection = dataset.GetProjection()
    # dst = osr.SpatialReference(projection)
    #
    # ct = osr.CoordinateTransformation(src, dst)
    # xy = ct.TransformPoint(lon, lat)
    #
    # x = (xy[0] - geotransform[0]) / geotransform[1]
    # y = (xy[1] - geotransform[3]) / geotransform[5]

    # --
    tr = dataset.GetGeoTransform()
    itr = gdal.InvGeoTransform(tr)

    x = int(itr[0] + itr[1] * lon + itr[2] * lat)
    y = int(itr[3] + itr[4] * lon + itr[5] * lat)

    print("XXX")


Esempio n. 12
0
def stitch_raster(lock_map, cpu_semaphore, payload,
                  raster_id_to_global_stitch_path_map):
    """Stitch incoming country rasters into global raster.

    Parameters:
        lock_map (dict): maps global raster paths to locks so we don't
        cpu_semaphore (BoundedSemaphore): release this when stitch is done
        payload (tuple): payloads come in as an alert that a sub raster
            is ready for stitching into the global raster. Payloads are of the
            form (bin_raster_path,(raster_id, aggregate_vector_id, nodataflag))
            is indexed into
            `raster_id_to_global_stitch_path_map[
                (raster_id, aggregate_id, nodata_flag)]`.
        raster_id_to_global_stitch_path_map (dict): dictionary indexed by
            raster id, aggregate id, and nodata flag tuple to the global
            raster.

    """
    local_tile_raster_path, raster_aggregate_nodata_id_tuple = payload
    global_stitch_raster_path = raster_id_to_global_stitch_path_map[
        raster_aggregate_nodata_id_tuple]

    # get ul of tile and figure out where it goes in global
    local_tile_info = pygeoprocessing.get_raster_info(local_tile_raster_path)
    global_stitch_info = pygeoprocessing.get_raster_info(
        global_stitch_raster_path)
    global_inv_gt = gdal.InvGeoTransform(global_stitch_info['geotransform'])
    local_gt = local_tile_info['geotransform']
    global_i, global_j = gdal.ApplyGeoTransform(global_inv_gt, local_gt[0],
                                                local_gt[3])

    for offsect_dict, local_array in pygeoprocessing.iterblocks(
        (local_tile_raster_path, 1)):
        valid_mask = ~numpy.isclose(local_array, local_tile_info['nodata'][0])
        if valid_mask.size > 0:
            with lock_map[global_stitch_raster_path]:
                global_raster = gdal.OpenEx(global_stitch_raster_path,
                                            gdal.OF_RASTER | gdal.GA_Update)

                LOGGER.debug('stitching this %s into this %s', payload,
                             global_stitch_raster_path)
                global_band = global_raster.GetRasterBand(1)
                local_i = global_i + offsect_dict['xoff']
                local_j = global_j + offsect_dict['yoff']
                global_array = global_band.ReadAsArray(
                    xoff=local_i,
                    yoff=local_j,
                    win_xsize=local_array.shape[1],
                    win_ysize=local_array.shape[0])
                global_array[valid_mask] = local_array[valid_mask]
                win_ysize_write, win_xsize_write = global_array.shape
                if win_ysize_write == 0 or win_xsize_write == 0:
                    raise ValueError('got zeros on sizes: %d %d %s',
                                     win_ysize_write, win_xsize_write, payload)
                if local_i + win_xsize_write >= global_band.XSize:
                    win_xsize_write = int(global_band.XSize - local_i)
                if local_j + win_ysize_write >= global_band.YSize:
                    win_ysize_write = int(global_band.YSize - local_j)

                global_band.WriteArray(global_array[0:win_ysize_write,
                                                    0:win_xsize_write],
                                       xoff=local_i,
                                       yoff=local_j)
                global_band.FlushCache()
                global_band = None
                global_raster = None

    # update the done database
    if raster_aggregate_nodata_id_tuple[2] == '':
        sql_string = '''
            UPDATE job_status
                SET
                  stitched_bin=1
                WHERE
                    bin_raster_path=? AND raster_id=? AND
                    aggregate_vector_id=?
            '''
    else:
        sql_string = '''
            UPDATE job_status
                SET
                  stitched_bin_nodata0=1
                WHERE
                    bin_nodata0_raster_path=? AND raster_id=? AND
                    aggregate_vector_id=?
            '''
    LOGGER.debug(
        'update the database with this command %s\nand these data:%s',
        sql_string, [
            local_tile_raster_path, raster_aggregate_nodata_id_tuple[0],
            raster_aggregate_nodata_id_tuple[1]
        ])
    _execute_sqlite(sql_string,
                    WORK_DATABASE_PATH,
                    mode='modify',
                    execute='execute',
                    argument_list=[
                        local_tile_raster_path,
                        raster_aggregate_nodata_id_tuple[0],
                        raster_aggregate_nodata_id_tuple[1]
                    ])
    cpu_semaphore.release()
Esempio n. 13
0
 def geotransform(self, value):
     self._geotransform = value
     self._invgeotransform = gdal.InvGeoTransform(value)
Esempio n. 14
0
# Script to subset a raster using a VRT.

import os
from osgeo import gdal

# Change your directory.
os.chdir(r'D:\osgeopy-data\Landsat\Washington')

# Open the original raster and get its geotransform info.
tmp_ds = gdal.Open('nat_color.tif')
tmp_gt = tmp_ds.GetGeoTransform()
inv_gt = gdal.InvGeoTransform(tmp_gt)[1]

# Figure out what the new geotransform is.
vashon_ul = (532000, 5262600)
vashon_lr = (548500, 5241500)
ulx, uly = map(int, gdal.ApplyGeoTransform(inv_gt, *vashon_ul))
lrx, lry = map(int, gdal.ApplyGeoTransform(inv_gt, *vashon_lr))
rows = lry - uly
columns = lrx - ulx
gt = list(tmp_gt)
gt[0] += gt[1] * ulx
gt[3] += gt[5] * uly

# Create the output VRT, which is really just an XML file.
ds = gdal.GetDriverByName('vrt').Create('vashon.vrt', columns, rows, 3)
ds.SetProjection(tmp_ds.GetProjection())
ds.SetGeoTransform(gt)

# The XML definition for each band in the output.
xml = '''
Esempio n. 15
0
import georefUtils_py3
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import pdb
import struct

numPointCorrespondences = 100
#print("\nYou can find your UTM zone here: http://www.latlong.net/lat-long-utm.html")
utmZone = "2L"
print("Current UTM zone: ", utmZone)


largeAerialPath = "../Images/Aerial_RGB_2012.tif"
aerial_gtif = gdal.Open(largeAerialPath)
aerial_T = aerial_gtif.GetGeoTransform() # Transform to turn pixels to UTM
aerial_Tinv = gdal.InvGeoTransform(aerial_T) # Transform to turn UTM to pixels

Transect1Path = "../Images/July29_High_res_flight_2_60frames_FL_2D.tif"
transect1_gtif = gdal.Open(Transect1Path)
print("Size of Transect1 {} x {} x {}".format(transect1_gtif.RasterXSize,
                                     transect1_gtif.RasterYSize,
                                     transect1_gtif.RasterCount))
Transect1_HiRes = cv2.imread(Transect1Path)
Transect1_HiRes = cv2.cvtColor(Transect1_HiRes[:,:,0:3], cv2.COLOR_BGR2RGB)
# halfway_x = int(Transect1_HiRes.shape[1]/3)
# halfway_y = int(Transect1_HiRes.shape[0]/2)
# Transect1_HiRes = Transect1_HiRes[:halfway_y,halfway_x:,:]

try:
	srcband = aerial_gtif.GetRasterBand(1)
#     print("Band Type={}".format(gdal.GetDataTypeName(srcband.DataType)))
Esempio n. 16
0
def shp_files_to_csv(shp_files: list, raster_ds: gdal.Dataset,
                     out_csv_file) -> list:
    """
    return a list contain the tuple (x, y, class) of the point contain of polygon shp_ds.
    (x, y) is the coords of the shp_ds's spatial reference
    (the same as the raster_ds's spatial reference),
    the first element represent the x value,
    the second element represent the y value,
    the third element represent the class value.
    The class value is the code of one land cover.

    Parameters:
    --------------
    shp_files   - list of shape file(GeometryType is Polygon) Data source
    raster_ds   - raster file Dataset

    Returns:
    -------------
    train_data_coords       - The train data's list contains the  item (x,y, class)

    """

    # 创建一个shp
    train_data_coords = []

    for i in range(len(shp_files)):
        code = i + 1
        shp_ds = ogr.Open(shp_files[i])
        print(shp_files[i])
        # 获取首个图层
        poly_lyr: ogr.Layer = shp_ds.GetLayer(0)
        # 获取shp文件的坐标系
        shp_osr: osr.SpatialReference = poly_lyr.GetSpatialRef()
        shp_osr.GetAttrValue('AUTHORITY', 1)

        # 获取Gtiff文件坐标系
        raster_osr = osr.SpatialReference()  # 获取地理参考系统
        raster_osr.ImportFromWkt(
            raster_ds.GetProjection())  # 从一个WKT定义的坐标系统来构造一个SpatialReference类对象

        # 获取Gtiff文件地理变换
        gtiff_geotrans = raster_ds.GetGeoTransform()

        if raster_osr.GetAttrValue('AUTHORITY', 1) != shp_osr.GetAttrValue(
                'AUTHORITY', 1):
            print(
                'Error: The shape file and the raster file have the differnet spatial refer'
            )
            return train_data_coords

        inv_gt = gdal.InvGeoTransform(gtiff_geotrans)

        # 获取要素的数量
        feat_count = poly_lyr.GetFeatureCount()
        # 保存训练集在栅格上的坐标(X,Y)以及地理编码值(class),需要三列

        # 遍历图层获取每一要素
        for feat_i in range(feat_count):
            # 获取要素
            poly_feat: ogr.Feature = poly_lyr.GetFeature(feat_i)

            # 没有编码值
            # 从要素中获取多边形几何(是一个环)
            poly_geom: ogr.Geometry = poly_feat.geometry()
            if poly_geom.GetGeometryName() != 'POLYGON':
                print(
                    "Error: The geometry type of shape file isn't the polygon."
                )
                break
            for ring_i in range(poly_geom.GetGeometryCount()):
                # 获取多边形几何的第i个环
                ring: ogr.Geometry = poly_geom.GetGeometryRef(ring_i)

                # 获取几何多边形的边界(西东南北)
                left, right, lower, upper = ring.GetEnvelope()
                points = ring.GetPoints()
                # 判断点在多边形上
                # int OGRPolygon::PointOnSurface(OGRPoint * poPoint) const [virtual]
                for px in np.arange(left, right, gtiff_geotrans[1]):
                    for py in np.arange(upper, lower, gtiff_geotrans[5]):
                        # 创建一个点
                        if point_in_poly(px, py, points):
                            offsets = gdal.ApplyGeoTransform(inv_gt, px, py)
                            # 转换为像素坐标(整数值)
                            xoff, yoff = map(int, offsets)
                            train_data_coords.append(
                                (xoff, yoff, px, py, code))
                            #train_data_coords.append((px, py, code))
        df = pd.DataFrame(train_data_coords,
                          columns=['xoff', 'yoff', 'px', 'py', 'class'])
        df.to_csv(out_csv_file)
        del shp_ds
    print('train.csv have successfully write in.')
    return train_data_coords
Esempio n. 17
0
def pixel_xy(cd, mX, mY):
    gdata = gdal.Open(cd)
    gt = gdata.GetGeoTransform()
    (px, py) = gdal.ApplyGeoTransform(gdal.InvGeoTransform(gt), mX, mY)
    return int(px), int(py)
Esempio n. 18
0
def shp_file_to_csv(shp_ds: ogr.DataSource, raster_ds: gdal.Dataset) -> list:
    """
    return a list contain the tuple (x, y, class) of the point contain of polygon shp_ds.
    (x, y) is the coords of the shp_ds's spatial reference
    (the same as the raster_ds's spatial reference),
    the first element represent the x value,
    the second element represent the y value,
    the third element represent the class value.
    The class value is the code of one land cover.

    Parameters:
    --------------
    shp_ds      - shape file(GeometryType is Polygon) Data source
    raster_ds   - raster file Dataset

    Returns:
    -------------
    train_data_coords       - The train data's list contains the  item (x,y, class)

    """

    # 创建一个shp
    train_data_coords = []

    # 获取首个图层
    poly_lyr: ogr.Layer = shp_ds.GetLayer(0)
    # 获取shp文件的坐标系
    shp_osr: osr.SpatialReference = poly_lyr.GetSpatialRef()
    shp_osr.GetAttrValue('AUTHORITY', 1)  # ??? 获取对象属性值

    # 获取Gtiff文件坐标系
    raster_osr = osr.SpatialReference()
    raster_osr.ImportFromWkt(raster_ds.GetProjection())

    # 获取Gtiff文件地理变换
    gtiff_geotrans = raster_ds.GetGeoTransform()

    if raster_osr.GetAttrValue('AUTHORITY', 1) != shp_osr.GetAttrValue(
            'AUTHORITY', 1):
        print(
            'Error: The shape file and the raster file have the differnet spatial refer'
        )
        return train_data_coords

    inv_gt = gdal.InvGeoTransform(gtiff_geotrans)

    # 获取要素的数量
    feat_count = poly_lyr.GetFeatureCount()
    # 保存训练集在栅格上的坐标(X,Y)以及地理编码值(class),需要三列

    # 遍历图层获取每一要素
    for feat_i in range(feat_count):
        # 获取要素
        poly_feat: ogr.Feature = poly_lyr.GetFeature(feat_i)

        # 提取类别编码值
        if 'class' not in poly_feat.keys():
            print("Error: The shape file don't have the 'class' Field")
            break
        name = poly_feat.GetField('class')
        # 从要素中获取多边形几何(是一个环)
        poly_geom: ogr.Geometry = poly_feat.geometry()
        if poly_geom.GetGeometryName() != 'POLYGON':
            print("Error: The geometry type of shape file isn't the polygon.")
            break
        for ring_i in range(poly_geom.GetGeometryCount()):
            # 获取多边形几何的第i个环
            ring: ogr.Geometry = poly_geom.GetGeometryRef(ring_i)

            # 获取几何多边形的边界(西东南北)
            left, right, lower, upper = ring.GetEnvelope()
            points = ring.GetPoints()
            # 判断点在多边形上
            # int OGRPolygon::PointOnSurface(OGRPoint * poPoint) const [virtual]
            for px in np.arange(left, right, gtiff_geotrans[1]):
                for py in np.arange(upper, lower, gtiff_geotrans[5]):
                    # 创建一个点
                    if point_in_poly(px, py, points):
                        offsets = gdal.ApplyGeoTransform(inv_gt, px, py)
                        # 转换为像素坐标(整数值)
                        xoff, yoff = map(int, offsets)
                        train_data_coords.append((xoff, yoff, px, py, name))
                        train_data_coords.append((px, py, name))
    return train_data_coords
Esempio n. 19
0
def overlapArea(src_ds, mask_ds):
    # 获取影像的投影和转换参数
    src_geo = src_ds.GetGeoTransform()
    mask_geo = mask_ds.GetGeoTransform()
    # 获取影像的四角坐标
    src_corner = Corner_coordinates(src_ds)
    mask_corner = Corner_coordinates(mask_ds)
    # 获取逆仿射变换的参数
    src_inv_geo = gdal.InvGeoTransform(src_geo)
    # 将mask的角点坐标映射到src图像上
    # 左上
    src_off_ulx, src_off_uly = map(
        round,
        gdal.ApplyGeoTransform(src_inv_geo, mask_corner[0], mask_corner[1]))
    # 右上
    src_off_urx, src_off_ury = map(
        round,
        gdal.ApplyGeoTransform(src_inv_geo, mask_corner[2], mask_corner[3]))
    # 左下
    src_off_dlx, src_off_dly = map(
        round,
        gdal.ApplyGeoTransform(src_inv_geo, mask_corner[4], mask_corner[5]))
    # 右下
    src_off_drx, src_off_dry = map(
        round,
        gdal.ApplyGeoTransform(src_inv_geo, mask_corner[6], mask_corner[7]))
    # # 获取被检测影像的行列数
    x_size = src_ds.RasterXSize
    y_size = src_ds.RasterYSize
    # 判断是否有重叠区域
    if min(src_off_ulx, src_off_urx, src_off_dlx, src_off_drx) >= x_size or \
            min(src_off_uly, src_off_ury, src_off_dly, src_off_dry) >= y_size or \
            max(src_off_ulx, src_off_urx, src_off_dlx, src_off_drx) <= 0 or \
            max(src_off_uly, src_off_ury, src_off_dly, src_off_dry) <= 0:
        sys.exit("Have no overlap")
    # 获取重叠区域
    # 列
    offset_column = np.array(
        [src_off_ulx, src_off_dlx, src_off_urx, src_off_drx])
    offset_column = np.maximum((np.minimum(offset_column, x_size)), 0)
    # 行
    offset_line = np.array(
        [src_off_uly, src_off_ury, src_off_dly, src_off_dry])
    offset_line = np.maximum((np.minimum(offset_line, x_size)), 0)
    # 在src影像上重叠区域的行列号
    # 左上
    src_offset_ulx = min(offset_column[0], offset_column[1])
    src_offset_uly = min(offset_line[0], offset_line[1])
    # 右下
    src_offset_drx = max(offset_column[2], offset_column[3])
    src_offset_dry = max(offset_line[2], offset_line[3])
    # 计算重叠区域行列数
    columns = src_offset_drx - src_offset_ulx
    rows = src_offset_dry - src_offset_uly
    # 计算重叠区域在src影像上对应的坐标
    # 左上
    src_ulx, src_uly = gdal.ApplyGeoTransform(src_geo, src_offset_ulx,
                                              src_offset_uly)
    # 右下
    src_drx, src_dry = gdal.ApplyGeoTransform(src_geo, src_offset_drx,
                                              src_offset_dry)

    return 1
def compute_viewshed(input_array, visibility_uri, in_structure_uri, \
    cell_size, rows, cols, nodata, GT, I_uri, J_uri, curvature_correction, \
    refr_coeff, args):
    """ array-based function that computes the viewshed as is defined in ArcGIS
    """
    # default parameter values that are not passed to this function but that
    # scenic_quality_core.viewshed needs
    obs_elev = 1.0  # Observator's elevation in meters
    tgt_elev = 0.0  # Extra elevation applied to all the DEM
    max_dist = -1.0  # max. viewing distance(m). Distance is infinite if negative
    coefficient = 1.0  # Used to weight the importance of individual viewsheds
    height = 0.0  # Per viewpoint height offset--updated as we read file info

    #input_raster = gdal.Open(in_dem_uri)
    #input_band = input_raster.GetRasterBand(1)
    #input_array = input_band.ReadAsArray()
    #input_band = None
    #input_raster = None

    # Compute the distance for each point
    def compute_distance(vi, vj, cell_size):
        def compute(i, j, v):
            if v == 1:
                return ((vi - i)**2 + (vj - j)**2)**.5 * cell_size
            else:
                return -1.

        return compute

    # Apply the valuation functions to the distance
    def polynomial(a, b, c, d, max_valuation_radius):
        def compute(x, v):
            if v == 1:
                if x < 1000:
                    return a + b*1000 + c*1000**2 + d*1000**3 - \
                        (b + 2*c*1000 + 3*d*1000**2)*(1000-x)
                elif x <= max_valuation_radius:
                    return a + b * x + c * x**2 + d * x**3
                else:
                    return 0.
            else:
                return 0.

        return compute

    def logarithmic(a, b, max_valuation_radius):
        def compute(x, v):
            if v == 1:
                if x < 1000:
                    return a + b * math.log(1000) - (b / 1000) * (1000 - x)
                elif x <= max_valuation_radius:
                    return a + b * math.log(x)
                else:
                    return 0.
            else:
                return 0.

        return compute

    # Multiply a value by a constant
    def multiply(c):
        def compute(x):
            return x * c

        return compute

    # Setup valuation function
    a = args["a_coefficient"]
    b = args["b_coefficient"]
    c = args["c_coefficient"]
    d = args["d_coefficient"]

    valuation_function = None
    max_valuation_radius = args['max_valuation_radius']
    if "polynomial" in args["valuation_function"]:
        print("Polynomial")
        valuation_function = polynomial(a, b, c, d, max_valuation_radius)
    elif "logarithmic" in args['valuation_function']:
        print("logarithmic")
        valuation_function = logarithmic(a, b, max_valuation_radius)

    assert valuation_function is not None

    # Make sure the values don't become too small at max_valuation_radius:
    edge_value = valuation_function(max_valuation_radius, 1)
    message = "Valuation function can't be negative if evaluated at " + \
    str(max_valuation_radius) + " meters (value is " + str(edge_value) + ")"
    assert edge_value >= 0., message

    # Base path uri
    base_uri = os.path.split(visibility_uri)[0]

    # Temporary files that will be used
    distance_uri = geoprocessing.temporary_filename()
    viewshed_uri = geoprocessing.temporary_filename()

    # The model extracts each viewpoint from the shapefile
    point_list = []
    shapefile = ogr.Open(in_structure_uri)
    assert shapefile is not None
    layer = shapefile.GetLayer(0)
    assert layer is not None
    iGT = gdal.InvGeoTransform(GT)[1]
    feature_count = layer.GetFeatureCount()
    viewshed_uri_list = []
    print('Number of viewpoints: ' + str(feature_count))
    for f in range(feature_count):
        print("feature " + str(f))
        feature = layer.GetFeature(f)
        field_count = feature.GetFieldCount()
        # Check for feature information (radius, coeff, height)
        for field in range(field_count):
            field_def = feature.GetFieldDefnRef(field)
            field_name = field_def.GetNameRef()
            if (field_name.upper() == 'RADIUS2') or \
                (field_name.upper() == 'RADIUS'):
                max_dist = abs(int(feature.GetField(field)))
                assert max_dist is not None, "max distance can't be None"
                if max_dist < args['max_valuation_radius']:
                    LOGGER.warning( \
                        'Valuation radius > maximum visibility distance: ' + \
                        '(' + str(args['max_valuation_radius']) + ' < ' + \
                        str(max_dist) + ')')
                    LOGGER.warning( \
                        'The valuation is performed beyond what is visible')
                max_dist = int(max_dist / cell_size)
            if field_name.lower() == 'coeff':
                coefficient = float(feature.GetField(field))
                assert coefficient is not None, "feature coeff can't be None"
            if field_name.lower() == 'OFFSETA':
                obs_elev = float(feature.GetField(field))
                assert obs_elev is not None, "OFFSETA can't be None"
            if field_name.lower() == 'OFFSETB':
                tgt_elev = float(feature.GetField(field))
                assert tgt_elev is not None, "OFFSETB can't be None"

        geometry = feature.GetGeometryRef()
        assert geometry is not None
        message = 'geometry type is ' + str(geometry.GetGeometryName()) + \
        ' point is "POINT"'
        assert geometry.GetGeometryName() == 'POINT', message
        x = geometry.GetX()
        y = geometry.GetY()
        j = int((iGT[0] + x * iGT[1] + y * iGT[2]))
        i = int((iGT[3] + x * iGT[4] + y * iGT[5]))

        array_shape = (rows, cols)

        #tmp_visibility_uri = geoprocessing.temporary_filename()
        tmp_visibility_uri = os.path.join(base_uri,
                                          'visibility_' + str(f) + '.tif')
        geoprocessing.new_raster_from_base_uri( \
            visibility_uri, tmp_visibility_uri, 'GTiff', \
            255, gdal.GDT_Float64, fill_value=255)
        scenic_quality_core.viewshed(input_array, cell_size, \
        array_shape, nodata, tmp_visibility_uri, (i,j), obs_elev, tgt_elev, \
        max_dist, refr_coeff)

        # Compute the distance
        #tmp_distance_uri = geoprocessing.temporary_filename()
        tmp_distance_uri = os.path.join(base_uri,
                                        'distance_' + str(f) + '.tif')
        geoprocessing.new_raster_from_base_uri(visibility_uri, \
        tmp_distance_uri, 'GTiff', \
        255, gdal.GDT_Byte, fill_value = 255)
        distance_fn = compute_distance(i, j, cell_size)
        geoprocessing.vectorize_datasets([I_uri, J_uri, tmp_visibility_uri], \
        distance_fn, tmp_distance_uri, gdal.GDT_Float64, -1., cell_size, "union")
        # Apply the valuation function
        #tmp_viewshed_uri = geoprocessing.temporary_filename()
        tmp_viewshed_uri = os.path.join(base_uri,
                                        'viewshed_' + str(f) + '.tif')

        geoprocessing.vectorize_datasets(
            [tmp_distance_uri, tmp_visibility_uri], valuation_function,
            tmp_viewshed_uri, gdal.GDT_Float64, -9999.0, cell_size, "union")

        # Multiply the viewshed by its coefficient
        scaled_viewshed_uri = geoprocessing.temporary_filename()
        #os.path.join(base_uri, 'vshed_' + str(f) + '.tif') #geoprocessing.temporary_filename()
        apply_coefficient = multiply(coefficient)
        geoprocessing.vectorize_datasets([tmp_viewshed_uri], apply_coefficient, \
        scaled_viewshed_uri, gdal.GDT_Float64, 0., cell_size, "union")
        viewshed_uri_list.append(scaled_viewshed_uri)

    layer = None
    shapefile = None

    # Accumulate result to combined raster
    def sum_rasters(*x):
        return np.sum(x, axis=0)

    LOGGER.debug('Summing up everything using vectorize_datasets...')
    LOGGER.debug('visibility_uri' + visibility_uri)
    LOGGER.debug('viewshed_uri_list: ' + str(viewshed_uri_list))
    geoprocessing.vectorize_datasets( \
        viewshed_uri_list, sum_rasters, \
        visibility_uri, gdal.GDT_Float64, -1., cell_size, "union", vectorize_op=False)
Esempio n. 21
0
def gdallocationinfo(
    filename_or_ds: PathOrDS,
    x: NumpyCompatibleArrayOrReal,
    y: NumpyCompatibleArrayOrReal,
    gis_order: bool = False,
    open_options: Optional[dict] = None,
    ovr_idx: Optional[int] = None,
    band_nums: Optional[Sequence[int]] = None,
    srs: CoordinateTransformationOrSRS = None,
    inline_xy_replacement: bool = True,
    quiet_mode: bool = True,
    allow_xy_outside_extent: bool = True,
    pixel_offset: Real = -0.5,
    line_offset: Real = -0.5,
    resample_alg=gdalconst.GRIORA_NearestNeighbour
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:

    ds = open_ds(filename_or_ds, open_options=open_options)
    filename = filename_or_ds if is_path_like(filename_or_ds) else ''
    if ds is None:
        raise Exception(f'Could not open {filename}.')
    if not isinstance(x, NumpyCompatibleArray.__args__):
        x = [x]
    if not isinstance(y, NumpyCompatibleArray.__args__):
        y = [y]
    if len(x) != len(y):
        raise Exception(
            f'len(x)={len(x)} should be the same as len(y)={len(y)}')
    point_count = len(x)

    if not isinstance(x, np.ndarray):
        x = np.ndarray(x)
    if not isinstance(y, np.ndarray):
        y = np.ndarray(y)

    if srs is None:
        srs = LocationInfoSRS.PixelLine

    # Build Spatial Reference object based on coordinate system, fetched from the opened dataset
    if srs != LocationInfoSRS.PixelLine:
        if srs != LocationInfoSRS.SameAsDS_SRS:
            ds_srs = ds.GetSpatialRef()
            ct = None
            if isinstance(srs, osr.CoordinateTransformation):
                ct = srs
            else:
                if srs == LocationInfoSRS.SameAsDS_SRS_GeogCS:
                    points_srs = ds_srs.CloneGeogCS()
                else:
                    points_srs = get_srs(srs, gis_order=gis_order)
                ct = get_transform(points_srs, ds_srs)
            x, y, _z = transform_points(ct, x, y)

        # Read geotransform matrix and calculate corresponding pixel coordinates
        geomatrix = ds.GetGeoTransform()
        inv_geometrix = gdal.InvGeoTransform(geomatrix)
        if inv_geometrix is None:
            raise Exception("Failed InvGeoTransform()")

        x, y = \
            (inv_geometrix[0] + inv_geometrix[1] * x + inv_geometrix[2] * y), \
            (inv_geometrix[3] + inv_geometrix[4] * x + inv_geometrix[5] * y)

    xsize, ysize = ds.RasterXSize, ds.RasterYSize
    bands = get_bands(ds, band_nums, ovr_idx=ovr_idx)
    ovr_xsize, ovr_ysize = bands[0].XSize, bands[0].YSize
    pixel_fact, line_fact = (ovr_xsize / xsize,
                             ovr_ysize / ysize) if ovr_idx else (1, 1)
    bnd_count = len(bands)

    shape = (bnd_count, point_count)
    np_dtype, np_dtype = GDALTypeCodeAndNumericTypeCodeFromDataSet(ds)
    results = np.empty(shape=shape, dtype=np_dtype)

    check_outside = not quiet_mode or not allow_xy_outside_extent
    if check_outside and (np.any(x < 0) or np.any(x >= xsize) or np.any(y < 0)
                          or np.any(y >= ysize)):
        msg = 'Passed coordinates are not in dataset extent!'
        if not allow_xy_outside_extent:
            raise Exception(msg)
        elif not quiet_mode:
            print(msg)

    pixels = np.clip(x * pixel_fact + pixel_offset,
                     0,
                     ovr_xsize - 1,
                     out=x if inline_xy_replacement else None)
    lines = np.clip(y * line_fact + line_offset,
                    0,
                    ovr_ysize - 1,
                    out=y if inline_xy_replacement else None)

    for idx, (pixel, line) in enumerate(zip(pixels, lines)):
        for bnd_idx, band in enumerate(bands):
            val = band.ReadAsArray(pixel,
                                   line,
                                   1,
                                   1,
                                   resample_alg=resample_alg)
            val = val[0][0]
            results[bnd_idx][idx] = val

    is_scaled, scales, offsets = get_scales_and_offsets(bands)
    if is_scaled:
        for bnd_idx, scale, offset in enumerate(zip(scales, offsets)):
            results[bnd_idx] = results[bnd_idx] * scale + offset

    return pixels, lines, results
Esempio n. 22
0
def process_quad(quad_uri, quad_id, dams_database_path):
    """Process quad into bounding box annotated chunks.

    Parameters:
        quad_uri (str): gs:// path to quad to download.
        quad_id (str): ID in the database so work can be updated.
        dams_database_path (str): path to the database that can be
            updated to include the processing state complete and the
            quad processed.

    Returns:
        True when complete.

    """
    task_graph = taskgraph.TaskGraph(WORKSPACE_DIR, -1)
    quad_raster_path = os.path.join(TRAINING_IMAGERY_DIR,
                                    os.path.basename(quad_uri))
    download_quad_task = task_graph.add_task(
        func=copy_from_gs,
        args=(quad_uri, quad_raster_path),
        target_path_list=[quad_raster_path],
        task_name='download %s' % quad_uri)
    download_quad_task.join()
    quad_info = pygeoprocessing.get_raster_info(quad_raster_path)
    n_cols, n_rows = quad_info['raster_size']

    # extract the bounding boxes
    bb_srs = osr.SpatialReference()
    bb_srs.ImportFromEPSG(4326)

    bounding_box_blob_list = _execute_sqlite('''
        SELECT bounding_box
        FROM quad_bounding_box_uri_table
        WHERE quad_id=?
        ''',
                                             dams_database_path,
                                             argument_list=[quad_id],
                                             fetch='all')
    working_dam_bb_list = []  # will be used to collapose duplicates later
    for index, (bounding_box_blob, ) in enumerate(bounding_box_blob_list):
        bounding_box = pickle.loads(bounding_box_blob)
        LOGGER.debug('%s: %s', quad_uri, bounding_box)

        local_bb = pygeoprocessing.transform_bounding_box(
            bounding_box,
            bb_srs.ExportToWkt(),
            quad_info['projection'],
            edge_samples=11)

        inv_gt = gdal.InvGeoTransform(quad_info['geotransform'])
        ul_i, ul_j = [
            int(x)
            for x in gdal.ApplyGeoTransform(inv_gt, local_bb[0], local_bb[1])
        ]
        lr_i, lr_j = [
            int(x)
            for x in gdal.ApplyGeoTransform(inv_gt, local_bb[2], local_bb[3])
        ]
        ul_i, lr_i = sorted([ul_i, lr_i])
        ul_j, lr_j = sorted([ul_j, lr_j])

        # possible the dam may lie outside of the quad, if so clip to the
        # edge of the quad
        if ul_j < 0:
            ul_j = 0
        if ul_i < 0:
            ul_i = 0
        if lr_i >= n_cols:
            lr_i = n_cols - 1
        if lr_j >= n_rows:
            lr_j = n_rows - 1

        # if < 0.5 ratio, bump up to 0.5 ratio
        bb_xsize = max(1, lr_i - ul_i)
        bb_ysize = max(1, lr_j - ul_j)
        if bb_xsize / bb_ysize < 0.5:
            delta_xsize = max(2, 0.5 * bb_ysize - bb_xsize)
            ul_i -= delta_xsize / 2
            lr_i += delta_xsize / 2
        elif bb_ysize / bb_xsize < 0.5:
            delta_ysize = max(2, 0.5 * bb_xsize - bb_ysize)
            ul_j -= delta_ysize / 2
            lr_j += delta_ysize / 2
        dam_bb = [ul_i, ul_j, lr_i, lr_j]

        # this is a sanity check
        if ul_i >= n_cols or ul_j >= n_rows or lr_i < 0 or lr_j < 0:
            raise ValueError(
                'transformed coordinates outside of raster bounds: '
                'lat/lng: %s\nlocal: %sraster_bb: %s\ntransformed: %s' %
                (bounding_box, local_bb, quad_info['bounding_box'], dam_bb))

        working_dam_bb_list.append(dam_bb)

    bounding_box_rtree = rtree.index.Index()
    index_to_bb_list = []
    while working_dam_bb_list:
        current_bb = shapely.geometry.box(*working_dam_bb_list.pop())
        for index in range(len(working_dam_bb_list) - 1, -1, -1):
            test_bb = shapely.geometry.box(*working_dam_bb_list[index])
            if current_bb.intersects(test_bb):
                current_bb = current_bb.union(test_bb)
                del working_dam_bb_list[index]
        LOGGER.debug('going to insert this: %s',
                     str((len(index_to_bb_list), current_bb.bounds)))
        bounding_box_rtree.insert(len(index_to_bb_list), current_bb.bounds)
        index_to_bb_list.append(current_bb.bounds)

    quad_slice_index = 0
    annotation_string_list = []
    for xoff in range(0, n_cols, TRAINING_IMAGE_DIMS[0]):
        win_xsize = TRAINING_IMAGE_DIMS[0]
        if xoff + win_xsize >= n_cols:
            xoff = n_cols - win_xsize - 1
        for yoff in range(0, n_rows, TRAINING_IMAGE_DIMS[1]):
            win_ysize = TRAINING_IMAGE_DIMS[1]
            if yoff + win_ysize >= n_rows:
                yoff = n_rows - win_ysize - 1

            bb_indexes = list(
                bounding_box_rtree.intersection(
                    (xoff, yoff, xoff + win_xsize, yoff + win_ysize)))

            # see if any of the bounding boxes intersect in which case make
            # a single big one

            if bb_indexes:
                LOGGER.debug('these local bbs at %d %d: %s', xoff, yoff,
                             str(bb_indexes))
                # clip out the png and name after number of bbs per image
                quad_png_path = os.path.join(
                    TRAINING_IMAGERY_DIR, '%d_%s_%d.png' %
                    (len(bb_indexes), quad_id, quad_slice_index))
                quad_slice_index += 1
                try:
                    make_quad_png(quad_raster_path, quad_png_path, xoff, yoff,
                                  win_xsize, win_ysize)
                    # transform local bbs so they're relative to the png
                    for bb_index in bb_indexes:
                        base_bb = list(index_to_bb_list[bb_index])
                        # if the centroid is out of bounds, go with the other
                        # quad that contains it
                        bb_xcentroid = base_bb[0] + (base_bb[2] -
                                                     base_bb[0]) / 2
                        bb_ycentroid = base_bb[1] + (base_bb[3] -
                                                     base_bb[1]) / 2
                        if (bb_xcentroid - xoff < 0 or
                                bb_xcentroid - xoff >= TRAINING_IMAGE_DIMS[0]
                                or bb_ycentroid - yoff < 0 or
                                bb_ycentroid - yoff >= TRAINING_IMAGE_DIMS[1]):
                            continue

                        # make sure it's not tiny
                        if base_bb[2] - base_bb[0] < 16:
                            delta = 16 - (base_bb[2] - base_bb[0])
                            base_bb[0] -= delta // 2
                            base_bb[2] += delta // 2
                        if base_bb[3] - base_bb[1] < 16:
                            delta = 16 - (base_bb[3] - base_bb[1])
                            base_bb[1] -= delta // 2
                            base_bb[3] += delta // 2

                        base_bb[0] = max(0, base_bb[0] - xoff)
                        base_bb[1] = max(0, base_bb[1] - yoff)
                        base_bb[2] = \
                            min(TRAINING_IMAGE_DIMS[0], base_bb[2]-xoff)
                        base_bb[3] = \
                            min(TRAINING_IMAGE_DIMS[1], base_bb[3]-yoff)
                        annotation_string_list.append([
                            '%s,%d,%d,%d,%d,dam' %
                            (quad_png_path, base_bb[0], base_bb[1], base_bb[2],
                             base_bb[3])
                        ])
                except Exception:
                    LOGGER.exception('skipping %s' % quad_raster_path)

    LOGGER.debug('updating annotation table with this: %s',
                 str(annotation_string_list))
    _execute_sqlite('''
        INSERT OR REPLACE INTO annotation_table
            (record)
        VALUES (?);
        ''',
                    dams_database_path,
                    argument_list=annotation_string_list,
                    execute='many',
                    mode='modify')

    _execute_sqlite('''
        UPDATE quad_processing_status
            SET processed=1
        WHERE quad_id=?
        ''',
                    dams_database_path,
                    argument_list=[quad_id],
                    mode='modify')

    task_graph.join()
    task_graph.close()
    os.remove(quad_raster_path)
Esempio n. 23
0
def move(filename, t_srs, s_srs=None, pixel_threshold=None):

    # -------------------------------------------------------------------------
    # Open the file.
    # -------------------------------------------------------------------------
    ds = gdal.Open(filename)

    # -------------------------------------------------------------------------
    # Compute the current (s_srs) locations of the four corners and center
    # of the image.
    # -------------------------------------------------------------------------
    corners_names = [
        'Upper Left', 'Lower Left', 'Upper Right', 'Lower Right', 'Center'
    ]

    corners_pixel_line = [(0, 0, 0), (0, ds.RasterYSize, 0),
                          (ds.RasterXSize, 0, 0),
                          (ds.RasterXSize, ds.RasterYSize, 0),
                          (ds.RasterXSize / 2.0, ds.RasterYSize / 2.0, 0.0)]

    orig_gt = ds.GetGeoTransform()

    corners_s_geo = []
    for item in corners_pixel_line:
        corners_s_geo.append( \
            (orig_gt[0] + item[0] * orig_gt[1] + item[1] * orig_gt[2],
             orig_gt[3] + item[0] * orig_gt[4] + item[1] * orig_gt[5],
             item[2]) )

    # -------------------------------------------------------------------------
    # Prepare a transformation from source to destination srs.
    # -------------------------------------------------------------------------
    if s_srs is None:
        s_srs = ds.GetProjectionRef()

    s_srs_obj = osr.SpatialReference()
    s_srs_obj.SetFromUserInput(s_srs)

    t_srs_obj = osr.SpatialReference()
    t_srs_obj.SetFromUserInput(t_srs)

    tr = osr.CoordinateTransformation(s_srs_obj, t_srs_obj)

    # -------------------------------------------------------------------------
    # Transform the corners
    # -------------------------------------------------------------------------

    corners_t_geo = tr.TransformPoints(corners_s_geo)

    # -------------------------------------------------------------------------
    #  Compute a new geotransform for the image in the target SRS.  For now
    #  we just use the top left, top right, and bottom left to produce the
    #  geotransform.  The result will be exact at these three points by
    #  definition, but if the underlying transformation is not affine it will
    #  be wrong at the center and bottom right.  It would be better if we
    #  used all five points for a least squares fit but that is a bit beyond
    #  me for now.
    # -------------------------------------------------------------------------
    ul = corners_t_geo[0]
    ur = corners_t_geo[2]
    ll = corners_t_geo[1]

    new_gt = (ul[0], (ur[0] - ul[0]) / ds.RasterXSize,
              (ll[0] - ul[0]) / ds.RasterYSize, ul[1],
              (ur[1] - ul[1]) / ds.RasterXSize,
              (ll[1] - ul[1]) / ds.RasterYSize)

    inv_new_gt = gdal.InvGeoTransform(new_gt)

    # -------------------------------------------------------------------------
    #  Report results for the five locations.
    # -------------------------------------------------------------------------

    corners_t_new_geo = []
    error_geo = []
    error_pixel_line = []
    corners_pixel_line_new = []

    print(
        '___Corner___ ________Original________  _______Adjusted_________   ______ Err (geo) ______ _Err (pix)_'
    )

    for i in range(len(corners_s_geo)):

        item = corners_pixel_line[i]
        corners_t_new_geo.append(
            (new_gt[0] + item[0] * new_gt[1] + item[1] * new_gt[2],
             new_gt[3] + item[0] * new_gt[4] + item[1] * new_gt[5], item[2]))

        error_geo.append((corners_t_new_geo[i][0] - corners_t_geo[i][0],
                          corners_t_new_geo[i][1] - corners_t_geo[i][1], 0.0))

        item = corners_t_geo[i]
        corners_pixel_line_new.append(
            (inv_new_gt[0] + item[0] * inv_new_gt[1] + item[1] * inv_new_gt[2],
             inv_new_gt[3] + item[0] * inv_new_gt[4] + item[1] * inv_new_gt[5],
             item[2]))

        error_pixel_line.append(
            (corners_pixel_line_new[i][0] - corners_pixel_line[i][0],
             corners_pixel_line_new[i][1] - corners_pixel_line[i][1],
             corners_pixel_line_new[i][2] - corners_pixel_line[i][2]))

        print( '%-11s %s %s %s %5.2f %5.2f' % \
            (corners_names[i],
             fmt_loc(s_srs_obj, corners_s_geo[i]),
             fmt_loc(t_srs_obj, corners_t_geo[i]),
             fmt_loc(t_srs_obj, error_geo[i]),
             error_pixel_line[i][0],
             error_pixel_line[i][1]))

    print('')

    # -------------------------------------------------------------------------
    # Do we want to update the file?
    # -------------------------------------------------------------------------
    max_error = 0
    for err_item in error_pixel_line:
        this_error = math.sqrt(err_item[0] * err_item[0] +
                               err_item[1] * err_item[1])
        if this_error > max_error:
            max_error = this_error

    update = False
    if pixel_threshold is not None:
        if pixel_threshold > max_error:
            update = True

    # -------------------------------------------------------------------------
    # Apply the change coordinate system and geotransform.
    # -------------------------------------------------------------------------
    if update:
        ds = None
        ds = gdal.Open(filename, gdal.GA_Update)

        print('Updating file...')
        ds.SetGeoTransform(new_gt)
        ds.SetProjection(t_srs_obj.ExportToWkt())
        print('Done.')

    elif pixel_threshold is None:
        print(
            'No error threshold in pixels selected with -et, file not updated.'
        )

    else:
        print("""Maximum check point error is %.5f pixels which exceeds the
error threshold so the file has not been updated.""" % max_error)

    ds = None
Esempio n. 24
0
def Geom_Raster_to_np(geom, raster):
    '''
    Function that takes a geometry from a polygon shapefile and a rasterfile, and returns both features as 2d-arryas
    in the size of the geom --> can be later used for masking.
    Function does a coordinate transformation implicitely!

    PARAMETERS
    -----------
    geom : geom object (required)
        geometry of the feature
    raster: gdal object (required)
        raster as a gdal-object (through gdal.Open())

    RETURNS
    -------
    Two numpy-arrays
    (1) np-array of the geometry as binary feature --> values inside the geometry have value '1', values outside '0'
    (2) np-array of the raster in the same size (i.e., as a subset of the raster) of the geometry

    '''
    # Make a coordinate transformation of the geom-srs to the raster-srs
    pol_srs = geom.GetSpatialReference()
    #print(pol_srs)
    ras_srs = raster.GetProjection()
    #print(ras_srs)
    #exit(0)
    target_SR = osr.SpatialReference()
    target_SR.ImportFromWkt(ras_srs)
    srs_trans = osr.CoordinateTransformation(pol_srs, target_SR)
    geom.Transform(srs_trans)
    # Create a memory shp/lyr to rasterize in
    geom_shp = ogr.GetDriverByName('Memory').CreateDataSource('')
    geom_lyr = geom_shp.CreateLayer('geom_shp', srs=geom.GetSpatialReference())
    geom_feat = ogr.Feature(geom_lyr.GetLayerDefn())
    geom_feat.SetGeometryDirectly(ogr.Geometry(wkt=str(geom)))
    geom_lyr.CreateFeature(geom_feat)
    # Rasterize the layer, open in numpy
    #bt.baumiVT.CopySHPDisk(geom_shp, "D:/baumamat/Warfare/_Variables/Forest/_tryout.shp")
    x_min, x_max, y_min, y_max = geom.GetEnvelope()
    gt = raster.GetGeoTransform()
    pr = raster.GetProjection()
    x_res = math.ceil((abs(x_max - x_min)) / gt[1])
    y_res = math.ceil((abs(y_max - y_min)) / gt[1])
    new_gt = (x_min, gt[1], 0, y_max, 0, -gt[1])
    lyr_ras = gdal.GetDriverByName('MEM').Create('', x_res, y_res, 1,
                                                 gdal.GDT_Byte)
    #lyr_ras.GetRasterBand(1).SetNoDataValue(0)
    lyr_ras.SetProjection(pr)
    lyr_ras.SetGeoTransform(new_gt)
    gdal.RasterizeLayer(lyr_ras, [1],
                        geom_lyr,
                        burn_values=[1],
                        options=['ALL_TOUCHED=TRUE'])
    geom_np = np.array(lyr_ras.GetRasterBand(1).ReadAsArray())
    # Now load the raster into the array --> only take the area that is 1:1 the geom-layer (see Garrard p.195)
    inv_gt = gdal.InvGeoTransform(gt)
    offsets_ul = gdal.ApplyGeoTransform(inv_gt, x_min, y_max)
    off_ul_x, off_ul_y = map(int, offsets_ul)
    raster_np = np.array(
        raster.GetRasterBand(1).ReadAsArray(off_ul_x, off_ul_y, x_res, y_res))
    ## Just for checking if the output is correct --> write it to disc. Outcommented here
    #val_ras = gdal.GetDriverByName('MEM').Create('', x_res, y_res, 1, gdal.GDT_UInt16)
    #val_ras.SetProjection(pr)
    #val_ras.SetGeoTransform(new_gt)
    #val_ras.GetRasterBand(1).WriteArray(raster_np, 0, 0)
    #bt.baumiRT.CopyMEMtoDisk(lyr_ras, "E:/Baumann/_ANALYSES/geom.tif")
    #bt.baumiRT.CopyMEMtoDisk(val_ras, "E:/Baumann/_ANALYSES/raster.tif")
    #exit(0)
    return geom_np, raster_np
Esempio n. 25
0
    img = gdal.Open(args.RASTER)
except RuntimeError as e:
    fail(str(e).strip())

# input raster dimensions
w = img.RasterXSize
h = img.RasterYSize
log("raster dimensions = (%s, %s)" % (str(w), str(h)))

# get default transformation from image coordinates to world coordinates
# note that since we obtain this transformation before making any region
# selection, and since this transformation is used for output, subset
# window regions will be aligned correctly in output stl coordinates.
t = img.GetGeoTransform()

git = gdal.InvGeoTransform(t)[1]
log("geo->pixel transform: %s" % str(git))

if args.window is not None:
    # if a geographic window is specified, convert it to a pixel window in input raster coordinates

    # apply inverse geo transform to window points
    px0, py0 = gdal.ApplyGeoTransform(git, args.window[0], args.window[1])
    px1, py1 = gdal.ApplyGeoTransform(git, args.window[2], args.window[3])

    # set arg.pixels to obtained pixel points
    args.pixels = [px0, py0, px1, py1]

if args.pixels is None:
    # if no pixel extent window is specified, use whole input raster.
    xmin = 0
    target_ds = gdal.GetDriverByName('MEM').Create('', x_res, y_res,
                                                   gdal.GDT_Byte)
    target_ds.GetRasterBand(1).SetNoDataValue(-9999)
    target_ds.SetProjection(pr)
    target_ds.SetGeoTransform((x_min, gt[1], 0, y_max, 0, gt[5]))

    # Rasterization
    # to account for small overlaps of polygons in pixels
    gdal.RasterizeLayer(target_ds, [1], ds_lyr, burn_values=[
        1
    ])  #options=['ALL_TOUCHED=TRUE']) --> this part was defect
    target_array = target_ds.ReadAsArray()
    # target_ds = None

    # Convert data from the DEM to the extent of the envelope of the polygon (to array)
    inv_gt = gdal.InvGeoTransform(gt)
    offsets_ul = gdal.ApplyGeoTransform(inv_gt, x_min, y_max)
    off_ul_x, off_ul_y = map(int, offsets_ul)
    raster_np = np.array(
        dem.GetRasterBand(1).ReadAsArray(off_ul_x, off_ul_y, x_res, y_res))

    # Calculate the mean of the array with masking
    test_array = np.ma.masked_where(target_array < 1, target_array)
    raster_masked = np.ma.masked_array(raster_np, test_array.mask)
    dem_mean = np.mean(raster_masked)

    # COL 7: Mean elevation
    print('Mean elevation: ', dem_mean, '\n')

    ##############################
Esempio n. 27
0
    def create_warped_vrt(self, corners=None, res=None):

        #----------------------------

        # generate warp transform
        src_geotr = self.src_ds.GetGeoTransform()
        src_proj = txt2proj4(self.src_ds.GetProjection())
        gcp_proj = None

        if not self.options.tps and src_geotr and src_geotr != (0.0, 1.0, 0.0,
                                                                0.0, 0.0, 1.0):
            ok, src_igeotr = gdal.InvGeoTransform(src_geotr)
            assert ok
            src_transform = '%s\n%s' % (warp_src_geotr % src_geotr,
                                        warp_src_igeotr % src_igeotr)
        else:
            gcps = self.src_ds.GetGCPs()
            assert gcps, 'Neither geotransform, nor gpcs are in the source file %s' % self.src

            gcp_lst = [(g.Id, g.GCPPixel, g.GCPLine, g.GCPX, g.GCPY, g.GCPZ)
                       for g in gcps]
            ld('src_proj', self.src_ds.GetProjection(), 'gcp_proj',
               self.src_ds.GetGCPProjection())
            gcp_proj = txt2proj4(self.src_ds.GetGCPProjection())
            if src_proj and gcp_proj != src_proj:
                coords = GdalTransformer(SRC_SRS=gcp_proj,
                                         DST_SRS=src_proj).transform(
                                             [g[3:6] for g in gcp_lst])

                gcp_lst = [tuple(p[:3] + c) for p, c in zip(gcp_lst, coords)]

            gcp_txt = '\n'.join((gcp_templ % g for g in gcp_lst))
            #src_transform = warp_src_gcp_transformer % (0, gcp_txt)
            src_transform = warp_src_tps_transformer % gcp_txt

        # base zoom level raster size
        tl_c, br_c = corners
        left, top = tl_c
        right, bottom = br_c
        ld('right, left, top, bottom', right, left, top, bottom)
        size = (abs((right - left) / res[0]), abs((top - bottom) / res[0]))

        #tl_ll, br_ll = self.coords2longlat([tl_c, br_c])
        ld('create_target_dataset', 'max_zoom', self.max_zoom, 'size', size[0],
           size[1], '-tr', res[0], res[1], '-te', tl_c[0], br_c[1], br_c[0],
           tl_c[1], '-t_srs', self.proj_srs)

        dst_geotr = (left, res[0], 0.0, top, 0.0, -res[1])
        ok, dst_igeotr = gdal.InvGeoTransform(dst_geotr)
        assert ok
        dst_transform = '%s\n%s' % (warp_dst_geotr % dst_geotr,
                                    warp_dst_igeotr % dst_igeotr)

        # generate warp options
        warp_options = []

        def w_option(name, value):  # warp options template
            return '    <Option name="%s">%s</Option>' % (name, value)

        warp_options.append(w_option('INIT_DEST', 'NO_DATA'))

        # generate cut line
        if self.options.cut or self.options.cutline:
            cut_wkt = self.get_cutline()
        else:
            cut_wkt = None
        if cut_wkt:
            warp_options.append(w_option('CUTLINE', cut_wkt))
            if self.options.blend_dist:
                warp_options.append(
                    w_option('CUTLINE_BLEND_DIST', self.options.blend_dist))

        src_bands = self.src_ds.RasterCount
        ld('src_bands', src_bands)

        # process nodata info
        src_nodata = None
        if self.options.src_nodata:
            src_nodata = map(int, self.options.src_nodata.split(','))
            assert len(src_nodata
                       ) == src_bands, 'Nodata must match the number of bands'
            if src_bands > 1:
                warp_options.append(w_option('UNIFIED_SRC_NODATA', 'YES'))
        dst_nodata = None
        if self.palette is not None:
            dst_nodata = [self.transparency]
        ld('nodata', src_nodata, dst_nodata)

        # src raster bands mapping
        vrt_bands = []
        wo_BandList = []
        for i in range(src_bands):
            vrt_bands.append(warp_band % (i + 1, '/'))
            if src_nodata or dst_nodata:
                band_mapping_info = warp_band_mapping_nodata % (
                    warp_band_src_nodata %
                    (src_nodata[i], 0) if src_nodata else '',
                    warp_band_dst_nodata %
                    (dst_nodata[i], 0) if dst_nodata else '')
            else:
                band_mapping_info = '/'
            wo_BandList.append(warp_band_mapping %
                               (i + 1, i + 1, band_mapping_info))

        if src_bands < 4 and self.palette is None:
            vrt_bands.append(warp_band %
                             (src_bands + 1, warp_band_color % 'Alpha'))

        vrt_text = warp_vrt % {
            'xsize':
            size[0],
            'ysize':
            size[1],
            'srs':
            self.proj_srs,
            'geotr':
            geotr_templ % dst_geotr,
            'band_list':
            '\n'.join(vrt_bands),
            'blxsize':
            self.tile_size[0],
            'blysize':
            self.tile_size[1],
            'wo_ResampleAlg':
            self.base_resampling,
            'wo_src_path':
            cgi.escape(self.src_path, quote=True),
            'warp_options':
            '\n'.join(warp_options),
            'wo_src_srs':
            gcp_proj if gcp_proj else src_proj,
            'wo_dst_srs':
            self.proj_srs,
            'wo_src_transform':
            src_transform,
            'wo_dst_transform':
            dst_transform,
            'wo_BandList':
            '\n'.join(wo_BandList),
            'wo_DstAlphaBand':
            warp_dst_alpha_band %
            (src_bands + 1) if src_bands < 4 and self.palette is None else '',
            'wo_Cutline': (warp_cutline % cut_wkt) if cut_wkt else '',
        }

        temp_vrt = os.path.join(self.dest,
                                self.base + '.tmp.vrt')  # auxilary VRT file
        self.temp_files.append(temp_vrt)
        with open(temp_vrt, 'w') as f:
            f.write(vrt_text.encode('utf-8'))

        return gdal.Open(vrt_text, GA_ReadOnly)
Esempio n. 28
0
#####################  9.3.1 Using real-world coordinates  ####################

# Get the geotransform from one of the Landsat bands.
os.chdir(os.path.join(data_dir, 'Landsat', 'Washington'))
ds = gdal.Open('p047r027_7t20000730_z10_nn10.tif')
band = ds.GetRasterBand(1)
gt = ds.GetGeoTransform()
print(gt)

# Now get the inverse geotransform. The original can be used to convert
# offsets to real-world coordinates, and the inverse can be used to convert
# real-world coordinates to offsets.

# GDAL 1.x: You get a success flag and the geotransform.
success, inv_gt = gdal.InvGeoTransform(gt)
print(success, inv_gt)

# GDAL 2.x: You get the geotransform or None
inv_gt = gdal.InvGeoTransform(gt)
print(inv_gt)

# Use the inverset geotransform to get some pixel offsets from real-world
# UTM coordinates (since that's what the Landsat image uses). The offsets
# are returned as floating point.
offsets = gdal.ApplyGeoTransform(inv_gt, 465200, 5296000)
print(offsets)

# Convert the offsets to integers.
xoff, yoff = map(int, offsets)
print(xoff, yoff)
Esempio n. 29
0
def mapToPixel(mX, mY, geoTransform):
    (pX, pY) = gdal.ApplyGeoTransform(
        gdal.InvGeoTransform(geoTransform), mX, mY)
    return (int(pX), int(pY))
Esempio n. 30
0
def geo_to_corner(point_coor, raster_geo):
    # 计算逆放射变换系数
    raster_inv_geo = gdal.InvGeoTransform(raster_geo)
    off_ulx, off_uly = map(round, gdal.ApplyGeoTransform(raster_inv_geo, point_coor[1], point_coor[0]))
    return off_ulx, off_uly