def parse_gridspec(s: str) -> GridSpec: """ "albers_africa_10" "epsg:6936;10;9600" "epsg:6936;-10x10;9600x9600" """ named_gs = GRIDS.get(s) if named_gs is not None: return named_gs crs, res, shape = split_and_check(s, ';', 3) try: if 'x' in res: res = tuple(float(v) for v in split_and_check(res, 'x', 2)) else: res = float(res) res = (-res, res) if 'x' in shape: shape = parse_range_int(shape, separator='x') else: shape = int(shape) shape = (shape, shape) except ValueError: raise ValueError(f"Failed to parse gridspec: {s}") tsz = tuple(abs(n * res) for n, res in zip(res, shape)) return GridSpec(crs=CRS(crs), tile_size=tsz, resolution=res, origin=(0, 0))
def test_split_check(): assert split_and_check("one/two/three", '/', 3) == ('one', 'two', 'three') assert split_and_check("one/two/three", '/', (3, 4)) == ('one', 'two', 'three') with pytest.raises(ValueError): split_and_check("a:b", ":", 3)
def _parse_gridspec_string(s: str) -> GridSpec: """ "epsg:6936;10;9600" "epsg:6936;-10x10;9600x9600" """ crs, res, shape = split_and_check(s, ";", 3) try: if "x" in res: res = tuple(float(v) for v in split_and_check(res, "x", 2)) else: res = float(res) res = (-res, res) if "x" in shape: shape = parse_range_int(shape, separator="x") else: shape = int(shape) shape = (shape, shape) except ValueError: raise ValueError(f"Failed to parse gridspec: {s}") tsz = tuple(abs(n * res) for n, res in zip(res, shape)) return GridSpec(crs=CRS(crs), tile_size=tsz, resolution=res, origin=(0, 0))
def test_split_check(): assert split_and_check("one/two/three", "/", 3) == ("one", "two", "three") assert split_and_check("one/two/three", "/", (3, 4)) == ("one", "two", "three") with pytest.raises(ValueError): split_and_check("a:b", ":", 3)
def __init__(self, start: Union[str, datetime], freq: Optional[str] = None): """ DateTimeRange('2019-03--P3M') DateTimeRange('2019-03', '3M') DateTimeRange(datetime(2019, 3, 1), '3M') """ if freq is None: assert isinstance(start, str) start, freq = split_and_check(start, '--P', 2) freq = freq.upper().lstrip('P') # Pandas period snaps to frequency resolution, we need to undo that by re-adding the snapping delta t0 = pd.Timestamp(start) period = pd.Period(t0, freq=freq) dt = t0 - period.start_time self.freq: str = freq self.start: datetime = normalise_dt(t0.to_pydatetime(warn=False)) self.end: datetime = normalise_dt( (period.end_time + dt).to_pydatetime(warn=False))
def parse_group_name(group_name: str) -> Tuple[TileIdx, str]: """ Return an ((int, int), prefix:str) x,y ((str, int, int), prefix:str) t,x,y tuple from group name. Expects group to be in the form {prefix}/{x}/{y} or {prefix}/{t}/{x}/{y} raises ValueError if group_name is not in the expected format. """ try: prefix, *tidx = split_and_check(group_name, '/', (3, 4)) x, y = map(int, tidx[-2:]) except ValueError: raise ValueError('Bad group name: ' + group_name) if len(tidx) == 2: return (x, y), prefix return (cast(str, tidx[0]), x, y), prefix
def parse_task(s: str) -> TileIdx: from odc.io.text import split_and_check sep = '/' if '/' in s else ',' t, x, y = split_and_check(s, sep, 3) if t.startswith('x'): t, x, y = y, t, x return (t, int(x.lstrip('x')), int(y.lstrip('y')))
def parse_resolution(s: str, separator: str = ",") -> Tuple[float, float]: from odc.io.text import split_and_check parts = [float(v) for v in split_and_check(s, separator, (1, 2))] if len(parts) == 1: return (-parts[0], parts[0]) return (parts[0], parts[1])
def parse_task(s: str) -> TileIdx_txy: """ Intentional copy of tasks.parse_task only for CLI parsing """ from odc.io.text import split_and_check sep = "/" if "/" in s else "," t, x, y = split_and_check(s, sep, 3) if t.startswith("x"): t, x, y = y, t, x return (t, int(x.lstrip("x")), int(y.lstrip("y")))
def parse_task(s: str) -> TileIdx_txy: sep = "/" if "/" in s else "," t, x, y = split_and_check(s, sep, 3) if t.startswith("x"): t, x, y = y, t, x return (t, int(x.lstrip("x")), int(y.lstrip("y")))