12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 | @dataclass
class Layout:
"""
Layout
Attributes:
overviews_min_size: Maximum width or height of the smallest overview level. 0: No overview, -1: default=256.
interlacing_pattern: To define how to interlace the records, the blocks, the bands and the overviews.
See https://airbusgeo.github.io/geocube/user-guide/grpc/#geocube-ConsolidationParams
"""
name: str
grid_flags: List[str]
grid_parameters: Dict[str, str]
block_shape: Tuple[int, int]
max_records: int = field(default=1000)
overviews_min_size: int = field(default=-1)
interlacing_pattern: str = field(default=MUCOGPattern)
@classmethod
def from_pb(cls, pb_layout: layouts_pb2.Layout):
return cls(pb_layout.name, pb_layout.grid_flags, pb_layout.grid_parameters,
(pb_layout.block_x_size, pb_layout.block_y_size), pb_layout.max_records,
pb_layout.overviews_min_size, pb_layout.interlacing_pattern)
def to_pb(self):
return layouts_pb2.Layout(
name=self.name,
grid_flags=self.grid_flags,
grid_parameters=self.grid_parameters,
block_x_size=self.block_shape[0],
block_y_size=self.block_shape[1],
max_records=self.max_records,
overviews_min_size=self.overviews_min_size,
interlacing_pattern=self.interlacing_pattern
)
@classmethod
def regular(cls, name: str, crs: str, cell_size: Union[int, Tuple[int, int]], resolution: float,
block_size: int = 256, max_records: int = 1000,
overviews_min_size: int = -1, interlacing_pattern=MUCOGPattern,
origin: Tuple[float, float] = None):
grid_parameters = {
"grid": "regular",
"crs": crs,
"resolution": f"{resolution}",
}
if isinstance(cell_size, tuple):
grid_parameters["cell_x_size"] = f"{cell_size[0]}"
grid_parameters["cell_y_size"] = f"{cell_size[1]}"
else:
grid_parameters["cell_size"] = f"{cell_size}"
if origin is not None:
grid_parameters["ox"] = f"{origin[0]}"
grid_parameters["oy"] = f"{origin[1]}"
return cls(
name=name,
grid_parameters=grid_parameters,
grid_flags=[],
block_shape=(block_size, block_size),
max_records=max_records,
overviews_min_size=overviews_min_size,
interlacing_pattern=interlacing_pattern
)
@classmethod
def single_cell(cls, name: str, crs: str, resolution: int,
block_size: int = 256, max_records: int = 1000,
overviews_min_size: int = -1, interlacing_pattern=MUCOGPattern):
grid_parameters = {
"grid": "singlecell",
"crs": crs,
"resolution": f"{resolution}",
}
grid_flags = []
return cls(
name=name,
grid_parameters=grid_parameters,
grid_flags=grid_flags,
block_shape=(block_size, block_size),
max_records=max_records,
overviews_min_size=overviews_min_size,
interlacing_pattern=interlacing_pattern
)
@classmethod
def web_mercator(cls, name: str, z_level: int, cell_size: int = 4096, **kwargs):
""" Define a regular layout using web-mercator projection at a given z_level """
earth_perimeter = 2*6378137*math.pi
ox, oy, resolution = -earth_perimeter/2, earth_perimeter/2, earth_perimeter/(256*(1 << z_level))
return Layout.regular(name, "epsg:3857", cell_size=cell_size, resolution=resolution, origin=(ox, oy), **kwargs)
def __repr__(self):
return f"Layout '{self.name}'"
def __str__(self):
return "Layout '{}'\n" \
" grid_flags\n{}\n" \
" grid_parameters\n{}\n" \
" block_shape {}\n" \
" max_records {}\n" \
" overview_min_size {}\n" \
" interlacing_pattern {}\n".format(self.name, " \n".join(self.grid_flags),
pprint.pformat(self.grid_parameters, indent=7, width=1),
self.block_shape, self.max_records,
self.overviews_min_size, self.interlacing_pattern)
|