def load_subdataset(subdataset, attrs, band_spec, **reader_kwargs): '''Load a single subdataset''' data_file = gdal.Open(subdataset) raster = raster_as_2d(data_file.ReadAsArray(**reader_kwargs)) #raster = raster.T if getattr(band_spec, 'stored_coords_order', ['y', 'x'])[0] == 'y': rows, cols = raster.shape dims = ('y', 'x') else: rows, cols = raster.T.shape dims = ('x', 'y') geo_transform = take_geo_transform_from_meta(band_spec, **attrs) if geo_transform is None: geo_transform = data_file.GetGeoTransform() coord_x, coord_y = geotransform_to_coords(cols, rows, geo_transform) canvas = Canvas(geo_transform=geo_transform, buf_xsize=cols, buf_ysize=rows, dims=dims, bounds=geotransform_to_bounds(cols, rows, geo_transform), ravel_order='C') attrs['canvas'] = canvas attrs['geo_transform'] = geo_transform if dims == ('y', 'x'): coords = [('y', coord_y), ('x', coord_x)] else: coords = [('x', coord_x), ('y', coord_y)] return xr.DataArray(data=raster, coords=coords, dims=dims, attrs=attrs)
def load_dir_of_tifs_array(dir_of_tiffs, meta, band_specs=None): '''Return an ElmStore where each subdataset is a DataArray Parameters: :dir_of_tiffs: directory of GeoTiff files where each is a single band raster :meta: meta from earthio.load_dir_of_tifs_meta :band_specs: list of earthio.BandSpec objects, defaulting to reading all subdatasets as bands Returns: :X: ElmStore ''' logger.debug('load_dir_of_tifs_array: {}'.format(dir_of_tiffs)) band_order_info = meta['band_order_info'] tifs = ls_tif_files(dir_of_tiffs) logger.info('Load tif files from {}'.format(dir_of_tiffs)) if not len(band_order_info): raise ValueError('No matching bands with ' 'band_specs {}'.format(band_specs)) native_dims = ('y', 'x') elm_store_dict = OrderedDict() attrs = {'meta': meta} attrs['band_order'] = [] for (idx, filename, band_spec), band_meta in zip(band_order_info, meta['band_meta']): band_name = getattr(band_spec, 'name', band_spec) if not isinstance(band_spec, str): reader_kwargs = {k: getattr(band_spec, k) for k in READ_ARRAY_KWARGS if getattr(band_spec, k)} else: reader_kwargs = {} if 'buf_xsize' in reader_kwargs: reader_kwargs['width'] = reader_kwargs.pop('buf_xsize') if 'buf_ysize' in reader_kwargs: reader_kwargs['height'] = reader_kwargs.pop('buf_ysize') if 'window' in reader_kwargs: reader_kwargs['window'] = tuple(map(tuple, reader_kwargs['window'])) # TODO multx, multy should be handled here as well? if reader_kwargs: multy = band_meta['height'] / reader_kwargs.get('height', band_meta['height']) multx = band_meta['width'] / reader_kwargs.get('width', band_meta['width']) else: multx = multy = 1. band_meta.update(reader_kwargs) geo_transform = take_geo_transform_from_meta(band_spec, **attrs) handle, raster = open_prefilter(filename, band_meta, **reader_kwargs) raster = raster_as_2d(raster) if getattr(band_spec, 'stored_coords_order', ['y', 'x'])[0] == 'y': rows, cols = raster.shape else: rows, cols = raster.T.shape if geo_transform is None: band_meta['geo_transform'] = handle.get_transform() else: band_meta['geo_transform'] = geo_transform band_meta['geo_transform'][1] *= multx band_meta['geo_transform'][-1] *= multy coords_x, coords_y = geotransform_to_coords(cols, rows, band_meta['geo_transform']) elm_store_dict[band_name] = xr.DataArray(raster, coords=[('y', coords_y), ('x', coords_x),], dims=native_dims, attrs=band_meta) attrs['band_order'].append(band_name) gc.collect() return ElmStore(elm_store_dict, attrs=attrs)
def load_hdf4_array(datafile, meta, band_specs=None): '''Return an ElmStore where each subdataset is a DataArray Parameters: :datafile: filename :meta: meta from earthio.load_hdf4_meta :band_specs: list of earthio.BandSpec objects, defaulting to reading all subdatasets as bands Returns: :Elmstore: Elmstore of teh hdf4 data ''' from earthio import ElmStore from earthio.metadata_selection import match_meta logger.debug('load_hdf4_array: {}'.format(datafile)) f = gdal.Open(datafile, GA_ReadOnly) sds = meta['sub_datasets'] band_metas = meta['band_meta'] band_order_info = [] if band_specs: for band_meta, s in zip(band_metas, sds): for idx, band_spec in enumerate(band_specs): if match_meta(band_meta, band_spec): band_order_info.append((idx, band_meta, s, band_spec)) break band_order_info.sort(key=lambda x: x[0]) if not len(band_order_info): raise ValueError('No matching bands with ' 'band_specs {}'.format(band_specs)) else: band_order_info = [(idx, band_meta, s, 'band_{}'.format(idx)) for idx, (band_meta, s) in enumerate(zip(band_metas, sds))] native_dims = ('y', 'x') elm_store_data = OrderedDict() band_order = [] for _, band_meta, s, band_spec in band_order_info: attrs = copy.deepcopy(meta) attrs.update(copy.deepcopy(band_meta)) if isinstance(band_spec, BandSpec): name = band_spec.name reader_kwargs = { k: getattr(band_spec, k) for k in READ_ARRAY_KWARGS if getattr(band_spec, k) } geo_transform = take_geo_transform_from_meta(band_spec, **attrs) else: reader_kwargs = {} name = band_spec geo_transform = None reader_kwargs = window_to_gdal_read_kwargs(**reader_kwargs) dat0 = gdal.Open(s[0], GA_ReadOnly) band_meta.update(reader_kwargs) raster = raster_as_2d(dat0.ReadAsArray(**reader_kwargs)) if geo_transform is None: geo_transform = dat0.GetGeoTransform() attrs['geo_transform'] = geo_transform if hasattr(band_spec, 'store_coords_order'): if band_spec.stored_coords_order[0] == 'y': rows, cols = raster.shape else: rows, cols = raster.T.shape else: rows, cols = raster.shape coord_x, coord_y = geotransform_to_coords(cols, rows, geo_transform) canvas = Canvas(geo_transform=geo_transform, buf_xsize=cols, buf_ysize=rows, dims=native_dims, ravel_order='C', bounds=geotransform_to_bounds(cols, rows, geo_transform)) attrs['canvas'] = canvas elm_store_data[name] = xr.DataArray(raster, coords=[('y', coord_y), ('x', coord_x)], dims=native_dims, attrs=attrs) band_order.append(name) del dat0 attrs = copy.deepcopy(attrs) attrs['band_order'] = band_order gc.collect() return ElmStore(elm_store_data, attrs=attrs)