def raster(self, name=None, **creteria): """Generates a GeoRaster2 object based on the asset name(key) or a creteria(protety name and value).""" if name: asset = self.assets[name] if asset["type"] in raster_types: __object = asset.get('__object') if isinstance(__object, GeoRaster2): return __object else: return GeoRaster2.from_assets([asset]) else: return None if creteria: key = next(iter(creteria)) value = creteria[key] else: # default creteria is to return a visual raster key = 'product' value = 'visual' rasters = { k: asset for k, asset in self.assets.items() if asset['type'] in raster_types } raster_list = list(rasters.values()) # if there is only a single raster in the assetes and it hase a GeoRaster object serve the object if len(raster_list) == 1 and isinstance(raster_list[0].get('__object'), GeoRaster2): return raster_list[0].get('__object') rasters = {k: r for k, r in rasters.items() if r[key] == value} raster = GeoRaster2.from_assets(rasters) return raster
def test_vrt_from_single_raster(): rasters = [ GeoRaster2.open("tests/data/raster/overlap1.tif"), ] raster = GeoRaster2.from_rasters(rasters, False) assert raster.crs == rasters[0].crs assert raster.shape == rasters[0].shape assert raster.affine.almost_equals(rasters[0].affine) assert (raster.image.data == rasters[0].image.data).all()
def setUpClass(cls): path = "/vsimem/raster_for_test.tif" cls.raster_for_test().save(path) cls.read_only_vgr = GeoRaster2.open(path) path = "/vsimem/small_raster.tif" cls.raster_small_for_test().save(path) cls.small_read_only_vgr = GeoRaster2.open(path) path = "/vsimem/raster_wgs84.tif" cls.raster_for_test_wgs84().save(path) cls.read_only_vgr_wgs84 = GeoRaster2.open(path)
def setUpClass(cls): cls.temp_dir = tempfile.TemporaryDirectory() path = os.path.join(cls.temp_dir.name, 'test_raster.tif') if not os.path.isfile(path): cls.raster_for_test().save(path) cls.read_only_vgr = GeoRaster2.open(path) path = os.path.join(cls.temp_dir.name, 'small_test_raster.tif') if not os.path.isfile(path): cls.raster_small_for_test().save(path) cls.small_read_only_vgr = GeoRaster2.open(path)
def test_boundless_vrt_preserves_mask(): expected = GeoRaster2.open("tests/data/raster/overlap1.tif") with rasterio.open(expected.source_file) as raster: doc = boundless_vrt_doc(raster, bands=[1, 2]).tostring() with TemporaryDirectory() as d: file_name = os.path.join(d, 'vrt_file.vrt') with open(file_name, 'wb') as f: f.write(doc) raster = GeoRaster2.open(file_name) assert np.array_equal(raster.image.mask, expected.image.mask[:2, :, :])
def test_vrt_from_multi_raster(): rasters = [ GeoRaster2.open("tests/data/raster/overlap1.tif"), GeoRaster2.open("tests/data/raster/overlap2.tif") ] raster = GeoRaster2.from_rasters(rasters, False) # made by gdalbuildvrt expected = GeoRaster2.open("tests/data/raster/expected_overlaps.vrt") assert raster.crs == expected.crs assert raster.shape == expected.shape # is this reasonable relative_precission = 10e-6 * expected.resolution() assert raster.affine.almost_equals(expected.affine, precision=relative_precission) assert (raster.image == expected.image).all()
def test_raster_list_vrt_for_single_raster(): rasters = [ GeoRaster2.open("tests/data/raster/overlap1.tif"), ] doc = raster_list_vrt(rasters, False).tostring() with TemporaryDirectory() as d: file_name = os.path.join(d, 'vrt_file.vrt') with open(file_name, 'wb') as f: f.write(doc) raster = GeoRaster2.open(file_name) assert raster.crs == rasters[0].crs assert raster.shape == rasters[0].shape assert raster.affine.almost_equals(rasters[0].affine) assert (raster.image.data == rasters[0].image.data).all() assert raster.band_names == rasters[0].band_names
def masked_raster(cls): data = np.array([ [0, 1, 1, 1], [0, 2, 0, 2], [0, 3, 3, 3], ], dtype=np.uint8) mask = np.array([ [True, False, False, False], [True, False, False, False], [True, False, False, False], ], dtype=np.bool) image = np.ma.array(np.repeat(data[np.newaxis, :, :], 3, 0), mask=np.repeat(mask[np.newaxis, :, :], 3, 0)) # Don't use exactly -1.0 for the affine for rasterio < 1.0a13, see # https://github.com/mapbox/rasterio/issues/1272 affine = Affine.scale(1, -1.0001) * Affine.translation(0, -3) crs = WGS84_CRS return GeoRaster2( image, affine=affine, crs=crs, )
def raster_small_for_test(cls): return GeoRaster2(np.random.uniform(0, 256, (3, 391, 370)), affine=Affine(1.0000252884112817, 0.0, 2653900.345511198, 0.0, -1.0000599330133702, 4598361.485763356), crs={'init': 'epsg:3857'})
def test_band_names_setter_fail(): raster = GeoRaster2.open("tests/data/raster/overlap2.tif", mutable=True) new_band_names = ["1", "2"] prev_band_names = raster.band_names with pytest.raises(tl.georaster.GeoRaster2Error): raster.band_names = new_band_names assert prev_band_names == raster.band_names
def test_changing_bandnames_and_image(): raster = GeoRaster2.open("tests/data/raster/overlap2.tif", mutable=True) new_band_names = ["1"] (indeces, width, height) = raster.shape raster.set_image(raster.image[0:1, 50:, 50:], new_band_names) assert (1, width - 50, height - 50) == raster.shape assert raster.band_names == new_band_names
def test_pixel_change_in_immutable_raster(): raster = GeoRaster2.open("tests/data/raster/overlap2.tif", mutable=False) val = raster.image[1, 300, 300] assert val is not 4 with pytest.raises(ValueError): raster.image[1, 300, 300] = 4 assert raster.image[1, 300, 300] == val
def test_set_affine_immutable(): raster = GeoRaster2.open("tests/data/raster/overlap2.tif", mutable=False) affine = Affine(1, 2, 3, 4, 5, 6) old_affine = raster.affine with pytest.raises(AttributeError): raster.affine = affine assert raster.affine == old_affine
def test_warp_no_reproject(in_memory): """ When called without parameters, output should be same as source """ raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image expected_raster = raster.reproject() assert expected_raster == raster
def test_small_read_only_virtual_geo_raster_wgs84_crop(): # See https://github.com/satellogic/telluric/issues/61 roi = GeoVector.from_bounds(xmin=0, ymin=0, xmax=2, ymax=2, crs=WGS84_CRS) resolution = 1.0 # deg / px raster = GeoRaster2.empty_from_roi(roi, resolution) assert raster.crop(roi) == raster.crop(roi, raster.resolution())
def setUpClass(cls): path = os.path.join('./', 'test_masked_raster.tif') if not os.path.isfile(path): # Save without overviews to avoid segmentation fault, see # https://publicgitlab.satellogic.com/telluric/telluric/issues/60 cls.masked_raster().save(path, overviews=False) cls.read_only_vgr = GeoRaster2.open(path)
def raster_for_test(cls): # return GeoRaster2(np.random.uniform(0, 256, (3, 7823, 7417)), return GeoRaster2(np.random.uniform(0, 256, (3, 3911, 3708)), affine=Affine(1.0000252884112817, 0.0, 2653750.345511198, 0.0, -1.0000599330133702, 4594461.485763356), crs={'init': 'epsg:3857'})
def test_save_nongeo(tmp_path, recwarn): raster = GeoRaster2(image=np.ones([10, 10], dtype=np.uint8), crs=DEFAULT_CRS, affine=Affine.translation(10, 100)) path = tmp_path / 'raster1.tif' raster.save(path) raster = GeoRaster2.open(path) assert raster.crs is not None and raster.affine is not None raster = raster.copy_with(crs=None, affine=None) assert raster.crs is None and raster.affine is None path = Path('/tmp/raster2.tif') raster.save(path) raster = GeoRaster2.open(path) assert raster.crs is None assert raster.affine == Affine.identity() # rasterio does this
def test_warp_reproject_dst_crs(in_memory): raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image expected_raster = raster.reproject(dst_crs=WGS84_CRS) assert expected_raster.shape[0] == raster.shape[0] assert expected_raster.crs == WGS84_CRS assert expected_raster.width == 109 assert expected_raster.height == 90
def test_crop_use_get_window_for_a_not_loaded_image(self, mock_get_window): coords = mercantile.xy_bounds(*tiles[15]) shape = GeoVector(Polygon.from_bounds(*coords), WEB_MERCATOR_CRS) raster = self.read_only_virtual_geo_raster() with NamedTemporaryFile(mode='w+b', suffix=".tif") as rf: raster.save(rf.name) raster = GeoRaster2.open(rf.name) raster.crop(shape, MERCATOR_RESOLUTION_MAPPING[15]) assert mock_get_window.called_once
def test_warp_target_aligned_pixels_invalid_params(in_memory, bad_params): raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image with pytest.raises(ValueError) as error: expected_raster = raster.reproject(dst_crs=WGS84_CRS, target_aligned_pixels=True, **bad_params) assert "target_aligned_pixels cannot be used" in error.exconly()
def test_vrt_from_multi_raster_and_save_to_file(): rasters = [ GeoRaster2.open("tests/data/raster/overlap1.tif"), GeoRaster2.open("tests/data/raster/overlap2.tif") ] with NamedTemporaryFile(suffix='.vrt') as f: raster = GeoRaster2.from_rasters(rasters, False, destination_file=f.name) assert raster._filename == f.name assert os.path.exists(f.name) # made by gdalbuildvrt expected = GeoRaster2.open("tests/data/raster/expected_overlaps.vrt") assert raster.crs == expected.crs assert raster.shape == expected.shape # is this reasonable relative_precission = 10e-6 * expected.resolution() assert raster.affine.almost_equals(expected.affine, precision=relative_precission) assert (raster.image == expected.image).all()
def test_crop_use_get_window_for_a_not_loaded_image(self, mock_get_window): coords = mercantile.xy_bounds(*tiles[15]) shape = GeoVector(Polygon.from_bounds(*coords), WEB_MERCATOR_CRS) raster = self.metric_raster() with NamedTemporaryFile(mode='w+b', suffix=".tif") as rf: raster.save(rf.name) raster = GeoRaster2.open(rf.name) raster.crop(shape, mercator_zoom_to_resolution[15]) assert mock_get_window.called_once
def test_georaster_wms_vrt_with_destination_file(): vector = GeoFeature.from_record(record, crs=constants.WGS84_CRS).geometry with NamedTemporaryFile(suffix='.vrt') as f: raster = GeoRaster2.from_wms("tests/data/google.xml", vector, resolution=1, destination_file=f.name) assert raster._filename == f.name assert os.path.exists(f.name) assert raster.resolution() == 1 assert raster.crs == constants.WEB_MERCATOR_CRS assert raster.footprint().difference(vector).area < 0.9
def test_crop_image_from_and_get_win_do_the_same_with_resize(self): bounds = (2, 3, 4, 5) win = rasterio.windows.Window(bounds[0], bounds[1], bounds[2] - bounds[0], bounds[3] - bounds[1]) xsize = round((bounds[2] - bounds[0]) / 2) ysize = round((bounds[3] - bounds[1]) / 2) raster = self.read_only_virtual_geo_raster() with NamedTemporaryFile(mode='w+b', suffix=".tif") as rf: raster.save(rf.name) raster.save('area.tif', tags={'AREA_OR_POINT': 'Area'}) raster.save('point.tif', tags={'AREA_OR_POINT': 'Point'}) saved_raster = GeoRaster2.open(rf.name) cropped_win = saved_raster.get_window(win, xsize=xsize, ysize=ysize) saved_raster_area = GeoRaster2.open('area.tif') cropped_win_area = saved_raster_area.get_window(win, xsize=xsize, ysize=ysize) saved_raster_point = GeoRaster2.open('point.tif') cropped_win_point = saved_raster_point.get_window(win, xsize=xsize, ysize=ysize) cropped_image = raster._crop(bounds, xsize=xsize, ysize=ysize) print('cropped_win_area pixels\n', cropped_win_area.image) print('cropped_win_point pixels\n', cropped_win_point.image) print('cropped_win pixels\n', cropped_win.image) print('cropped_image pixels\n', cropped_image.image) if (cropped_win_point == cropped_win_area): print('point == area') if (cropped_image == cropped_win_area): print('image == area') if (cropped_image == cropped_win_point): print('image == point') if (cropped_win == cropped_win_area): print('win == area') if (cropped_win == cropped_win_point): print('win == point') self.assertEqual(cropped_image, cropped_win)
def test_warp_reproject_dimensions_invalid_params(in_memory, bad_params): raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image dimensions = (100, 100) with pytest.raises(ValueError) as error: expected_raster = raster.reproject(dst_crs=WGS84_CRS, dimensions=dimensions, **bad_params) assert "dimensions cannot be used with" in error.exconly()
def test_warp_reproject_bounds_no_resolution(in_memory): raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image dst_bounds = [-11850000, 4810000, -11849000, 4812000] with pytest.raises(ValueError) as error: expected_raster = raster.reproject(dst_crs=WGS84_CRS, dst_bounds=dst_bounds) assert "resolution is required when using src_bounds or dst_bounds" in error.exconly( )
def test_warp_no_reproject_resolution(in_memory): raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image expected_raster = raster.reproject(resolution=30) assert expected_raster.crs == raster.crs assert expected_raster.width == 255 assert expected_raster.height == 255 assert np.allclose( [30, 30], [expected_raster.transform.a, -expected_raster.transform.e])
def test_warp_no_reproject_dimensions(in_memory): raster = GeoRaster2.open("tests/data/raster/rgb.tif") if in_memory: raster_image = raster.image expected_raster = raster.reproject(dimensions=(512, 512)) assert expected_raster.crs == raster.crs assert expected_raster.width == 512 assert expected_raster.height == 512 assert np.allclose( [14.929107, 14.929107], [expected_raster.transform.a, -expected_raster.transform.e])
def test_crop_and_get_tile_do_the_same_when_image_is_populated(self): coords = mercantile.xy_bounds(*tiles[15]) shape = GeoVector(Polygon.from_bounds(*coords), WEB_MERCATOR_CRS) raster = self.read_only_virtual_geo_raster() with NamedTemporaryFile(mode='w+b', suffix=".tif") as rf: raster.save(rf.name) raster = GeoRaster2.open(rf.name) tile15 = raster.get_tile(*tiles[15]) raster._populate_from_rasterio_object(read_image=True) cropped_15 = raster.crop(shape, MERCATOR_RESOLUTION_MAPPING[15]) self.assertEqual(tile15, cropped_15)