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 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, attribute: str) -> bool:
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
- attribute: The attribute name to check on the object.
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
- return hasattr(obj.__class__, attribute) and isinstance(
86
- getattr(obj.__class__, attribute), property
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.norges_grunnkart,
148
- "gråtone": kartverket.norges_grunnkart_gråtone,
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
- "OpenStreetMap",
221
- "dark",
217
+ tiles: ClassVar[tuple[str, ...]] = (
218
+ "grunnkart",
222
219
  "norge_i_bilder",
223
- # "grunnkart",
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 red_band.shape[0] == 0:
1203
- continue
1204
- if blue_band.shape[0] == 0:
1205
- continue
1206
- if green_band.shape[0] == 0:
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.stem:
1280
- name = obj.stem
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
- from jenkspy import jenks_breaks
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
- norgeskart=TileProvider(
7
- name="Norgeskart",
8
- url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=norgeskart_bakgrunn&zoom={z}&x={x}&y={y}",
9
- attribution="© Kartverket",
10
- html_attribution='&copy; <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='&copy; <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='&copy; <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='&copy; <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='&copy; <a href="https://kartverket.no">Kartverket</a>',
35
11
  ),
36
12
  topogråtone=TileProvider(
37
13
  name="Topografisk norgeskart gråtone",
38
- url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4graatone&zoom={z}&x={x}&y={y}",
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='&copy; <a href="https://kartverket.no">Kartverket</a>',
41
17
  ),
42
18
  toporaster=TileProvider(
43
19
  name="Topografisk raster",
44
- url="https://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=toporaster4&zoom={z}&x={x}&y={y}",
20
+ url="https://cache.kartverket.no/v1/wmts/1.0.0/toporaster/default/webmercator/{z}/{y}/{x}.png",
21
+ attribution="© Kartverket",
22
+ html_attribution='&copy; <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='&copy; <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
- )