def test_tests(): box1 = geometry.box(10, 10, 30, 30, crs=epsg4326) box2 = geometry.box(20, 10, 40, 30, crs=epsg4326) box3 = geometry.box(30, 10, 50, 30, crs=epsg4326) box4 = geometry.box(40, 10, 60, 30, crs=epsg4326) minibox = geometry.box(15, 15, 25, 25, crs=epsg4326) assert not box1.touches(box2) assert box1.touches(box3) assert not box1.touches(box4) assert box1.intersects(box2) assert box1.intersects(box3) assert not box1.intersects(box4) assert not box1.crosses(box2) assert not box1.crosses(box3) assert not box1.crosses(box4) assert not box1.disjoint(box2) assert not box1.disjoint(box3) assert box1.disjoint(box4) assert box1.contains(minibox) assert not box1.contains(box2) assert not box1.contains(box3) assert not box1.contains(box4) assert minibox.within(box1) assert not box1.within(box2) assert not box1.within(box3) assert not box1.within(box4)
def test_to_crs(): poly = geometry.polygon([(0, 0), (0, 5), (10, 5)], epsg4326) num_points = 3 assert poly.crs is epsg4326 assert poly.to_crs(epsg3857).crs is epsg3857 assert poly.to_crs('EPSG:3857').crs == 'EPSG:3857' assert poly.to_crs('EPSG:3857', 0.1).crs == epsg3857 assert poly.exterior.to_crs(epsg3857) == poly.to_crs(epsg3857).exterior # test that by default segmentation happens # +1 is because exterior loops back to start point assert len(poly.to_crs(epsg3857).exterior.xy[0]) > num_points + 1 # test that +inf disables segmentation # +1 is because exterior loops back to start point assert len(poly.to_crs(epsg3857, float('+inf')).exterior.xy[0]) == num_points + 1 # test the segmentation works on multi-polygons mpoly = (geometry.box(0, 0, 1, 3, 'EPSG:4326') | geometry.box(2, 4, 3, 6, 'EPSG:4326')) assert mpoly.type == 'MultiPolygon' assert mpoly.to_crs(epsg3857).type == 'MultiPolygon' poly = geometry.polygon([(0, 0), (0, 5), (10, 5)], None) assert poly.crs is None with pytest.raises(ValueError): poly.to_crs(epsg3857)
def test_lonlat_bounds(): # example from landsat scene: spans lon=180 poly = geometry.box(618300, -1876800, 849000, -1642500, 'EPSG:32660') bb = geometry.lonlat_bounds(poly) assert bb.left < 180 < bb.right assert geometry.lonlat_bounds(poly) == geometry.lonlat_bounds(poly, resolution=1e+8) bb = geometry.lonlat_bounds(poly, mode='quick') assert bb.right - bb.left > 180 poly = geometry.box(1, -10, 2, 20, 'EPSG:4326') assert geometry.lonlat_bounds(poly) == poly.boundingbox with pytest.raises(ValueError): geometry.lonlat_bounds(geometry.box(0, 0, 1, 1, None)) multi = { "type": "MultiPolygon", "coordinates": [ [[[174, 52], [174, 53], [175, 53], [174, 52]]], [[[168, 54], [167, 55], [167, 54], [168, 54]]] ] } multi_geom = geometry.Geometry(multi, "epsg:4326") multi_geom_projected = multi_geom.to_crs('epsg:32659', math.inf) ll_bounds = geometry.lonlat_bounds(multi_geom) ll_bounds_projected = geometry.lonlat_bounds(multi_geom_projected) assert ll_bounds == approx(ll_bounds_projected)
def test_unary_union(): box1 = geometry.box(10, 10, 30, 30, crs=epsg4326) box2 = geometry.box(20, 10, 40, 30, crs=epsg4326) box3 = geometry.box(30, 10, 50, 30, crs=epsg4326) box4 = geometry.box(40, 10, 60, 30, crs=epsg4326) union0 = geometry.unary_union([box1]) assert union0 == box1 union1 = geometry.unary_union([box1, box4]) assert union1.type == 'MultiPolygon' assert union1.area == 2.0 * box1.area union2 = geometry.unary_union([box1, box2]) assert union2.type == 'Polygon' assert union2.area == 1.5 * box1.area union3 = geometry.unary_union([box1, box2, box3, box4]) assert union3.type == 'Polygon' assert union3.area == 2.5 * box1.area union4 = geometry.unary_union([union1, box2, box3]) assert union4.type == 'Polygon' assert union4.area == 2.5 * box1.area assert geometry.unary_union([]) is None with pytest.raises(ValueError): pt = geometry.point(6, 7, epsg4326) geometry.unary_union([pt, pt])
def test_chop(): poly = geometry.box(618300, -1876800, 849000, -1642500, 'EPSG:32660') chopped = chop_along_antimeridian(poly) assert chopped.crs is poly.crs assert chopped.type == 'MultiPolygon' assert len([g for g in chopped]) == 2 poly = geometry.box(0, 0, 10, 20, 'EPSG:4326')._to_crs(epsg3857) assert poly.crs is epsg3857 assert chop_along_antimeridian(poly) is poly with pytest.raises(ValueError): chop_along_antimeridian(geometry.box(0, 1, 2, 3, None))
def create_grid_mapping_variable(nco, crs, name=DEFAULT_GRID_MAPPING): if crs.geographic: crs_var = _create_latlon_grid_mapping_variable(nco, crs, name) elif crs.projected: crs_var = _create_projected_grid_mapping_variable(nco, crs, name) else: raise ValueError('Unknown CRS') # mark crs variable as a coordinate coords = getattr(nco, 'coordinates', None) coords = [] if coords is None else coords.split(',') if name not in coords: coords.append(name) nco.coordinates = ','.join(coords) crs_var.semi_major_axis = crs.semi_major_axis crs_var.semi_minor_axis = crs.semi_minor_axis crs_var.inverse_flattening = crs.inverse_flattening crs_var.crs_wkt = crs.wkt crs_var.spatial_ref = crs.wkt dims = crs.dimensions xres, xoff = data_resolution_and_offset(nco[dims[1]]) yres, yoff = data_resolution_and_offset(nco[dims[0]]) crs_var.GeoTransform = [xoff, xres, 0.0, yoff, 0.0, yres] left, right = nco[dims[1]][0] - 0.5 * xres, nco[dims[1]][-1] + 0.5 * xres bottom, top = nco[dims[0]][0] - 0.5 * yres, nco[dims[0]][-1] + 0.5 * yres _write_geographical_extents_attributes( nco, geometry.box(left, bottom, right, top, crs=crs)) return crs_var
def test_geom_clone(): b = geometry.box(0, 0, 10, 20, epsg4326) assert b == b.clone() assert b.geom is not b.clone().geom assert b == geometry.Geometry(b) assert b.geom is not geometry.Geometry(b).geom
def test_lonalt_bounds_more_than_180(): poly = geometry.box(-150, -30, 150, 30, epsg4326).to_crs(epsg3857, math.inf) assert geometry.lonlat_bounds(poly, "quick") == approx( (-150, -30, 150, 30)) assert geometry.lonlat_bounds(poly, "safe") == approx((-150, -30, 150, 30))
def create_grid_mapping_variable(nco, crs): if crs.geographic: crs_var = _create_latlon_grid_mapping_variable(nco, crs) elif crs.projected: crs_var = _create_projected_grid_mapping_variable(nco, crs) else: raise ValueError('Unknown CRS') crs_var.semi_major_axis = crs.semi_major_axis crs_var.semi_minor_axis = crs.semi_minor_axis crs_var.inverse_flattening = crs.inverse_flattening crs_var.crs_wkt = crs.wkt crs_var.spatial_ref = crs.wkt dims = crs.dimensions xres, xoff = data_resolution_and_offset(nco[dims[1]]) yres, yoff = data_resolution_and_offset(nco[dims[0]]) crs_var.GeoTransform = [xoff, xres, 0.0, yoff, 0.0, yres] left, right = nco[dims[1]][0] - 0.5 * xres, nco[dims[1]][-1] + 0.5 * xres bottom, top = nco[dims[0]][0] - 0.5 * yres, nco[dims[0]][-1] + 0.5 * yres _write_geographical_extents_attributes( nco, geometry.box(left, bottom, right, top, crs=crs)) return crs_var
def to_lat_long_extent(left, bottom, right, top, spatial_reference, new_crs="EPSG:4326"): crs = CRS(spatial_reference) abox = box(left, bottom, right, top, crs) projected = abox.to_crs(CRS(new_crs)) proj = projected.boundingbox left, bottom, right, top = proj.left, proj.bottom, proj.right, proj.top coord = { 'ul': { 'lon': left, 'lat': top }, 'ur': { 'lon': right, 'lat': top }, 'll': { 'lon': left, 'lat': bottom }, 'lr': { 'lon': right, 'lat': bottom }, } return coord
def xr_bounds(x, crs=None) -> Tuple[Tuple[float, float], Tuple[float, float]]: from datacube.utils.geometry import box from datacube.testutils.geom import epsg4326 def get_range(a: np.ndarray) -> Tuple[float, float]: b = (a[1] - a[0])*0.5 return a[0]-b, a[-1]+b if 'latitude' in x.coords: r1, r2 = (get_range(a.values) for a in (x.latitude, x.longitude)) p1, p2 = ((r1[i], r2[i]) for i in (0, 1)) return p1, p2 if crs is None: geobox = getattr(x, 'geobox', None) if geobox: crs = geobox.crs if crs is None: raise ValueError('Need to supply CRS or use latitude/longitude coords') if not all(d in x.coords for d in crs.dimensions): raise ValueError('Incompatible CRS supplied') (t, b), (l, r) = (get_range(x.coords[dim].values) for dim in crs.dimensions) l, b, r, t = box(l, b, r, t, crs).to_crs(epsg4326).boundingbox return ((t, r), (b, l))
def test_crs(): CRS = geometry.CRS custom_crs = geometry.CRS("""PROJCS["unnamed", GEOGCS["Unknown datum based upon the custom spheroid", DATUM["Not specified (based on custom spheroid)", SPHEROID["Custom spheroid",6371007.181,0]], PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]], PROJECTION["Sinusoidal"], PARAMETER["longitude_of_center",0], PARAMETER["false_easting",0], PARAMETER["false_northing",0], UNIT["Meter",1]]""") crs = epsg3577 assert crs.geographic is False assert crs.projected is True assert crs.dimensions == ('y', 'x') assert crs.epsg == 3577 assert crs.units == ('metre', 'metre') assert isinstance(repr(crs), str) crs = epsg4326 assert crs.geographic is True assert crs.projected is False assert crs.dimensions == ('latitude', 'longitude') assert crs.epsg == 4326 crs2 = CRS(crs) assert crs2 == crs assert crs.proj is crs2.proj assert epsg4326.valid_region == geometry.box(-180, -90, 180, 90, epsg4326) assert epsg3857.valid_region.crs == epsg4326 xmin, _, xmax, _ = epsg3857.valid_region.boundingbox assert (xmin, xmax) == (-180, 180) assert custom_crs.valid_region is None assert epsg3577 == epsg3577 assert epsg3577 == 'EPSG:3577' assert (epsg3577 != epsg3577) is False assert (epsg3577 == epsg4326) is False assert (epsg3577 == 'EPSG:4326') is False assert epsg3577 != epsg4326 assert epsg3577 != 'EPSG:4326' bad_crs = [ 'cupcakes', ('PROJCS["unnamed",' 'GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]],' 'AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]],' 'UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4326"]]]' ) ] for bad in bad_crs: with pytest.raises(geometry.CRSError): CRS(bad) with pytest.warns(DeprecationWarning): assert str(epsg3857) == epsg3857.crs_str
def make_fake_datasets(num_datasets): start_time = datetime.datetime(2001, 2, 15) delta = datetime.timedelta(days=16) for i in range(num_datasets): fakedataset = MagicMock() fakedataset.extent = geometry.box(left=grid, bottom=-grid, right=2*grid, top=-2*grid, crs=fakecrs) fakedataset.center_time = start_time + (delta * i) yield fakedataset
def test_props(): crs = epsg4326 box1 = geometry.box(10, 10, 30, 30, crs=crs) assert box1 assert box1.is_valid assert not box1.is_empty assert box1.area == 400.0 assert box1.boundary.length == 80.0 assert box1.centroid == geometry.point(20, 20, crs) triangle = geometry.polygon([(10, 20), (20, 20), (20, 10), (10, 20)], crs=crs) assert triangle.boundingbox == geometry.BoundingBox(10, 10, 20, 20) assert triangle.envelope.contains(triangle) assert box1.length == 80.0 box1copy = geometry.box(10, 10, 30, 30, crs=crs) assert box1 == box1copy assert box1.convex_hull == box1copy # NOTE: this might fail because of point order box2 = geometry.box(20, 10, 40, 30, crs=crs) assert box1 != box2 bbox = geometry.BoundingBox(1, 0, 10, 13) assert bbox.width == 9 assert bbox.height == 13 assert bbox.points == [(1, 0), (1, 13), (10, 0), (10, 13)] assert bbox.transform(Affine.identity()) == bbox assert bbox.transform(Affine.translation(1, 2)) == geometry.BoundingBox( 2, 2, 11, 15) pt = geometry.point(3, 4, crs) assert pt.json['coordinates'] == (3.0, 4.0) assert 'Point' in str(pt) assert bool(pt) is True assert pt.__nonzero__() is True # check "CRS as string is converted to class automatically" assert isinstance(geometry.point(3, 4, 'epsg:3857').crs, geometry.CRS) # constructor with bad input should raise ValueError with pytest.raises(ValueError): geometry.Geometry(object())
def test_lonlat_bounds(): # example from landsat scene: spans lon=180 poly = geometry.box(618300, -1876800, 849000, -1642500, 'EPSG:32660') bb = geometry.lonlat_bounds(poly) assert bb.left < 180 < bb.right assert geometry.lonlat_bounds(poly) == geometry.lonlat_bounds( poly, resolution=1e+8) bb = geometry.lonlat_bounds(poly, mode='quick') assert bb.right - bb.left > 180 poly = geometry.box(1, -10, 2, 20, 'EPSG:4326') assert geometry.lonlat_bounds(poly) == poly.boundingbox with pytest.raises(ValueError): geometry.lonlat_bounds(geometry.box(0, 0, 1, 1, None))
def test_wrap_dateline_utm(): poly = geometry.box(618300, -1876800, 849000, -1642500, 'EPSG:32660') wrapped = poly.to_crs(epsg4326) assert wrapped.type == 'Polygon' assert wrapped.intersects(geometry.line([(0, -90), (0, 90)], crs=epsg4326)) wrapped = poly.to_crs(epsg4326, wrapdateline=True) assert wrapped.type == 'MultiPolygon' assert not wrapped.intersects( geometry.line([(0, -90), (0, 90)], crs=epsg4326))
def test_geom_split(): box = geometry.box(0, 0, 10, 30, epsg4326) line = geometry.line([(5, 0), (5, 30)], epsg4326) bb = list(box.split(line)) assert len(bb) == 2 assert box.contains(bb[0] | bb[1]) assert (box ^ (bb[0] | bb[1])).is_empty with pytest.raises(CRSMismatchError): list(box.split(geometry.line([(5, 0), (5, 30)], epsg3857)))
def test_ops(): box1 = geometry.box(10, 10, 30, 30, crs=epsg4326) box2 = geometry.box(20, 10, 40, 30, crs=epsg4326) box3 = geometry.box(20, 10, 40, 30, crs=epsg4326) box4 = geometry.box(40, 10, 60, 30, crs=epsg4326) no_box = None assert box1 != box2 assert box2 == box3 assert box3 != no_box union1 = box1.union(box2) assert union1.area == 600.0 inter1 = box1.intersection(box2) assert bool(inter1) assert inter1.area == 200.0 inter2 = box1.intersection(box4) assert not bool(inter2) assert inter2.is_empty # assert not inter2.is_valid TODO: what's going on here? diff1 = box1.difference(box2) assert diff1.area == 200.0 symdiff1 = box1.symmetric_difference(box2) assert symdiff1.area == 400.0 # test segmented line = geometry.line([(0, 0), (0, 5), (10, 5)], epsg4326) line2 = line.segmented(2) assert line.crs is line2.crs assert line.length == line2.length assert len(line.coords) < len(line2.coords) # test interpolate pt = line.interpolate(1) assert pt.crs is line.crs assert pt.coords[0] == (0, 1) assert pt.interpolate(3) is None
def test_multigeom(): p1, p2 = (0, 0), (1, 2) p3, p4 = (3, 4), (5, 6) b1 = geometry.box(*p1, *p2, epsg4326) b2 = geometry.box(*p3, *p4, epsg4326) bb = multigeom([b1, b2]) assert bb.type == 'MultiPolygon' assert bb.crs is b1.crs assert len(list(bb)) == 2 g1 = geometry.line([p1, p2], None) g2 = geometry.line([p3, p4], None) gg = multigeom(iter([g1, g2, g1])) assert gg.type == 'MultiLineString' assert gg.crs is g1.crs assert len(list(gg)) == 3 g1 = geometry.point(*p1, epsg3857) g2 = geometry.point(*p2, epsg3857) g3 = geometry.point(*p3, epsg3857) gg = multigeom(iter([g1, g2, g3])) assert gg.type == 'MultiPoint' assert gg.crs is g1.crs assert len(list(gg)) == 3 assert list(gg)[0] == g1 assert list(gg)[1] == g2 assert list(gg)[2] == g3 # can't mix types with pytest.raises(ValueError): multigeom([geometry.line([p1, p2], None), geometry.point(*p1, None)]) # can't mix CRSs with pytest.raises(CRSMismatchError): multigeom([ geometry.line([p1, p2], epsg4326), geometry.line([p3, p4], epsg3857) ]) # only some types are supported on input with pytest.raises(ValueError): multigeom([gg])
def test_extent_and_spatial(): cfg = get_config() lyr = list(cfg.product_index.values())[0] layer_ext_bbx = ( lyr.bboxes["EPSG:4326"]["left"], lyr.bboxes["EPSG:4326"]["bottom"], lyr.bboxes["EPSG:4326"]["right"], lyr.bboxes["EPSG:4326"]["top"], ) small_bbox = pytest.helpers.enclosed_bbox(layer_ext_bbx) layer_ext_geom = box( layer_ext_bbx[0], layer_ext_bbx[1], layer_ext_bbx[2], layer_ext_bbx[3], "EPSG:4326", ) small_geom = box(small_bbox[0], small_bbox[1], small_bbox[2], small_bbox[3], "EPSG:4326") with cube() as dc: all_ext = mv_search_datasets(dc.index, MVSelectOpts.EXTENT, geom=layer_ext_geom, layer=lyr) small_ext = mv_search_datasets(dc.index, MVSelectOpts.EXTENT, geom=small_geom, layer=lyr) assert layer_ext_geom.contains(all_ext) assert small_geom.contains(small_ext) assert all_ext.contains(small_ext) assert small_ext.area < all_ext.area all_count = mv_search_datasets(dc.index, MVSelectOpts.COUNT, geom=layer_ext_geom, layer=lyr) small_count = mv_search_datasets(dc.index, MVSelectOpts.COUNT, geom=small_geom, layer=lyr) assert small_count <= all_count
def __init__(self, resolution: Tuple[int, int] = (-20, 20), crs: str = "epsg:6933"): target_crs = CRS(crs) self.albers_africa_N = GridSpec( crs=target_crs, tile_size=(96_000.0, 96_000.0), # default resolution=resolution, ) africa = box(-18, -38, 60, 30, "epsg:4326") self.africa_projected = africa.to_crs(crs, resolution=math.inf)
def test_props(): box1 = geometry.box(10, 10, 30, 30, crs=geometry.CRS('EPSG:4326')) assert box1 assert box1.is_valid assert not box1.is_empty assert box1.area == 400.0 assert box1.boundary.length == 80.0 assert box1.centroid == geometry.point(20, 20, geometry.CRS('EPSG:4326')) triangle = geometry.polygon([(10, 20), (20, 20), (20, 10), (10, 20)], crs=geometry.CRS('EPSG:4326')) assert triangle.envelope == geometry.BoundingBox(10, 10, 20, 20) outer = next(iter(box1)) assert outer.length == 80.0 box1copy = geometry.box(10, 10, 30, 30, crs=geometry.CRS('EPSG:4326')) assert box1 == box1copy assert box1.convex_hull == box1copy # NOTE: this might fail because of point order box2 = geometry.box(20, 10, 40, 30, crs=geometry.CRS('EPSG:4326')) assert box1 != box2
def test_unary_intersection(): box1 = geometry.box(10, 10, 30, 30, crs=geometry.CRS('EPSG:4326')) box2 = geometry.box(15, 10, 35, 30, crs=geometry.CRS('EPSG:4326')) box3 = geometry.box(20, 10, 40, 30, crs=geometry.CRS('EPSG:4326')) box4 = geometry.box(25, 10, 45, 30, crs=geometry.CRS('EPSG:4326')) box5 = geometry.box(30, 10, 50, 30, crs=geometry.CRS('EPSG:4326')) box6 = geometry.box(35, 10, 55, 30, crs=geometry.CRS('EPSG:4326')) inter1 = geometry.unary_intersection([box1]) assert bool(inter1) assert inter1 == box1 inter2 = geometry.unary_intersection([box1, box2]) assert bool(inter2) assert inter2.area == 300.0 inter3 = geometry.unary_intersection([box1, box2, box3]) assert bool(inter3) assert inter3.area == 200.0 inter4 = geometry.unary_intersection([box1, box2, box3, box4]) assert bool(inter4) assert inter4.area == 100.0 inter5 = geometry.unary_intersection([box1, box2, box3, box4, box5]) assert bool(inter5) assert inter5.type == 'LineString' assert inter5.length == 20.0 inter6 = geometry.unary_intersection([box1, box2, box3, box4, box5, box6]) assert not bool(inter6) assert inter6.is_empty
def test_ops(): box1 = geometry.box(10, 10, 30, 30, crs=geometry.CRS('EPSG:4326')) box2 = geometry.box(20, 10, 40, 30, crs=geometry.CRS('EPSG:4326')) box4 = geometry.box(40, 10, 60, 30, crs=geometry.CRS('EPSG:4326')) union1 = box1.union(box2) assert union1.area == 600.0 inter1 = box1.intersection(box2) assert bool(inter1) assert inter1.area == 200.0 inter2 = box1.intersection(box4) assert not bool(inter2) assert inter2.is_empty # assert not inter2.is_valid TODO: what's going on here? diff1 = box1.difference(box2) assert diff1.area == 200.0 symdiff1 = box1.symmetric_difference(box2) assert symdiff1.area == 400.0
def test_props(): crs = epsg4326 box1 = geometry.box(10, 10, 30, 30, crs=crs) assert box1 assert box1.is_valid assert not box1.is_empty assert box1.area == 400.0 assert box1.boundary.length == 80.0 assert box1.centroid == geometry.point(20, 20, crs) triangle = geometry.polygon([(10, 20), (20, 20), (20, 10), (10, 20)], crs=crs) assert triangle.envelope == geometry.BoundingBox(10, 10, 20, 20) outer = next(iter(box1)) assert outer.length == 80.0 box1copy = geometry.box(10, 10, 30, 30, crs=crs) assert box1 == box1copy assert box1.convex_hull == box1copy # NOTE: this might fail because of point order box2 = geometry.box(20, 10, 40, 30, crs=crs) assert box1 != box2 bbox = geometry.BoundingBox(1, 0, 10, 13) assert bbox.width == 9 assert bbox.height == 13 assert bbox.points == [(1, 0), (1, 13), (10, 0), (10, 13)] assert bbox.transform(Affine.identity()) == bbox assert bbox.transform(Affine.translation(1, 2)) == geometry.BoundingBox( 2, 2, 11, 15) pt = geometry.point(3, 4, crs) assert pt.json['coordinates'] == (3.0, 4.0) assert 'Point' in str(pt) assert bool(pt) is True assert pt.__nonzero__() is True
def test_mid_lon(lon, lat): r = 0.1 rect = geom.box(lon - r, lat - r, lon + r, lat + r, "epsg:4326") assert rect.centroid.coords[0] == pytest.approx((lon, lat)) assert mid_longitude(rect) == pytest.approx(lon) assert mid_longitude(rect.to_crs("epsg:3857")) == pytest.approx(lon) offset = solar_offset(rect, "h") assert offset.seconds % (60 * 60) == 0 offset_sec = solar_offset(rect, "s") assert abs((offset - offset_sec).seconds) <= 60 * 60
def test_unary_union(): box1 = geometry.box(10, 10, 30, 30, crs=geometry.CRS('EPSG:4326')) box2 = geometry.box(20, 10, 40, 30, crs=geometry.CRS('EPSG:4326')) box3 = geometry.box(30, 10, 50, 30, crs=geometry.CRS('EPSG:4326')) box4 = geometry.box(40, 10, 60, 30, crs=geometry.CRS('EPSG:4326')) union0 = geometry.unary_union([box1]) assert union0 == box1 union1 = geometry.unary_union([box1, box4]) assert union1.type == 'MultiPolygon' assert union1.area == 2.0 * box1.area union2 = geometry.unary_union([box1, box2]) assert union2.type == 'Polygon' assert union2.area == 1.5 * box1.area union3 = geometry.unary_union([box1, box2, box3, box4]) assert union3.type == 'Polygon' assert union3.area == 2.5 * box1.area union4 = geometry.unary_union([union1, box2, box3]) assert union4.type == 'Polygon' assert union4.area == 2.5 * box1.area
def test_time_search(): cfg = get_config() lyr = list(cfg.product_index.values())[0] time = lyr.ranges["times"][-1] geom = box(lyr.bboxes["EPSG:4326"]["bottom"], lyr.bboxes["EPSG:4326"]["left"], lyr.bboxes["EPSG:4326"]["top"], lyr.bboxes["EPSG:4326"]["right"], "EPSG:4326") time_rng = local_solar_date_range(MockGeobox(geom), time) with cube() as dc: sel = mv_search_datasets(dc.index, MVSelectOpts.COUNT, times=[time_rng], layer=lyr) assert sel > 0
def b_neg(lside): return geometry.box(lside, 0, -170, 10, epsg4326)
def b(rside): return geometry.box(170, 0, rside, 10, epsg4326)