def test_generate_tile_coordinates_in_pixels_raises_error_for_non_int_pixel_size(): roi = GeoVector(Polygon([(0, 0), (10, 0), (10, 20), (0, 20)])) with pytest.raises(ValueError) as error: list(generate_tile_coordinates_from_pixels(roi, 1, (1.5, 1.5))) assert "Pixel size must be a tuple of integers" in error.exconly()
def test_generate_tile_coordinates_in_pixels(pixel_size, resolution, length): roi = GeoVector(Polygon([(0, 0), (10, 0), (10, 20), (0, 20)])) tiles = list( generate_tile_coordinates_from_pixels(roi, resolution, pixel_size)) assert len(tiles) == length
def test_get_tile_merge_tiles(tile): raster1_path = './tests/data/raster/overlap1.tif' raster2_path = './tests/data/raster/overlap2.tif' raster1 = GeoRaster2.open(raster1_path) raster2 = GeoRaster2.open(raster2_path) features = [ GeoFeature(raster1.footprint().reproject(new_crs=WGS84_CRS), {'raster_url': raster1_path, 'created': datetime.now()}), GeoFeature(raster2.footprint().reproject(new_crs=WGS84_CRS), {'raster_url': raster2_path, 'created': datetime.now()}), ] fc = FeatureCollection(features) bounds = mercantile.xy_bounds(*tile) eroi = GeoVector.from_bounds(xmin=bounds.left, xmax=bounds.right, ymin=bounds.bottom, ymax=bounds.top, crs=WEB_MERCATOR_CRS) expected_tile = merge_all([raster1.get_tile(*tile), raster2.get_tile(*tile)], roi=eroi) merged = fc.get_tile(*tile, sort_by='created') if merged is not None: assert merged == expected_tile else: assert expected_tile.image.mask.all() assert (expected_tile.image.data == 0).all()
def test_rasterization_of_line_simple(): resolution = 1 pixels_width = 1 line = GeoFeature.from_shape(LineString([(2.5, 0), (2.5, 3)])) roi = GeoVector.from_bounds(xmin=0, ymin=0, xmax=5, ymax=5, crs=DEFAULT_CRS) fc = FeatureCollection([line]) expected_image = np.zeros((5, 5), dtype=np.uint8) expected_image[2:, 2] = 1 expected_affine = Affine(1.0, 0.0, 0.0, 0.0, -1.0, 5.0) expected_crs = DEFAULT_CRS expected_result = GeoRaster2(expected_image, expected_affine, expected_crs, nodata=0) result = fc.rasterize(resolution, polygonize_width=pixels_width, crs=DEFAULT_CRS, bounds=roi) assert result == expected_result
def test_raster_closer_than_resolution_to_roi(): raster_close_to_roi = make_test_raster( 1, [1], height=2255, width=6500, affine=Affine(1.000056241624503, -0.0001677700491717716, 251130.52371896777, -0.00011325628093143738, -1.0000703876618153, 2703061.4308057753), crs=CRS.from_epsg(32613), ) raster_intersecting_roi = make_test_raster( 1, [1], height=3515, width=6497, affine=Affine(1.000063460933417, -2.935588943753421e-05, 250953.40276071787, -3.26265458078499e-05, -1.000053742629815, 2703428.138070052), crs=CRS.from_epsg(32613), ) roi = GeoVector.from_bounds(251726, 2696110, 256422, 2700806, CRS.from_epsg(32613)) merge_all( [raster_close_to_roi, raster_intersecting_roi], roi=roi, dest_resolution=(1, 1), merge_strategy=MergeStrategy.INTERSECTION, )
def test_layer_from_shape(): expected_geo = {'coordinates': (0.0, 0.0), 'type': 'Point'} vector = GeoVector(shape(expected_geo)) result = layer_from_element(vector) assert result.data == expected_geo
def test_groupby_agg_returns_expected_result(): fc = FeatureCollection([ GeoFeature(GeoVector(Point(3, 3)), {'prop1': 'a', 'b': 1}), GeoFeature(GeoVector(Point(1, 1)), {'prop1': 'a', 'b': 2}), GeoFeature(GeoVector(Point(2, 2)), {'prop1': 'b', 'b': 3}) ]) def first(collection): return collection[0] expected_result = FeatureCollection([ GeoFeature(GeoVector(Point(3, 3)), {'b': 1}), GeoFeature(GeoVector(Point(2, 2)), {'b': 3}) ]) assert list(fc.groupby('prop1')['b'].agg(first)) == expected_result
def test_geofeature_str(): expected_geovector = GeoVector(Point(0.0, 0.0)) expected_properties = {'property_1': 1} res = GeoFeature(expected_geovector, expected_properties) assert str(res) == "GeoFeature(Point, {'property_1': 1})"
def test_feature_collection_with_dates_serializes_correctly(): # "For Shapefiles, however, the only possible field type is 'date' as 'datetime' and 'time' are not available." # https://github.com/Toblerity/Fiona/pull/130 # See also: https://github.com/Toblerity/Fiona/issues/572 schema = { 'geometry': 'Point', 'properties': OrderedDict([ ('prop_date', 'date'), ]), } expected_attributes = { 'prop_date': date(2018, 4, 23), } feature = GeoFeature(GeoVector(Point(0, 0)), expected_attributes) with tempfile.TemporaryDirectory() as path: file_path = os.path.join(path, "test_dates.shp") with fiona.open(file_path, mode='w', driver="ESRI Shapefile", schema=schema, crs=feature.crs) as sink: sink.write(mapping(feature)) fc = FileCollection.open(file_path) assert fc.schema == schema assert fc[0].geometry == feature.geometry assert fc[0].attributes == expected_attributes
def test_delegated_properties(property_name): feature = GeoFeature( GeoVector(Point(0, 10)), {} ) assert getattr(feature, property_name) == getattr(feature.geometry, property_name)
def test_delegated_unary_predicates(predicate_name): feature = GeoFeature( GeoVector(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])), {} ) assert getattr(feature, predicate_name) == getattr(feature.geometry, predicate_name)
def test_geofeature_str(): expected_geovector = GeoVector(Point(0.0, 0.0)) expected_attributes = {'attribute_1': 1} res = GeoFeature(expected_geovector, expected_attributes) assert str(res) == "GeoFeature(Point, {'attribute_1': 1})"
def from_record(cls, record, crs, schema=None): if schema is not None: attributes = transform_attributes(record["properties"], schema) else: attributes = record["properties"] return cls(GeoVector(shape(record['geometry']), crs), attributes)
def test_area_is_cartesian_and_correct(): shape = Point(0.0, 40.0).buffer(1.0) expected_area = 29773634861.23 # geojson.io gv = GeoVector(shape) assert gv.area == approx(expected_area)
def test_featurecollection_schema_for_property_types_without_none_values(): fc = FeatureCollection([ GeoFeature(GeoVector(Point(0, 0)), {'prop1': 1, 'prop2': 1.0, 'prop3': 'A'}), GeoFeature(GeoVector(Point(0, 0)), {'prop1': 2, 'prop2': 2.0, 'prop3': 'B'}) ]) expected_schema = { 'geometry': 'Point', 'properties': { 'prop1': 'int', 'prop2': 'float', 'prop3': 'str' } } assert fc.schema == expected_schema
def test_rasterization_of_line_has_correct_pixel_width(resolution): xmax, ymax = 11, 5 pixels_width = 1 line = GeoFeature.from_shape( LineString([(xmax / 2, 0), (xmax / 2, ymax * 4 / 5)])) roi = GeoVector.from_bounds(xmin=0, ymin=0, xmax=xmax, ymax=ymax, crs=DEFAULT_CRS) fc = FeatureCollection([line]) expected_image = np.zeros( (int(ymax // resolution), int(xmax // resolution)), dtype=np.uint8) expected_image[int(1 // resolution):, expected_image.shape[1] // 2] = 1 expected_affine = Affine(resolution, 0.0, 0.0, 0.0, -resolution, 5.0) expected_crs = DEFAULT_CRS expected_result = GeoRaster2(expected_image, expected_affine, expected_crs, nodata=0) result = fc.rasterize(resolution, polygonize_width=pixels_width, crs=DEFAULT_CRS, bounds=roi) assert result == expected_result
def test_plot_adds_layer_to_map(mock_layer_from_element, mock_add_layer): gv = GeoVector(Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])) layer = mock_layer_from_element.return_value plot(gv) mock_add_layer.assert_called_once_with(layer)
def test_geofeature_dict(): expected_geovector = GeoVector(Point(0.0, 0.0)) expected_properties = {'property_1': 1} res = GeoFeature(expected_geovector, expected_properties) assert res['property_1'] == 1 assert res.geometry == expected_geovector
def test_rasterization_raise_error_for_too_big_image(): shape = Polygon([(0, 0), (1, 0), (1, -1), (0, -1)]) fcol = FeatureCollection([GeoFeature(GeoVector(shape), {})]) with pytest.raises(ScaleError) as excinfo: fcol.rasterize(1e-50) assert "Scale is too fine, increase it for a smaller image" in excinfo.exconly( )
def test_footprint(): expected_shp = Polygon([[raster_origin.x + 0, raster_origin.y + 0], [raster_origin.x + some_raster.width, raster_origin.y + 0], [raster_origin.x + some_raster.width, raster_origin.y + some_raster.height], [raster_origin.x + 0, raster_origin.y + some_raster.height]]) expected = GeoVector(expected_shp, some_raster.crs) assert some_raster.footprint().almost_equals(expected)
def test_geofeature_dict(): expected_geovector = GeoVector(Point(0.0, 0.0)) expected_attributes = {'attribute_1': 1} res = GeoFeature(expected_geovector, expected_attributes) assert res['attribute_1'] == 1 assert res.geometry == expected_geovector
def test_crop_boundless_masked(bounds): raster_w_mask = GeoRaster2.open("tests/data/raster/rgb.tif") raster_wo_mask = GeoRaster2.open("tests/data/raster/rgb.jp2") roi = GeoVector(Polygon.from_bounds(*bounds), WEB_MERCATOR_CRS) assert (np.array_equal( raster_w_mask.crop(roi).image.mask, raster_wo_mask.crop(roi).image.mask))
def test_plot_empty_geometry_prints_warning(): vector = GeoVector(Point([0, 0]).buffer(0)) assert vector.is_empty with pytest.warns(UserWarning) as record: plot(vector) assert "The geometry is empty." in record[0].message.args[0]
def test_geofeature_initializer(): expected_geovector = GeoVector(Point(0.0, 0.0)) expected_attributes = {'attribute_1': 1} res = GeoFeature(expected_geovector, expected_attributes) assert res.geometry is expected_geovector assert dict(res) == expected_attributes
def test_delegated_properties(property_name): expected_properties = {'property_1': 1} feature = GeoFeature(GeoVector(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])), expected_properties) assert getattr(feature, property_name).geometry == getattr(feature.geometry, property_name)
def test_delegated_operations(operation_name): properties_1 = {'property_1': 1} properties_2 = {'property_2': 2} feature_1 = GeoFeature( GeoVector(Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])), properties_1) feature_2 = GeoFeature( GeoVector(Polygon([(0.5, 0), (1.5, 0), (1.5, 1), (0.5, 1)])), properties_2) expected_properties = {'property_1': 1, 'property_2': 2} assert (getattr(feature_1, operation_name)(feature_2).geometry == getattr( feature_1.geometry, operation_name)(feature_2.geometry)) assert getattr(feature_1, operation_name)(feature_2).properties == expected_properties assert getattr(feature_2, operation_name)(feature_1).properties == expected_properties
def test_rasterization_point_single_pixel(): data = np.zeros((5, 5), dtype=np.uint8)[None, :, :] data[0, 2, 2] = 1 mask = ~(data.astype(bool)) expected_image = np.ma.masked_array(data, mask) fc = FeatureCollection.from_geovectors([ GeoVector(Point(2, 2), crs=WEB_MERCATOR_CRS)] ) roi = GeoVector.from_bounds(xmin=0, ymin=0, xmax=5, ymax=5, crs=WEB_MERCATOR_CRS) result = fc.rasterize(1, polygonize_width=1, bounds=roi).image assert_array_equal(result.data, expected_image.data) assert_array_equal(result.mask, expected_image.mask)
def test_rasterize_with_geovector_bounds(mock_rasterize): fc = fc_generator(num_features=1) expected_bounds = Polygon.from_bounds(0, 0, 1, 1) bounds = GeoVector(expected_bounds, crs=DEFAULT_CRS) fc.rasterize(0.00001, crs=DEFAULT_CRS, bounds=bounds) f = next(iter(fc)) expected_shape = [f.geometry.get_shape(f.geometry.crs)] mock_rasterize.assert_called_with(expected_shape, DEFAULT_CRS, expected_bounds, 0.00001, None, None)
def test_get_bounding_box(): src_crs = CRS(init='epsg:4326') dst_crs = CRS(init='epsg:32718') src_bounds = dict(xmin=-73.309037, ymin=-40.665865, xmax=-72.723835, ymax=-40.026434) gv = GeoVector.from_bounds(crs=src_crs, **src_bounds) bounds = transform_bounds(src_crs=src_crs, dst_crs=dst_crs, left=src_bounds['xmin'], bottom=src_bounds['ymin'], right=src_bounds['xmax'], top=src_bounds['ymax']) assert gv.get_bounding_box(dst_crs).almost_equals( GeoVector.from_bounds(*bounds, crs=dst_crs))
def test_geofeature_correctly_serializes_non_simple_types(): date_feature = datetime(2018, 4, 25, 11, 18) feature = GeoFeature( GeoVector(Point(0, 0)), OrderedDict([('prop1', 1), ('prop2', '2'), ('prop3', date_feature)])) expected_properties = OrderedDict([('prop1', 1), ('prop2', '2'), ('prop3', date_feature.isoformat())]) assert mapping(feature)['properties'] == expected_properties