ssb-sgis 1.0.6__py3-none-any.whl → 1.0.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sgis/helpers.py +23 -7
- sgis/maps/explore.py +14 -35
- sgis/maps/map.py +5 -1
- sgis/maps/tilesources.py +11 -29
- sgis/raster/base.py +0 -54
- sgis/raster/image_collection.py +936 -580
- sgis/raster/indices.py +2 -5
- sgis/raster/regex.py +7 -2
- sgis/raster/sentinel_config.py +1 -71
- {ssb_sgis-1.0.6.dist-info → ssb_sgis-1.0.8.dist-info}/METADATA +1 -1
- {ssb_sgis-1.0.6.dist-info → ssb_sgis-1.0.8.dist-info}/RECORD +13 -13
- {ssb_sgis-1.0.6.dist-info → ssb_sgis-1.0.8.dist-info}/LICENSE +0 -0
- {ssb_sgis-1.0.6.dist-info → ssb_sgis-1.0.8.dist-info}/WHEEL +0 -0
sgis/helpers.py
CHANGED
|
@@ -72,19 +72,29 @@ def to_numpy_func(text: str) -> Callable:
|
|
|
72
72
|
raise ValueError
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
def is_property(obj: object,
|
|
75
|
+
def is_property(obj: object, attr: str) -> bool:
|
|
76
76
|
"""Determine if a class attribute is a property.
|
|
77
77
|
|
|
78
78
|
Args:
|
|
79
79
|
obj: The object to check.
|
|
80
|
-
|
|
80
|
+
attr: The attribute name to check on the object.
|
|
81
81
|
|
|
82
82
|
Returns:
|
|
83
83
|
True if the attribute is a property, False otherwise.
|
|
84
84
|
"""
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
85
|
+
if not hasattr(obj.__class__, attr):
|
|
86
|
+
return False
|
|
87
|
+
if isinstance(obj, type):
|
|
88
|
+
return isinstance(getattr(obj, attr), property)
|
|
89
|
+
else:
|
|
90
|
+
return isinstance(getattr(obj.__class__, attr), property)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def is_method(obj: Any, attr: str) -> bool:
|
|
94
|
+
if isinstance(obj, type):
|
|
95
|
+
return inspect.ismethod(getattr(obj, attr, None))
|
|
96
|
+
else:
|
|
97
|
+
return inspect.ismethod(getattr(obj.__class__, attr, None))
|
|
88
98
|
|
|
89
99
|
|
|
90
100
|
def dict_zip_intersection(*dicts: dict) -> Generator[tuple[Any, ...], None, None]:
|
|
@@ -130,6 +140,12 @@ def in_jupyter() -> bool:
|
|
|
130
140
|
return False
|
|
131
141
|
|
|
132
142
|
|
|
143
|
+
def _fix_path(path: str) -> str:
|
|
144
|
+
return (
|
|
145
|
+
str(path).replace("\\", "/").replace(r"\"", "/").replace("//", "/").rstrip("/")
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
133
149
|
def get_all_files(root: str, recursive: bool = True) -> list[str]:
|
|
134
150
|
"""Fetch all files in a directory.
|
|
135
151
|
|
|
@@ -141,11 +157,11 @@ def get_all_files(root: str, recursive: bool = True) -> list[str]:
|
|
|
141
157
|
A list of file paths.
|
|
142
158
|
"""
|
|
143
159
|
if not recursive:
|
|
144
|
-
return [path for path in glob.glob(str(Path(root)) + "/**")]
|
|
160
|
+
return [_fix_path(path) for path in glob.glob(str(Path(root)) + "/**")]
|
|
145
161
|
paths = []
|
|
146
162
|
for root_dir, _, files in os.walk(root):
|
|
147
163
|
for file in files:
|
|
148
|
-
path = os.path.join(root_dir, file)
|
|
164
|
+
path = _fix_path(os.path.join(root_dir, file))
|
|
149
165
|
paths.append(path)
|
|
150
166
|
return paths
|
|
151
167
|
|
sgis/maps/explore.py
CHANGED
|
@@ -144,8 +144,8 @@ def to_tile(tile: str | xyzservices.TileProvider, max_zoom: int) -> folium.TileL
|
|
|
144
144
|
"openstreetmap": folium.TileLayer(
|
|
145
145
|
"OpenStreetMap", min_zoom=0, max_zoom=max_zoom
|
|
146
146
|
),
|
|
147
|
-
"grunnkart": kartverket.
|
|
148
|
-
"gråtone": kartverket.
|
|
147
|
+
"grunnkart": kartverket.topo,
|
|
148
|
+
"gråtone": kartverket.topogråtone,
|
|
149
149
|
"norge_i_bilder": kartverket.norge_i_bilder,
|
|
150
150
|
"dark": xyz.CartoDB.DarkMatter,
|
|
151
151
|
"voyager": xyz.CartoDB.Voyager,
|
|
@@ -194,8 +194,6 @@ def _single_band_to_arr(band, mask, name, raster_data_dict):
|
|
|
194
194
|
gpd.GeoSeries(box(*band.bounds), crs=band.crs).to_crs(4326).geometry.values
|
|
195
195
|
).bounds
|
|
196
196
|
)
|
|
197
|
-
# if np.max(arr) > 0:
|
|
198
|
-
# arr = arr / 255
|
|
199
197
|
try:
|
|
200
198
|
raster_data_dict["cmap"] = band.get_cmap(arr)
|
|
201
199
|
except Exception:
|
|
@@ -216,11 +214,11 @@ class Explore(Map):
|
|
|
216
214
|
"""Class for displaying and saving html maps of multiple GeoDataFrames."""
|
|
217
215
|
|
|
218
216
|
# class attribute that can be overridden locally
|
|
219
|
-
tiles: ClassVar[tuple[str]] = (
|
|
220
|
-
"
|
|
221
|
-
"dark",
|
|
217
|
+
tiles: ClassVar[tuple[str, ...]] = (
|
|
218
|
+
"grunnkart",
|
|
222
219
|
"norge_i_bilder",
|
|
223
|
-
|
|
220
|
+
"dark",
|
|
221
|
+
"OpenStreetMap",
|
|
224
222
|
)
|
|
225
223
|
|
|
226
224
|
def __init__(
|
|
@@ -533,8 +531,6 @@ class Explore(Map):
|
|
|
533
531
|
arr = arr.data
|
|
534
532
|
if "bool" in str(arr.dtype):
|
|
535
533
|
arr = np.where(arr, 1, 0)
|
|
536
|
-
# if np.max(arr[~np.isnan(arr)]) > 255:
|
|
537
|
-
# arr = (arr - np.min(arr)) / (np.max(arr) - np.min(arr))
|
|
538
534
|
try:
|
|
539
535
|
arr = (arr - np.min(arr)) / (np.max(arr) - np.min(arr))
|
|
540
536
|
except Exception:
|
|
@@ -1182,28 +1178,17 @@ class Explore(Map):
|
|
|
1182
1178
|
break
|
|
1183
1179
|
|
|
1184
1180
|
crs = red_band.crs
|
|
1185
|
-
|
|
1186
|
-
bounds: tuple = (
|
|
1187
|
-
_any_to_bbox_crs4326(mask, crs)
|
|
1188
|
-
if mask is not None
|
|
1189
|
-
else (
|
|
1190
|
-
union_all(
|
|
1191
|
-
gpd.GeoSeries(box(*red_band.bounds), crs=crs)
|
|
1192
|
-
.to_crs(4326)
|
|
1193
|
-
.geometry.values
|
|
1194
|
-
).bounds
|
|
1195
|
-
)
|
|
1196
|
-
)
|
|
1181
|
+
bounds = to_bbox(to_gdf(red_band.bounds, crs).to_crs(4326))
|
|
1197
1182
|
|
|
1198
1183
|
red_band = red_band.values
|
|
1199
1184
|
blue_band = blue_band.values
|
|
1200
1185
|
green_band = green_band.values
|
|
1201
1186
|
|
|
1202
|
-
if
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1187
|
+
if (
|
|
1188
|
+
red_band.shape[0] == 0
|
|
1189
|
+
or blue_band.shape[0] == 0
|
|
1190
|
+
or green_band.shape[0] == 0
|
|
1191
|
+
):
|
|
1207
1192
|
continue
|
|
1208
1193
|
|
|
1209
1194
|
# to 3d array in shape (x, y, 3)
|
|
@@ -1268,16 +1253,10 @@ def _determine_label(
|
|
|
1268
1253
|
)
|
|
1269
1254
|
if does_not_have_generic_name:
|
|
1270
1255
|
return obj_name
|
|
1271
|
-
# try:
|
|
1272
|
-
# if obj.tile and obj.date:
|
|
1273
|
-
# name = f"{obj.tile}_{obj.date[:8]}"
|
|
1274
|
-
# except (ValueError, AttributeError):
|
|
1275
|
-
# name = None
|
|
1276
|
-
|
|
1277
1256
|
try:
|
|
1278
1257
|
# Images/Bands/Collections constructed from arrays have no path stems
|
|
1279
|
-
if obj.
|
|
1280
|
-
name = obj.
|
|
1258
|
+
if obj.name:
|
|
1259
|
+
name = obj.name
|
|
1281
1260
|
else:
|
|
1282
1261
|
name = str(obj)[:23]
|
|
1283
1262
|
except (AttributeError, ValueError):
|
sgis/maps/map.py
CHANGED
|
@@ -14,7 +14,11 @@ import numpy as np
|
|
|
14
14
|
import pandas as pd
|
|
15
15
|
from geopandas import GeoDataFrame
|
|
16
16
|
from geopandas import GeoSeries
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from jenkspy import jenks_breaks
|
|
20
|
+
except ImportError:
|
|
21
|
+
pass
|
|
18
22
|
from mapclassify import classify
|
|
19
23
|
from pandas.errors import PerformanceWarning
|
|
20
24
|
from shapely import Geometry
|
sgis/maps/tilesources.py
CHANGED
|
@@ -3,45 +3,27 @@ from xyzservices import TileProvider
|
|
|
3
3
|
from xyzservices import providers
|
|
4
4
|
|
|
5
5
|
kartverket = Bunch(
|
|
6
|
-
|
|
7
|
-
name="
|
|
8
|
-
url="https://
|
|
9
|
-
attribution="© Kartverket",
|
|
10
|
-
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
11
|
-
),
|
|
12
|
-
bakgrunnskart_forenklet=TileProvider(
|
|
13
|
-
name="Norgeskart forenklet",
|
|
14
|
-
url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=bakgrunnskart_forenklet&zoom={z}&x={x}&y={y}",
|
|
15
|
-
attribution="© Kartverket",
|
|
16
|
-
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
17
|
-
),
|
|
18
|
-
norges_grunnkart=TileProvider(
|
|
19
|
-
name="Norges grunnkart",
|
|
20
|
-
url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=norges_grunnkart&zoom={z}&x={x}&y={y}",
|
|
21
|
-
attribution="© Kartverket",
|
|
22
|
-
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
23
|
-
),
|
|
24
|
-
norges_grunnkart_gråtone=TileProvider(
|
|
25
|
-
name="Norges grunnkart gråtone",
|
|
26
|
-
url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=norges_grunnkart_graatone&zoom={z}&x={x}&y={y}",
|
|
27
|
-
attribution="© Kartverket",
|
|
28
|
-
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
29
|
-
),
|
|
30
|
-
n50=TileProvider(
|
|
31
|
-
name="N5 til N50 kartdata",
|
|
32
|
-
url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=kartdata3&zoom={z}&x={x}&y={y}",
|
|
6
|
+
topo=TileProvider(
|
|
7
|
+
name="Topografisk norgeskart",
|
|
8
|
+
url="https://cache.kartverket.no/v1/wmts/1.0.0/topo/default/webmercator/{z}/{y}/{x}.png",
|
|
33
9
|
attribution="© Kartverket",
|
|
34
10
|
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
35
11
|
),
|
|
36
12
|
topogråtone=TileProvider(
|
|
37
13
|
name="Topografisk norgeskart gråtone",
|
|
38
|
-
url="https://
|
|
14
|
+
url="https://cache.kartverket.no/v1/wmts/1.0.0/topograatone/default/webmercator/{z}/{y}/{x}.png",
|
|
39
15
|
attribution="© Kartverket",
|
|
40
16
|
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
41
17
|
),
|
|
42
18
|
toporaster=TileProvider(
|
|
43
19
|
name="Topografisk raster",
|
|
44
|
-
url="https://
|
|
20
|
+
url="https://cache.kartverket.no/v1/wmts/1.0.0/toporaster/default/webmercator/{z}/{y}/{x}.png",
|
|
21
|
+
attribution="© Kartverket",
|
|
22
|
+
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
23
|
+
),
|
|
24
|
+
sjøkart=TileProvider(
|
|
25
|
+
name="Sjøkart",
|
|
26
|
+
url="https://cache.kartverket.no/v1/wmts/1.0.0/sjokartraster/default/webmercator/{z}/{y}/{x}.png",
|
|
45
27
|
attribution="© Kartverket",
|
|
46
28
|
html_attribution='© <a href="https://kartverket.no">Kartverket</a>',
|
|
47
29
|
),
|
sgis/raster/base.py
CHANGED
|
@@ -189,30 +189,6 @@ def _gdf_to_geojson_with_col(gdf: GeoDataFrame, values: np.ndarray) -> list[dict
|
|
|
189
189
|
]
|
|
190
190
|
|
|
191
191
|
|
|
192
|
-
def _shapely_to_raster(
|
|
193
|
-
geometry: Geometry,
|
|
194
|
-
res: int | float,
|
|
195
|
-
fill: int = 0,
|
|
196
|
-
all_touched: bool = False,
|
|
197
|
-
merge_alg: Callable = MergeAlg.replace,
|
|
198
|
-
default_value: int = 1,
|
|
199
|
-
dtype: Any | None = None,
|
|
200
|
-
) -> np.array:
|
|
201
|
-
shape = _get_shape_from_bounds(geometry.bounds, res=res, indexes=1)
|
|
202
|
-
transform = _get_transform_from_bounds(geometry.bounds, shape)
|
|
203
|
-
|
|
204
|
-
return features.rasterize(
|
|
205
|
-
[(geometry, default_value)],
|
|
206
|
-
out_shape=shape,
|
|
207
|
-
transform=transform,
|
|
208
|
-
fill=fill,
|
|
209
|
-
all_touched=all_touched,
|
|
210
|
-
merge_alg=merge_alg,
|
|
211
|
-
default_value=default_value,
|
|
212
|
-
dtype=dtype,
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
|
|
216
192
|
@contextmanager
|
|
217
193
|
def memfile_from_array(array: np.ndarray, **profile) -> rasterio.MemoryFile:
|
|
218
194
|
"""Yield a memory file from a numpy array."""
|
|
@@ -228,33 +204,3 @@ def get_index_mapper(df: pd.DataFrame) -> tuple[dict[int, int], str]:
|
|
|
228
204
|
idx_mapper = dict(enumerate(df.index))
|
|
229
205
|
idx_name = df.index.name
|
|
230
206
|
return idx_mapper, idx_name
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
NESSECARY_META = [
|
|
234
|
-
"path",
|
|
235
|
-
"type",
|
|
236
|
-
"bounds",
|
|
237
|
-
"crs",
|
|
238
|
-
]
|
|
239
|
-
|
|
240
|
-
PROFILE_ATTRS = [
|
|
241
|
-
"driver",
|
|
242
|
-
"dtype",
|
|
243
|
-
"nodata",
|
|
244
|
-
"crs",
|
|
245
|
-
"height",
|
|
246
|
-
"width",
|
|
247
|
-
"blockysize",
|
|
248
|
-
"blockxsize",
|
|
249
|
-
"tiled",
|
|
250
|
-
"compress",
|
|
251
|
-
"interleave",
|
|
252
|
-
"count", # TODO: this should be based on band_index / array depth, so will have no effect
|
|
253
|
-
"indexes", # TODO
|
|
254
|
-
]
|
|
255
|
-
|
|
256
|
-
ALLOWED_KEYS = (
|
|
257
|
-
NESSECARY_META
|
|
258
|
-
+ PROFILE_ATTRS
|
|
259
|
-
+ ["array", "res", "transform", "name", "date", "regex"]
|
|
260
|
-
)
|