ssb-sgis 1.0.2__py3-none-any.whl → 1.0.4__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/__init__.py +20 -9
- sgis/debug_config.py +24 -0
- sgis/exceptions.py +2 -2
- sgis/geopandas_tools/bounds.py +33 -36
- sgis/geopandas_tools/buffer_dissolve_explode.py +136 -35
- sgis/geopandas_tools/centerlines.py +4 -91
- sgis/geopandas_tools/cleaning.py +1576 -583
- sgis/geopandas_tools/conversion.py +38 -19
- sgis/geopandas_tools/duplicates.py +29 -8
- sgis/geopandas_tools/general.py +263 -100
- sgis/geopandas_tools/geometry_types.py +4 -4
- sgis/geopandas_tools/neighbors.py +19 -15
- sgis/geopandas_tools/overlay.py +2 -2
- sgis/geopandas_tools/point_operations.py +5 -5
- sgis/geopandas_tools/polygon_operations.py +510 -105
- sgis/geopandas_tools/polygons_as_rings.py +40 -8
- sgis/geopandas_tools/sfilter.py +29 -12
- sgis/helpers.py +3 -3
- sgis/io/dapla_functions.py +238 -19
- sgis/io/read_parquet.py +1 -1
- sgis/maps/examine.py +27 -12
- sgis/maps/explore.py +450 -65
- sgis/maps/legend.py +177 -76
- sgis/maps/map.py +206 -103
- sgis/maps/maps.py +178 -105
- sgis/maps/thematicmap.py +243 -83
- sgis/networkanalysis/_service_area.py +6 -1
- sgis/networkanalysis/closing_network_holes.py +2 -2
- sgis/networkanalysis/cutting_lines.py +15 -8
- sgis/networkanalysis/directednetwork.py +1 -1
- sgis/networkanalysis/finding_isolated_networks.py +15 -8
- sgis/networkanalysis/networkanalysis.py +17 -19
- sgis/networkanalysis/networkanalysisrules.py +1 -1
- sgis/networkanalysis/traveling_salesman.py +1 -1
- sgis/parallel/parallel.py +64 -27
- sgis/raster/__init__.py +0 -6
- sgis/raster/base.py +208 -0
- sgis/raster/cube.py +54 -8
- sgis/raster/image_collection.py +3257 -0
- sgis/raster/indices.py +17 -5
- sgis/raster/raster.py +138 -243
- sgis/raster/sentinel_config.py +120 -0
- sgis/raster/zonal.py +0 -1
- {ssb_sgis-1.0.2.dist-info → ssb_sgis-1.0.4.dist-info}/METADATA +6 -7
- ssb_sgis-1.0.4.dist-info/RECORD +62 -0
- sgis/raster/methods_as_functions.py +0 -0
- sgis/raster/torchgeo.py +0 -171
- ssb_sgis-1.0.2.dist-info/RECORD +0 -61
- {ssb_sgis-1.0.2.dist-info → ssb_sgis-1.0.4.dist-info}/LICENSE +0 -0
- {ssb_sgis-1.0.2.dist-info → ssb_sgis-1.0.4.dist-info}/WHEEL +0 -0
|
@@ -2,9 +2,7 @@ import functools
|
|
|
2
2
|
import itertools
|
|
3
3
|
import warnings
|
|
4
4
|
|
|
5
|
-
import numpy as np
|
|
6
5
|
import pandas as pd
|
|
7
|
-
import shapely
|
|
8
6
|
from geopandas import GeoDataFrame
|
|
9
7
|
from geopandas import GeoSeries
|
|
10
8
|
from numpy.typing import NDArray
|
|
@@ -16,17 +14,17 @@ from shapely import line_merge
|
|
|
16
14
|
from shapely import make_valid
|
|
17
15
|
from shapely import segmentize
|
|
18
16
|
from shapely import unary_union
|
|
17
|
+
from shapely import union_all
|
|
19
18
|
from shapely import voronoi_polygons
|
|
20
19
|
from shapely.errors import GEOSException
|
|
21
20
|
from shapely.geometry import LineString
|
|
22
21
|
from shapely.ops import nearest_points
|
|
23
22
|
|
|
24
|
-
from ..maps.maps import explore
|
|
25
23
|
from ..networkanalysis.traveling_salesman import traveling_salesman_problem
|
|
26
|
-
from .conversion import to_gdf
|
|
27
24
|
from .conversion import to_geoseries
|
|
28
25
|
from .general import clean_geoms
|
|
29
26
|
from .general import make_lines_between_points
|
|
27
|
+
from .general import multipoints_to_line_segments
|
|
30
28
|
from .general import sort_long_first
|
|
31
29
|
from .geometry_types import make_all_singlepart
|
|
32
30
|
from .sfilter import sfilter_inverse
|
|
@@ -64,7 +62,7 @@ def _remove_longest_if_not_intersecting(
|
|
|
64
62
|
|
|
65
63
|
nearest = longest_endpoints.groupby(level=0).apply(
|
|
66
64
|
lambda x: nearest_points(
|
|
67
|
-
x, not_longest[not_longest.index.isin(x.index)].
|
|
65
|
+
x, union_all(not_longest[not_longest.index.isin(x.index)].geometry.values)
|
|
68
66
|
)[1]
|
|
69
67
|
)
|
|
70
68
|
longest_endpoints.loc[:] = make_lines_between_points(
|
|
@@ -186,8 +184,6 @@ def get_rough_centerlines(
|
|
|
186
184
|
]
|
|
187
185
|
)
|
|
188
186
|
|
|
189
|
-
explore(points=to_gdf(points, 25833), gdf=gdf)
|
|
190
|
-
|
|
191
187
|
remove_longest = functools.partial(_remove_longest_if_not_intersecting, geoms=geoms)
|
|
192
188
|
|
|
193
189
|
centerlines = GeoSeries(
|
|
@@ -336,7 +332,7 @@ def _get_approximate_polygon_endpoints(geoms: GeoSeries) -> GeoSeries:
|
|
|
336
332
|
|
|
337
333
|
out_geoms.append(nearest_geom_points)
|
|
338
334
|
|
|
339
|
-
lines_around_geometries =
|
|
335
|
+
lines_around_geometries = multipoints_to_line_segments(
|
|
340
336
|
extract_unique_points(rectangles)
|
|
341
337
|
)
|
|
342
338
|
|
|
@@ -372,86 +368,3 @@ def _get_approximate_polygon_endpoints(geoms: GeoSeries) -> GeoSeries:
|
|
|
372
368
|
out_geoms.append(points_moved)
|
|
373
369
|
|
|
374
370
|
return pd.concat(out_geoms)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
def _multipoints_to_line_segments(
|
|
378
|
-
multipoints: GeoSeries | GeoDataFrame, to_next: bool = True, cycle: bool = True
|
|
379
|
-
) -> GeoSeries | GeoDataFrame:
|
|
380
|
-
if not len(multipoints):
|
|
381
|
-
return multipoints
|
|
382
|
-
|
|
383
|
-
multipoints = to_geoseries(multipoints)
|
|
384
|
-
|
|
385
|
-
if isinstance(multipoints.index, pd.MultiIndex):
|
|
386
|
-
index = [
|
|
387
|
-
multipoints.index.get_level_values(i)
|
|
388
|
-
for i in range(multipoints.index.nlevels)
|
|
389
|
-
]
|
|
390
|
-
multipoints.index = pd.MultiIndex.from_arrays(
|
|
391
|
-
[list(range(len(multipoints))), *index],
|
|
392
|
-
names=["range_idx", *multipoints.index.names],
|
|
393
|
-
)
|
|
394
|
-
else:
|
|
395
|
-
multipoints.index = pd.MultiIndex.from_arrays(
|
|
396
|
-
[np.arange(0, len(multipoints)), multipoints.index],
|
|
397
|
-
names=["range_idx", multipoints.index.name],
|
|
398
|
-
)
|
|
399
|
-
|
|
400
|
-
try:
|
|
401
|
-
crs = multipoints.crs
|
|
402
|
-
except AttributeError:
|
|
403
|
-
crs = None
|
|
404
|
-
|
|
405
|
-
point_df = multipoints.explode(index_parts=False).to_frame("geometry")
|
|
406
|
-
|
|
407
|
-
if to_next:
|
|
408
|
-
shift = -1
|
|
409
|
-
keep = "first"
|
|
410
|
-
else:
|
|
411
|
-
shift = 1
|
|
412
|
-
keep = "last"
|
|
413
|
-
|
|
414
|
-
point_df["next"] = point_df.groupby(level=0)["geometry"].shift(shift)
|
|
415
|
-
|
|
416
|
-
if cycle:
|
|
417
|
-
first_points: GeoSeries = point_df.loc[
|
|
418
|
-
lambda x: ~x.index.get_level_values(0).duplicated(keep=keep), "geometry"
|
|
419
|
-
]
|
|
420
|
-
is_last_point = point_df["next"].isna()
|
|
421
|
-
|
|
422
|
-
point_df.loc[is_last_point, "next"] = first_points
|
|
423
|
-
assert point_df["next"].notna().all()
|
|
424
|
-
else:
|
|
425
|
-
point_df = point_df[point_df["next"].notna()]
|
|
426
|
-
|
|
427
|
-
point_df["geometry"] = [
|
|
428
|
-
LineString([x1, x2])
|
|
429
|
-
for x1, x2 in zip(point_df["geometry"], point_df["next"], strict=False)
|
|
430
|
-
]
|
|
431
|
-
if isinstance(multipoints.index, pd.MultiIndex):
|
|
432
|
-
point_df.index = point_df.index.droplevel(0)
|
|
433
|
-
|
|
434
|
-
if isinstance(multipoints, GeoDataFrame):
|
|
435
|
-
return GeoDataFrame(
|
|
436
|
-
point_df.drop(columns=["next"]), geometry="geometry", crs=crs
|
|
437
|
-
)
|
|
438
|
-
return GeoSeries(point_df["geometry"], crs=crs)
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
def get_line_segments(
|
|
442
|
-
lines: GeoDataFrame | GeoSeries, extract_unique: bool = False, cycle=False
|
|
443
|
-
) -> GeoDataFrame:
|
|
444
|
-
try:
|
|
445
|
-
assert lines.index.is_unique
|
|
446
|
-
except AttributeError:
|
|
447
|
-
pass
|
|
448
|
-
|
|
449
|
-
lines = to_geoseries(lines)
|
|
450
|
-
|
|
451
|
-
if extract_unique:
|
|
452
|
-
points = extract_unique_points(lines.values)
|
|
453
|
-
else:
|
|
454
|
-
coords, indices = shapely.get_coordinates(lines, return_index=True)
|
|
455
|
-
points = GeoSeries(shapely.points(coords), index=indices)
|
|
456
|
-
|
|
457
|
-
return _multipoints_to_line_segments(points, cycle=cycle)
|