ssb-sgis 1.1.5__py3-none-any.whl → 1.1.6__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/geopandas_tools/cleaning.py +18 -14
- sgis/geopandas_tools/duplicates.py +1 -1
- sgis/geopandas_tools/general.py +5 -2
- sgis/io/dapla_functions.py +4 -1
- sgis/maps/explore.py +2 -3
- sgis/maps/httpserver.py +12 -0
- sgis/maps/map.py +32 -2
- sgis/parallel/parallel.py +0 -1
- sgis/raster/image_collection.py +17 -3
- {ssb_sgis-1.1.5.dist-info → ssb_sgis-1.1.6.dist-info}/METADATA +1 -1
- {ssb_sgis-1.1.5.dist-info → ssb_sgis-1.1.6.dist-info}/RECORD +13 -13
- {ssb_sgis-1.1.5.dist-info → ssb_sgis-1.1.6.dist-info}/LICENSE +0 -0
- {ssb_sgis-1.1.5.dist-info → ssb_sgis-1.1.6.dist-info}/WHEEL +0 -0
sgis/geopandas_tools/cleaning.py
CHANGED
|
@@ -101,18 +101,18 @@ def coverage_clean(
|
|
|
101
101
|
|
|
102
102
|
_cleaning_checks(gdf, tolerance, duplicate_action)
|
|
103
103
|
|
|
104
|
-
if not gdf.index.is_unique:
|
|
105
|
-
|
|
104
|
+
# if not gdf.index.is_unique:
|
|
105
|
+
# gdf = gdf.reset_index(drop=True)
|
|
106
106
|
|
|
107
|
-
gdf = make_all_singlepart(gdf).loc[
|
|
108
|
-
|
|
109
|
-
]
|
|
107
|
+
# gdf = make_all_singlepart(gdf).loc[
|
|
108
|
+
# lambda x: x.geom_type.isin(["Polygon", "MultiPolygon"])
|
|
109
|
+
# ]
|
|
110
110
|
|
|
111
|
-
gdf = safe_simplify(gdf, PRECISION)
|
|
111
|
+
# gdf = safe_simplify(gdf, PRECISION)
|
|
112
112
|
|
|
113
113
|
gdf = (
|
|
114
114
|
clean_geoms(gdf)
|
|
115
|
-
.pipe(make_all_singlepart)
|
|
115
|
+
.pipe(make_all_singlepart, ignore_index=True)
|
|
116
116
|
.loc[lambda x: x.geom_type.isin(["Polygon", "MultiPolygon"])]
|
|
117
117
|
)
|
|
118
118
|
|
|
@@ -475,14 +475,14 @@ def _dissolve_thick_double_and_update(gdf, double, thin_double):
|
|
|
475
475
|
large = (
|
|
476
476
|
double.loc[~double["_double_idx"].isin(thin_double["_double_idx"])]
|
|
477
477
|
.drop(columns="_double_idx")
|
|
478
|
-
|
|
479
|
-
.sort_values("_poly_idx")
|
|
478
|
+
.pipe(sort_small_first)
|
|
479
|
+
# .sort_values("_poly_idx")
|
|
480
480
|
.pipe(update_geometries, geom_type="polygon")
|
|
481
481
|
)
|
|
482
482
|
return (
|
|
483
|
-
clean_overlay(gdf, large, how="update")
|
|
484
|
-
# .
|
|
485
|
-
.
|
|
483
|
+
clean_overlay(gdf, large, how="update").pipe(sort_small_first)
|
|
484
|
+
# .sort_values("_poly_idx")
|
|
485
|
+
.pipe(update_geometries, geom_type="polygon")
|
|
486
486
|
)
|
|
487
487
|
|
|
488
488
|
|
|
@@ -534,7 +534,8 @@ def split_and_eliminate_by_longest(
|
|
|
534
534
|
**kwargs,
|
|
535
535
|
) -> GeoDataFrame | tuple[GeoDataFrame]:
|
|
536
536
|
if not len(to_eliminate):
|
|
537
|
-
|
|
537
|
+
gdf = (gdf,) if isinstance(gdf, GeoDataFrame) else gdf
|
|
538
|
+
return (*gdf, to_eliminate)
|
|
538
539
|
|
|
539
540
|
if not isinstance(gdf, (GeoDataFrame, GeoSeries)):
|
|
540
541
|
as_gdf = pd.concat(gdf, ignore_index=True)
|
|
@@ -596,7 +597,10 @@ def split_by_neighbors(df, split_by, tolerance, grid_size=None) -> GeoDataFrame:
|
|
|
596
597
|
|
|
597
598
|
intersecting_lines = (
|
|
598
599
|
clean_overlay(
|
|
599
|
-
to_lines(split_by)
|
|
600
|
+
to_lines(split_by.explode(ignore_index=True)[lambda x: x.length > 0]),
|
|
601
|
+
buff(df, tolerance),
|
|
602
|
+
how="identity",
|
|
603
|
+
grid_size=grid_size,
|
|
600
604
|
)
|
|
601
605
|
.pipe(get_line_segments)
|
|
602
606
|
.reset_index(drop=True)
|
sgis/geopandas_tools/general.py
CHANGED
|
@@ -594,8 +594,9 @@ def to_lines(
|
|
|
594
594
|
"""
|
|
595
595
|
gdf = (
|
|
596
596
|
pd.concat(df.assign(**{"_df_idx": i}) for i, df in enumerate(gdfs))
|
|
597
|
-
.pipe(make_all_singlepart
|
|
597
|
+
.pipe(make_all_singlepart)
|
|
598
598
|
.pipe(clean_geoms)
|
|
599
|
+
.pipe(make_all_singlepart, ignore_index=True)
|
|
599
600
|
)
|
|
600
601
|
geom_col = gdf.geometry.name
|
|
601
602
|
|
|
@@ -607,7 +608,9 @@ def to_lines(
|
|
|
607
608
|
if (geoms.geom_type == "Polygon").all():
|
|
608
609
|
geoms = polygons_to_lines(geoms, copy=copy)
|
|
609
610
|
elif (geoms.geom_type != "LineString").any():
|
|
610
|
-
raise ValueError(
|
|
611
|
+
raise ValueError(
|
|
612
|
+
f"Point geometries not allowed in 'to_lines'. {geoms.geom_type.value_counts()}"
|
|
613
|
+
)
|
|
611
614
|
|
|
612
615
|
gdf.geometry.loc[:] = geoms
|
|
613
616
|
|
sgis/io/dapla_functions.py
CHANGED
|
@@ -86,6 +86,9 @@ def read_geopandas(
|
|
|
86
86
|
"""
|
|
87
87
|
file_system = _get_file_system(file_system, kwargs)
|
|
88
88
|
|
|
89
|
+
if isinstance(gcs_path, (Path | os.PathLike)):
|
|
90
|
+
gcs_path = str(gcs_path)
|
|
91
|
+
|
|
89
92
|
if not isinstance(gcs_path, (str | Path | os.PathLike)):
|
|
90
93
|
return _read_geopandas_from_iterable(
|
|
91
94
|
gcs_path,
|
|
@@ -664,7 +667,7 @@ def _read_geopandas(
|
|
|
664
667
|
return read_func(file, **kwargs)
|
|
665
668
|
except ValueError as e:
|
|
666
669
|
if "Missing geo metadata" not in str(e) and "geometry" not in str(e):
|
|
667
|
-
raise e
|
|
670
|
+
raise e.__class__(f"{e.__class__.__name__}: {e} for {file}. ") from e
|
|
668
671
|
df = getattr(pd, f"read_{file_format}")(file, **kwargs)
|
|
669
672
|
if not len(df):
|
|
670
673
|
return GeoDataFrame(df)
|
sgis/maps/explore.py
CHANGED
|
@@ -441,11 +441,10 @@ class Explore(Map):
|
|
|
441
441
|
self.cmap_start = self.kwargs.pop("cmap_start", 0)
|
|
442
442
|
self.cmap_stop = self.kwargs.pop("cmap_stop", 256)
|
|
443
443
|
|
|
444
|
-
# if self._gdf.crs is None:
|
|
445
|
-
# self.kwargs["crs"] = "Simple"
|
|
446
|
-
|
|
447
444
|
self.original_crs = self.gdf.crs
|
|
448
445
|
|
|
446
|
+
self._to_categorical()
|
|
447
|
+
|
|
449
448
|
def __repr__(self) -> str:
|
|
450
449
|
"""Representation."""
|
|
451
450
|
return f"{self.__class__.__name__}({len(self)})"
|
sgis/maps/httpserver.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import socket
|
|
2
3
|
import webbrowser
|
|
3
4
|
from http.server import BaseHTTPRequestHandler
|
|
4
5
|
from http.server import HTTPServer
|
|
@@ -7,8 +8,19 @@ from IPython.display import HTML
|
|
|
7
8
|
from IPython.display import display
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
def find_available_port(start_port: int, max_attempts: int = 10) -> int:
|
|
12
|
+
"""Find an available port starting from `start_port`."""
|
|
13
|
+
for port in range(start_port, start_port + max_attempts):
|
|
14
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
|
15
|
+
if sock.connect_ex(("127.0.0.1", port)) != 0:
|
|
16
|
+
return port # Port is available
|
|
17
|
+
raise RuntimeError("No available ports found in range.")
|
|
18
|
+
|
|
19
|
+
|
|
10
20
|
def run_html_server(contents: str | None = None, port: int = 3000) -> None:
|
|
11
21
|
"""Run a simple, temporary http web server for serving static HTML content."""
|
|
22
|
+
port = find_available_port(port)
|
|
23
|
+
|
|
12
24
|
if "JUPYTERHUB_SERVICE_PREFIX" in os.environ:
|
|
13
25
|
# Create a link using the https://github.com/jupyterhub/jupyter-server-proxy
|
|
14
26
|
display_address = os.environ["JUPYTERHUB_SERVICE_PREFIX"] + f"proxy/{port}/"
|
sgis/maps/map.py
CHANGED
|
@@ -110,6 +110,7 @@ class Map:
|
|
|
110
110
|
nan_color="#c2c2c2",
|
|
111
111
|
scheme: str = DEFAULT_SCHEME,
|
|
112
112
|
cmap: str | None = None,
|
|
113
|
+
categorical: bool | None = None,
|
|
113
114
|
**kwargs,
|
|
114
115
|
) -> None:
|
|
115
116
|
"""Initialiser.
|
|
@@ -124,6 +125,7 @@ class Map:
|
|
|
124
125
|
scheme: Classification scheme to be used.
|
|
125
126
|
cmap (str): Colormap of the plot. See:
|
|
126
127
|
https://matplotlib.org/stable/tutorials/colors/colormaps.html
|
|
128
|
+
categorical: Set to True to convert 'column' to string values.
|
|
127
129
|
**kwargs: Arbitrary keyword arguments.
|
|
128
130
|
"""
|
|
129
131
|
gdfs, column, kwargs = self._separate_args(gdfs, column, kwargs)
|
|
@@ -198,9 +200,13 @@ class Map:
|
|
|
198
200
|
f"length as gdfs ({len(gdfs)}). Got len {len(show)}"
|
|
199
201
|
)
|
|
200
202
|
|
|
203
|
+
if categorical is not None:
|
|
204
|
+
self._is_categorical = categorical
|
|
205
|
+
|
|
201
206
|
if not self._gdfs or not any(len(gdf) for gdf in self._gdfs):
|
|
202
207
|
self._gdfs = []
|
|
203
|
-
|
|
208
|
+
if categorical is None:
|
|
209
|
+
self._is_categorical = True
|
|
204
210
|
self._unique_values = []
|
|
205
211
|
self._nan_idx = []
|
|
206
212
|
return
|
|
@@ -209,7 +215,8 @@ class Map:
|
|
|
209
215
|
self._set_labels()
|
|
210
216
|
|
|
211
217
|
self._gdfs = self._to_common_crs_and_one_geom_col(self._gdfs)
|
|
212
|
-
|
|
218
|
+
if categorical is None:
|
|
219
|
+
self._is_categorical = self._check_if_categorical()
|
|
213
220
|
|
|
214
221
|
if self._column:
|
|
215
222
|
self._fillna_if_col_is_missing()
|
|
@@ -231,6 +238,29 @@ class Map:
|
|
|
231
238
|
|
|
232
239
|
self._nan_idx = self._gdf[self._column].isna()
|
|
233
240
|
self._get_unique_values()
|
|
241
|
+
self._to_categorical()
|
|
242
|
+
|
|
243
|
+
def _to_categorical(self):
|
|
244
|
+
if not (self._is_categorical and self.column is not None):
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
def to_string_via_int(series):
|
|
248
|
+
if not pd.api.types.is_numeric_dtype(series):
|
|
249
|
+
return series.astype("string")
|
|
250
|
+
try:
|
|
251
|
+
series = series.astype(float)
|
|
252
|
+
except ValueError:
|
|
253
|
+
return series
|
|
254
|
+
no_decimals: bool = (series.dropna() % 1 == 0).all()
|
|
255
|
+
if no_decimals:
|
|
256
|
+
return series.astype("Int64").astype("string")
|
|
257
|
+
else:
|
|
258
|
+
return series.astype("string")
|
|
259
|
+
|
|
260
|
+
for i, gdf in enumerate(self._gdfs):
|
|
261
|
+
if self.column in gdf:
|
|
262
|
+
self._gdfs[i][self.column] = to_string_via_int(gdf[self.column])
|
|
263
|
+
self._gdf[self.column] = to_string_via_int(self._gdf[self.column])
|
|
234
264
|
|
|
235
265
|
def __getattr__(self, attr: str) -> Any:
|
|
236
266
|
"""Search for attribute in kwargs."""
|
sgis/parallel/parallel.py
CHANGED
sgis/raster/image_collection.py
CHANGED
|
@@ -8,6 +8,7 @@ import re
|
|
|
8
8
|
import time
|
|
9
9
|
from abc import abstractmethod
|
|
10
10
|
from collections.abc import Callable
|
|
11
|
+
from collections.abc import Generator
|
|
11
12
|
from collections.abc import Iterable
|
|
12
13
|
from collections.abc import Iterator
|
|
13
14
|
from collections.abc import Sequence
|
|
@@ -86,6 +87,14 @@ except ImportError:
|
|
|
86
87
|
raise ImportError("xarray")
|
|
87
88
|
|
|
88
89
|
|
|
90
|
+
try:
|
|
91
|
+
from gcsfs.core import GCSFile
|
|
92
|
+
except ImportError:
|
|
93
|
+
|
|
94
|
+
class GCSFile:
|
|
95
|
+
"""Placeholder."""
|
|
96
|
+
|
|
97
|
+
|
|
89
98
|
from ..geopandas_tools.bounds import get_total_bounds
|
|
90
99
|
from ..geopandas_tools.conversion import to_bbox
|
|
91
100
|
from ..geopandas_tools.conversion import to_gdf
|
|
@@ -2645,9 +2654,10 @@ class ImageCollection(_ImageBase):
|
|
|
2645
2654
|
|
|
2646
2655
|
other = to_shapely(other)
|
|
2647
2656
|
|
|
2648
|
-
|
|
2649
|
-
[
|
|
2650
|
-
|
|
2657
|
+
with ThreadPoolExecutor() as executor:
|
|
2658
|
+
bounds_iterable: Generator[Polygon] = executor.map(_union_all, self)
|
|
2659
|
+
|
|
2660
|
+
intersects_list: pd.Series = GeoSeries(list(bounds_iterable)).intersects(other)
|
|
2651
2661
|
|
|
2652
2662
|
self.images = [
|
|
2653
2663
|
image
|
|
@@ -3479,6 +3489,10 @@ def _open_raster(path: str | Path) -> rasterio.io.DatasetReader:
|
|
|
3479
3489
|
return rasterio.open(file)
|
|
3480
3490
|
|
|
3481
3491
|
|
|
3492
|
+
def _union_all(obj: _ImageBase) -> Polygon:
|
|
3493
|
+
return obj.union_all()
|
|
3494
|
+
|
|
3495
|
+
|
|
3482
3496
|
def _read_mask_array(self: Band | Image, **kwargs) -> np.ndarray:
|
|
3483
3497
|
mask_band_id = self.masking["band_id"]
|
|
3484
3498
|
mask_paths = [path for path in self._all_file_paths if mask_band_id in path]
|
|
@@ -6,10 +6,10 @@ sgis/geopandas_tools/__init__.py,sha256=bo8lFMcltOz7TtWAi52_ekR2gd3mjfBfKeMDV5zu
|
|
|
6
6
|
sgis/geopandas_tools/bounds.py,sha256=YJyF0gp78hFAjLLZmDquRKCBAtbt7QouG3snTcJeNQs,23822
|
|
7
7
|
sgis/geopandas_tools/buffer_dissolve_explode.py,sha256=t9GJqRMDsHEU74RIlqeMr4QBgbTK0hYlXL4af1RKIks,19955
|
|
8
8
|
sgis/geopandas_tools/centerlines.py,sha256=Q65Sx01SeAlulBEd9oaZkB2maBBNdLcJwAbTILg4SPU,11848
|
|
9
|
-
sgis/geopandas_tools/cleaning.py,sha256=
|
|
9
|
+
sgis/geopandas_tools/cleaning.py,sha256=0j7_bfuAjWVBUImbPTXuwNdYRJ_By6HAwaOdw5Dh4vc,24315
|
|
10
10
|
sgis/geopandas_tools/conversion.py,sha256=o3QJZLfaqqpJNdWWNKfQn_dS77uJxxRxWZxhf18vPXs,25505
|
|
11
|
-
sgis/geopandas_tools/duplicates.py,sha256=
|
|
12
|
-
sgis/geopandas_tools/general.py,sha256=
|
|
11
|
+
sgis/geopandas_tools/duplicates.py,sha256=MTduclsUZlYifFsc7g9KOJyh6P4EkixZlcZmFH-bgYo,14926
|
|
12
|
+
sgis/geopandas_tools/general.py,sha256=UPtmgEMhTZw-qMiCCjeTtyBlJWoVE96SSanufPK8MLs,39976
|
|
13
13
|
sgis/geopandas_tools/geocoding.py,sha256=n47aFQMm4yX1MsPnTM4dFjwegCA1ZmGUDj1uyu7OJV4,691
|
|
14
14
|
sgis/geopandas_tools/geometry_types.py,sha256=ijQDbQaZPqPGjBl707H4yooNXpk21RXyatI7itnvqLk,7603
|
|
15
15
|
sgis/geopandas_tools/neighbors.py,sha256=vduQlHeoZjHyD5pxDbjfonQ3-LAHGfPETxV7-L6Sg4M,16634
|
|
@@ -21,15 +21,15 @@ sgis/geopandas_tools/sfilter.py,sha256=SLcMYprQwnY5DNo0R7TGXk4m6u26H8o4PRn-RPhme
|
|
|
21
21
|
sgis/helpers.py,sha256=_h7ke9hJrRNhHW-ZX3gA95fOrX2s1ADKBMxc94p2F4Q,9627
|
|
22
22
|
sgis/io/__init__.py,sha256=uyBr20YDqB2bQttrd5q1JuGOvX32A-MSvS7Wmw5f5qg,177
|
|
23
23
|
sgis/io/_is_dapla.py,sha256=wmfkSe98IrLhUg3dtXZusV6OVC8VlY1kbc5EQDf3P-Q,358
|
|
24
|
-
sgis/io/dapla_functions.py,sha256=
|
|
24
|
+
sgis/io/dapla_functions.py,sha256=bhdOw12qIZqKYn8TXPaDcvEOGZYhwv8VE62ESZmv7bM,29998
|
|
25
25
|
sgis/io/opener.py,sha256=HWO3G1NB6bpXKM94JadCD513vjat1o1TFjWGWzyVasg,898
|
|
26
26
|
sgis/io/read_parquet.py,sha256=FvZYv1rLkUlrSaUY6QW6E1yntmntTeQuZ9ZRgCDO4IM,3776
|
|
27
27
|
sgis/maps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
sgis/maps/examine.py,sha256=Pb0dH8JazU5E2svfQrzHO1Bi-sjy5SeyY6zoeMO34jE,9369
|
|
29
|
-
sgis/maps/explore.py,sha256=
|
|
30
|
-
sgis/maps/httpserver.py,sha256=
|
|
29
|
+
sgis/maps/explore.py,sha256=Vdt1-vFKWkJxL-odh3rn2YlKpWw6Ew0bu8U3KURThNc,47797
|
|
30
|
+
sgis/maps/httpserver.py,sha256=eCDoB9x74kSLiGEj2X3O91t3oscY_ia17UNuaaJ6tCc,2472
|
|
31
31
|
sgis/maps/legend.py,sha256=lVRVCkhPmJRjGK23obFJZAO3qp6du1LYnobkkN7DPkc,26279
|
|
32
|
-
sgis/maps/map.py,sha256=
|
|
32
|
+
sgis/maps/map.py,sha256=S2SrOCbVesS8Y5KlziGCmCi85_LIumL8CH8z4MdOEXc,30744
|
|
33
33
|
sgis/maps/maps.py,sha256=gxu0rgcVygjudRtM1dVRmsUMilMUIg3vG-UgvASM91E,23072
|
|
34
34
|
sgis/maps/norge_i_bilder.json,sha256=W_mFfte3DxugWbEudZ5fadZ2JeFYb0hyab2Quf4oJME,481311
|
|
35
35
|
sgis/maps/thematicmap.py,sha256=w6q4_gIr8BubQgsPJkc6WXk-tmplDLGcKyjphhFp7ng,21873
|
|
@@ -50,16 +50,16 @@ sgis/networkanalysis/networkanalysisrules.py,sha256=9sXigaCzvKhXFwpeVNMtOiIK3_Hz
|
|
|
50
50
|
sgis/networkanalysis/nodes.py,sha256=atFSpqz-_uJHMrf6MC0zhrrcWIydRMFZrsaHC2xr1GU,3374
|
|
51
51
|
sgis/networkanalysis/traveling_salesman.py,sha256=Jjo6bHY4KJ-eK0LycyTy0sWxZjgITs5MBllZ_G9FhTE,5655
|
|
52
52
|
sgis/parallel/__init__.py,sha256=fw_Fl3IJk1bKzrRBhZIoOpznJqwd09NVHJJFj2ZLeIU,32
|
|
53
|
-
sgis/parallel/parallel.py,sha256=
|
|
53
|
+
sgis/parallel/parallel.py,sha256=CzHetSAr9wvSrEDFTqDq2xAsNuG1ig22-vcEOIoUVv4,39676
|
|
54
54
|
sgis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
55
|
sgis/raster/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
56
|
sgis/raster/base.py,sha256=tiZEuMcVK6hOm_aIjWhQ1WGshcjsxT1fFkuBSLFiMC0,7785
|
|
57
|
-
sgis/raster/image_collection.py,sha256=
|
|
57
|
+
sgis/raster/image_collection.py,sha256=FfsBgLtne9_pcCm6FynrMx90NpHLulcshj5ALT08zOA,122888
|
|
58
58
|
sgis/raster/indices.py,sha256=-J1HYmnT240iozvgagvyis6K0_GHZHRuUrPOgyoeIrY,223
|
|
59
59
|
sgis/raster/regex.py,sha256=kYhVpRYzoXutx1dSYmqMoselWXww7MMEsTPmLZwHjbM,3759
|
|
60
60
|
sgis/raster/sentinel_config.py,sha256=nySDqn2R8M6W8jguoBeSAK_zzbAsqmaI59i32446FwY,1268
|
|
61
61
|
sgis/raster/zonal.py,sha256=D4Gyptw-yOLTCO41peIuYbY-DANsJCG19xXDlf1QAz4,2299
|
|
62
|
-
ssb_sgis-1.1.
|
|
63
|
-
ssb_sgis-1.1.
|
|
64
|
-
ssb_sgis-1.1.
|
|
65
|
-
ssb_sgis-1.1.
|
|
62
|
+
ssb_sgis-1.1.6.dist-info/LICENSE,sha256=np3IfD5m0ZUofn_kVzDZqliozuiO6wrktw3LRPjyEiI,1073
|
|
63
|
+
ssb_sgis-1.1.6.dist-info/METADATA,sha256=hKTyyKXLiExr5vbMEoiz4F2BHEz-ktdKu58Eu1Ck8kg,11740
|
|
64
|
+
ssb_sgis-1.1.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
65
|
+
ssb_sgis-1.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|