ssb-sgis 1.0.14__tar.gz → 1.1.0__tar.gz
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.
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/PKG-INFO +1 -1
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/pyproject.toml +1 -1
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/__init__.py +1 -1
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/bounds.py +1 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/buffer_dissolve_explode.py +9 -9
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/io/dapla_functions.py +10 -10
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/explore.py +11 -15
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/maps.py +12 -18
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/thematicmap.py +9 -2
- ssb_sgis-1.0.14/src/sgis/maps/norge_i_bilder_wms.py → ssb_sgis-1.1.0/src/sgis/maps/wms.py +23 -1
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/parallel/parallel.py +5 -5
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/LICENSE +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/README.md +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/debug_config.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/exceptions.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/__init__.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/centerlines.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/cleaning.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/conversion.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/duplicates.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/general.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/geocoding.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/geometry_types.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/neighbors.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/overlay.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/point_operations.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/polygon_operations.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/polygons_as_rings.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/geopandas_tools/sfilter.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/helpers.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/io/_is_dapla.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/io/opener.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/io/read_parquet.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/__init__.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/examine.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/httpserver.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/legend.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/map.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/norge_i_bilder.json +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/maps/tilesources.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/__init__.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/_get_route.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/_od_cost_matrix.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/_points.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/_service_area.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/closing_network_holes.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/cutting_lines.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/directednetwork.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/finding_isolated_networks.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/network.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/networkanalysis.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/networkanalysisrules.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/nodes.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/networkanalysis/traveling_salesman.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/py.typed +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/__init__.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/base.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/image_collection.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/indices.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/regex.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/sentinel_config.py +0 -0
- {ssb_sgis-1.0.14 → ssb_sgis-1.1.0}/src/sgis/raster/zonal.py +0 -0
|
@@ -96,10 +96,10 @@ from .maps.maps import explore
|
|
|
96
96
|
from .maps.maps import explore_locals
|
|
97
97
|
from .maps.maps import qtm
|
|
98
98
|
from .maps.maps import samplemap
|
|
99
|
-
from .maps.norge_i_bilder_wms import NorgeIBilderWms
|
|
100
99
|
from .maps.thematicmap import ThematicMap
|
|
101
100
|
from .maps.tilesources import kartverket as kartverket_tiles
|
|
102
101
|
from .maps.tilesources import xyz as xyztiles
|
|
102
|
+
from .maps.wms import NorgeIBilderWms
|
|
103
103
|
from .networkanalysis.closing_network_holes import close_network_holes
|
|
104
104
|
from .networkanalysis.closing_network_holes import close_network_holes_to_deadends
|
|
105
105
|
from .networkanalysis.closing_network_holes import get_k_nearest_points_for_deadends
|
|
@@ -669,6 +669,7 @@ def bounds_to_points(
|
|
|
669
669
|
0 MULTIPOINT (1.00000 0.00000, 1.00000 1.00000, ...
|
|
670
670
|
1 MULTIPOINT (0.00000 0.00000)
|
|
671
671
|
"""
|
|
672
|
+
gdf = gdf.copy() if copy else gdf
|
|
672
673
|
as_bounds = bounds_to_polygon(gdf, copy=copy)
|
|
673
674
|
if isinstance(gdf, GeoSeries):
|
|
674
675
|
return GeoSeries(extract_unique_points(as_bounds), index=gdf.index)
|
|
@@ -5,7 +5,7 @@ for the following:
|
|
|
5
5
|
|
|
6
6
|
- Geometries are made valid after buffer and dissolve.
|
|
7
7
|
|
|
8
|
-
- The buffer resolution defaults to
|
|
8
|
+
- The buffer resolution defaults to 30 (geopandas' default is 16).
|
|
9
9
|
|
|
10
10
|
- If 'by' is not specified, the index will be labeled 0, 1, …, n - 1 after exploded, instead of 0, 0, …, 0 as it will with the geopandas defaults.
|
|
11
11
|
|
|
@@ -49,7 +49,7 @@ def buffdissexp(
|
|
|
49
49
|
gdf: GeoDataFrame,
|
|
50
50
|
distance: int | float,
|
|
51
51
|
*,
|
|
52
|
-
resolution: int =
|
|
52
|
+
resolution: int = 30,
|
|
53
53
|
index_parts: bool = False,
|
|
54
54
|
copy: bool = True,
|
|
55
55
|
grid_size: float | int | None = None,
|
|
@@ -68,7 +68,7 @@ def buffdissexp(
|
|
|
68
68
|
distance: the distance (meters, degrees, depending on the crs) to buffer
|
|
69
69
|
the geometry by
|
|
70
70
|
resolution: The number of segments used to approximate a quarter circle.
|
|
71
|
-
Here defaults to
|
|
71
|
+
Here defaults to 30, as opposed to the default 16 in geopandas.
|
|
72
72
|
index_parts: If False (default), the index after dissolve is respected. If
|
|
73
73
|
True, an integer index level is added during explode.
|
|
74
74
|
copy: Whether to copy the GeoDataFrame before buffering. Defaults to True.
|
|
@@ -101,7 +101,7 @@ def buffdissexp(
|
|
|
101
101
|
def buffdiss(
|
|
102
102
|
gdf: GeoDataFrame,
|
|
103
103
|
distance: int | float,
|
|
104
|
-
resolution: int =
|
|
104
|
+
resolution: int = 30,
|
|
105
105
|
copy: bool = True,
|
|
106
106
|
n_jobs: int = 1,
|
|
107
107
|
join_style: int | str = "round",
|
|
@@ -119,7 +119,7 @@ def buffdiss(
|
|
|
119
119
|
distance: the distance (meters, degrees, depending on the crs) to buffer
|
|
120
120
|
the geometry by
|
|
121
121
|
resolution: The number of segments used to approximate a quarter circle.
|
|
122
|
-
Here defaults to
|
|
122
|
+
Here defaults to 30, as opposed to the default 16 in geopandas.
|
|
123
123
|
join_style: Buffer join style.
|
|
124
124
|
copy: Whether to copy the GeoDataFrame before buffering. Defaults to True.
|
|
125
125
|
n_jobs: Number of threads to use. Defaults to 1.
|
|
@@ -511,7 +511,7 @@ def buffdissexp_by_cluster(
|
|
|
511
511
|
gdf: GeoDataFrame,
|
|
512
512
|
distance: int | float,
|
|
513
513
|
*,
|
|
514
|
-
resolution: int =
|
|
514
|
+
resolution: int = 30,
|
|
515
515
|
copy: bool = True,
|
|
516
516
|
n_jobs: int = 1,
|
|
517
517
|
join_style: int | str = "round",
|
|
@@ -532,7 +532,7 @@ def buffdissexp_by_cluster(
|
|
|
532
532
|
distance: the distance (meters, degrees, depending on the crs) to buffer
|
|
533
533
|
the geometry by
|
|
534
534
|
resolution: The number of segments used to approximate a quarter circle.
|
|
535
|
-
Here defaults to
|
|
535
|
+
Here defaults to 30, as opposed to the default 16 in geopandas.
|
|
536
536
|
join_style: Buffer join style.
|
|
537
537
|
copy: Whether to copy the GeoDataFrame before buffering. Defaults to True.
|
|
538
538
|
n_jobs: int = 1,
|
|
@@ -554,7 +554,7 @@ def buffdissexp_by_cluster(
|
|
|
554
554
|
def buff(
|
|
555
555
|
gdf: GeoDataFrame | GeoSeries,
|
|
556
556
|
distance: int | float,
|
|
557
|
-
resolution: int =
|
|
557
|
+
resolution: int = 30,
|
|
558
558
|
copy: bool = True,
|
|
559
559
|
join_style: int | str = "round",
|
|
560
560
|
**buffer_kwargs,
|
|
@@ -566,7 +566,7 @@ def buff(
|
|
|
566
566
|
distance: the distance (meters, degrees, depending on the crs) to buffer
|
|
567
567
|
the geometry by
|
|
568
568
|
resolution: The number of segments used to approximate a quarter circle.
|
|
569
|
-
Here defaults to
|
|
569
|
+
Here defaults to 30, as opposed to the default 16 in geopandas.
|
|
570
570
|
join_style: Buffer join style.
|
|
571
571
|
copy: Whether to copy the GeoDataFrame before buffering. Defaults to True.
|
|
572
572
|
**buffer_kwargs: additional keyword arguments passed to geopandas' buffer.
|
|
@@ -15,6 +15,7 @@ import pandas as pd
|
|
|
15
15
|
import pyarrow
|
|
16
16
|
import pyarrow.parquet as pq
|
|
17
17
|
import shapely
|
|
18
|
+
from gcsfs import GCSFileSystem
|
|
18
19
|
from geopandas import GeoDataFrame
|
|
19
20
|
from geopandas import GeoSeries
|
|
20
21
|
from geopandas.io.arrow import _geopandas_to_arrow
|
|
@@ -30,7 +31,7 @@ PANDAS_FALLBACK_INFO = " Set pandas_fallback=True to ignore this error."
|
|
|
30
31
|
def read_geopandas(
|
|
31
32
|
gcs_path: str | Path | list[str | Path] | tuple[str | Path] | GeoSeries,
|
|
32
33
|
pandas_fallback: bool = False,
|
|
33
|
-
file_system:
|
|
34
|
+
file_system: GCSFileSystem | None = None,
|
|
34
35
|
mask: GeoSeries | GeoDataFrame | shapely.Geometry | tuple | None = None,
|
|
35
36
|
threads: int | None = None,
|
|
36
37
|
**kwargs,
|
|
@@ -138,8 +139,7 @@ def read_geopandas(
|
|
|
138
139
|
raise e.__class__(
|
|
139
140
|
f"{e.__class__.__name__}: {e} for {gcs_path}."
|
|
140
141
|
) from e
|
|
141
|
-
df =
|
|
142
|
-
|
|
142
|
+
df = pd.read_parquet(file, **kwargs)
|
|
143
143
|
if pandas_fallback or not len(df):
|
|
144
144
|
return df
|
|
145
145
|
else:
|
|
@@ -157,7 +157,7 @@ def read_geopandas(
|
|
|
157
157
|
except ValueError as e:
|
|
158
158
|
if "Missing geo metadata" not in str(e) and "geometry" not in str(e):
|
|
159
159
|
raise e
|
|
160
|
-
df =
|
|
160
|
+
df = pd.read_parquet(file, **kwargs)
|
|
161
161
|
|
|
162
162
|
if pandas_fallback or not len(df):
|
|
163
163
|
return df
|
|
@@ -168,7 +168,7 @@ def read_geopandas(
|
|
|
168
168
|
) from e
|
|
169
169
|
except Exception as e:
|
|
170
170
|
raise e.__class__(
|
|
171
|
-
f"{e.__class__.__name__}: {e} for {
|
|
171
|
+
f"{e.__class__.__name__}: {e} for {gcs_path}." + more_txt
|
|
172
172
|
) from e
|
|
173
173
|
|
|
174
174
|
if mask is not None:
|
|
@@ -177,7 +177,7 @@ def read_geopandas(
|
|
|
177
177
|
|
|
178
178
|
|
|
179
179
|
def _get_bounds_parquet(
|
|
180
|
-
path: str | Path, file_system:
|
|
180
|
+
path: str | Path, file_system: GCSFileSystem, pandas_fallback: bool = False
|
|
181
181
|
) -> tuple[list[float], dict] | tuple[None, None]:
|
|
182
182
|
with file_system.open(path) as f:
|
|
183
183
|
try:
|
|
@@ -202,7 +202,7 @@ def _get_bounds_parquet(
|
|
|
202
202
|
return meta["bbox"], meta["crs"]
|
|
203
203
|
|
|
204
204
|
|
|
205
|
-
def _get_columns(path: str | Path, file_system:
|
|
205
|
+
def _get_columns(path: str | Path, file_system: GCSFileSystem) -> pd.Index:
|
|
206
206
|
with file_system.open(path) as f:
|
|
207
207
|
schema = pq.read_schema(f)
|
|
208
208
|
index_cols = _get_index_cols(schema)
|
|
@@ -216,7 +216,7 @@ def _get_index_cols(schema: pyarrow.Schema) -> list[str]:
|
|
|
216
216
|
|
|
217
217
|
def get_bounds_series(
|
|
218
218
|
paths: list[str | Path] | tuple[str | Path],
|
|
219
|
-
file_system:
|
|
219
|
+
file_system: GCSFileSystem | None = None,
|
|
220
220
|
threads: int | None = None,
|
|
221
221
|
pandas_fallback: bool = False,
|
|
222
222
|
) -> GeoSeries:
|
|
@@ -227,7 +227,7 @@ def get_bounds_series(
|
|
|
227
227
|
|
|
228
228
|
Args:
|
|
229
229
|
paths: Iterable of file paths in gcs.
|
|
230
|
-
file_system: Optional instance of
|
|
230
|
+
file_system: Optional instance of GCSFileSystem.
|
|
231
231
|
If None, an instance is created within the function.
|
|
232
232
|
Note that this is slower in long loops.
|
|
233
233
|
threads: Number of threads to use if reading multiple files. Defaults to
|
|
@@ -307,7 +307,7 @@ def write_geopandas(
|
|
|
307
307
|
gcs_path: str | Path,
|
|
308
308
|
overwrite: bool = True,
|
|
309
309
|
pandas_fallback: bool = False,
|
|
310
|
-
file_system:
|
|
310
|
+
file_system: GCSFileSystem | None = None,
|
|
311
311
|
write_covering_bbox: bool = False,
|
|
312
312
|
**kwargs,
|
|
313
313
|
) -> None:
|
|
@@ -44,7 +44,7 @@ from ..geopandas_tools.general import clean_geoms
|
|
|
44
44
|
from ..geopandas_tools.general import make_all_singlepart
|
|
45
45
|
from ..geopandas_tools.geometry_types import get_geom_type
|
|
46
46
|
from ..geopandas_tools.geometry_types import to_single_geom_type
|
|
47
|
-
from .
|
|
47
|
+
from .wms import WmsLoader
|
|
48
48
|
|
|
49
49
|
try:
|
|
50
50
|
from ..raster.image_collection import Band
|
|
@@ -280,7 +280,7 @@ class Explore(Map):
|
|
|
280
280
|
max_images: int = 10,
|
|
281
281
|
max_nodata_percentage: int = 100,
|
|
282
282
|
display: bool = True,
|
|
283
|
-
|
|
283
|
+
wms: WmsLoader | None = None,
|
|
284
284
|
**kwargs,
|
|
285
285
|
) -> None:
|
|
286
286
|
"""Initialiser.
|
|
@@ -310,9 +310,7 @@ class Explore(Map):
|
|
|
310
310
|
max_nodata_percentage: Maximum percentage nodata values (e.g. clouds) ro allow in
|
|
311
311
|
image arrays.
|
|
312
312
|
display: Whether to display the map interactively.
|
|
313
|
-
|
|
314
|
-
into the map. Can optionally be set to an instance of NorgeIBilderWms to filter
|
|
315
|
-
years and names.
|
|
313
|
+
wms: A WmsLoader instance for loading image tiles as layers. E.g. NorgeIBilderWms.
|
|
316
314
|
**kwargs: Additional keyword arguments. Can also be geometry-like objects
|
|
317
315
|
where the key is the label.
|
|
318
316
|
"""
|
|
@@ -329,7 +327,7 @@ class Explore(Map):
|
|
|
329
327
|
self.max_images = max_images
|
|
330
328
|
self.max_nodata_percentage = max_nodata_percentage
|
|
331
329
|
self.display = display
|
|
332
|
-
self.
|
|
330
|
+
self.wms = [wms] if isinstance(wms, WmsLoader) else wms
|
|
333
331
|
self.legend = None
|
|
334
332
|
|
|
335
333
|
self.browser = browser
|
|
@@ -768,13 +766,11 @@ class Explore(Map):
|
|
|
768
766
|
for tile in tiles:
|
|
769
767
|
to_tile(tile, max_zoom=self.max_zoom).add_to(mapobj)
|
|
770
768
|
|
|
771
|
-
def
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
for tile in tiles.values():
|
|
777
|
-
map_.add_child(tile)
|
|
769
|
+
def _add_wms(self, map_: folium.Map, bbox: Any) -> None:
|
|
770
|
+
for wms in self.wms:
|
|
771
|
+
tiles = wms.get_tiles(bbox, max_zoom=self.max_zoom)
|
|
772
|
+
for tile in tiles.values():
|
|
773
|
+
map_.add_child(tile)
|
|
778
774
|
|
|
779
775
|
def _create_continous_map(self):
|
|
780
776
|
self._prepare_continous_map()
|
|
@@ -982,8 +978,8 @@ class Explore(Map):
|
|
|
982
978
|
m.get_root().add_child(style)
|
|
983
979
|
# folium.LayerControl(collapsed=False).add_to(m)
|
|
984
980
|
|
|
985
|
-
if self.
|
|
986
|
-
self.
|
|
981
|
+
if self.wms:
|
|
982
|
+
self._add_wms(m, bounds)
|
|
987
983
|
|
|
988
984
|
return m
|
|
989
985
|
|
|
@@ -31,8 +31,8 @@ from ..geopandas_tools.geocoding import address_to_gdf
|
|
|
31
31
|
from ..geopandas_tools.geometry_types import get_geom_type
|
|
32
32
|
from .explore import Explore
|
|
33
33
|
from .map import Map
|
|
34
|
-
from .norge_i_bilder_wms import NorgeIBilderWms
|
|
35
34
|
from .thematicmap import ThematicMap
|
|
35
|
+
from .wms import WmsLoader
|
|
36
36
|
|
|
37
37
|
try:
|
|
38
38
|
from torchgeo.datasets.geo import RasterDataset
|
|
@@ -91,7 +91,7 @@ def explore(
|
|
|
91
91
|
size: int | None = None,
|
|
92
92
|
max_images: int = 10,
|
|
93
93
|
max_nodata_percentage: int = 100,
|
|
94
|
-
|
|
94
|
+
wms: WmsLoader | None = None,
|
|
95
95
|
**kwargs,
|
|
96
96
|
) -> Explore:
|
|
97
97
|
"""Interactive map of GeoDataFrames with layers that can be toggled on/off.
|
|
@@ -123,9 +123,7 @@ def explore(
|
|
|
123
123
|
map. Defaults to 10.
|
|
124
124
|
max_nodata_percentage: Maximum percentage nodata values (e.g. clouds) ro allow in
|
|
125
125
|
image arrays.
|
|
126
|
-
|
|
127
|
-
into the map. Can optionally be set to an instance of NorgeIBilderWms to filter
|
|
128
|
-
years and names.
|
|
126
|
+
wms: A WmsLoader instance for loading image tiles as layers. E.g. NorgeIBilderWms.
|
|
129
127
|
**kwargs: Keyword arguments to pass to geopandas.GeoDataFrame.explore, for
|
|
130
128
|
instance 'cmap' to change the colors, 'scheme' to change how the data
|
|
131
129
|
is grouped. This defaults to 'fisherjenkssampled' for numeric data.
|
|
@@ -175,7 +173,7 @@ def explore(
|
|
|
175
173
|
max_zoom=max_zoom,
|
|
176
174
|
max_images=max_images,
|
|
177
175
|
max_nodata_percentage=max_nodata_percentage,
|
|
178
|
-
|
|
176
|
+
wms=wms,
|
|
179
177
|
**kwargs,
|
|
180
178
|
)
|
|
181
179
|
|
|
@@ -233,7 +231,7 @@ def explore(
|
|
|
233
231
|
max_zoom=max_zoom,
|
|
234
232
|
max_images=max_images,
|
|
235
233
|
max_nodata_percentage=max_nodata_percentage,
|
|
236
|
-
|
|
234
|
+
wms=wms,
|
|
237
235
|
**kwargs,
|
|
238
236
|
)
|
|
239
237
|
|
|
@@ -245,7 +243,7 @@ def explore(
|
|
|
245
243
|
smooth_factor=smooth_factor,
|
|
246
244
|
max_images=max_images,
|
|
247
245
|
max_nodata_percentage=max_nodata_percentage,
|
|
248
|
-
|
|
246
|
+
wms=wms,
|
|
249
247
|
**kwargs,
|
|
250
248
|
)
|
|
251
249
|
|
|
@@ -271,7 +269,7 @@ def samplemap(
|
|
|
271
269
|
browser: bool = False,
|
|
272
270
|
max_images: int = 10,
|
|
273
271
|
max_nodata_percentage: int = 100,
|
|
274
|
-
|
|
272
|
+
wms: WmsLoader | None = None,
|
|
275
273
|
**kwargs,
|
|
276
274
|
) -> Explore:
|
|
277
275
|
"""Shows an interactive map of a random area of GeoDataFrames.
|
|
@@ -307,9 +305,7 @@ def samplemap(
|
|
|
307
305
|
map. Defaults to 10.
|
|
308
306
|
max_nodata_percentage: Maximum percentage nodata values (e.g. clouds) ro allow in
|
|
309
307
|
image arrays.
|
|
310
|
-
|
|
311
|
-
into the map. Can optionally be set to an instance of NorgeIBilderWms to filter
|
|
312
|
-
years and names.
|
|
308
|
+
wms: A WmsLoader instance for loading image tiles as layers. E.g. NorgeIBilderWms.
|
|
313
309
|
**kwargs: Keyword arguments to pass to geopandas.GeoDataFrame.explore, for
|
|
314
310
|
instance 'cmap' to change the colors, 'scheme' to change how the data
|
|
315
311
|
is grouped. This defaults to 'fisherjenkssampled' for numeric data.
|
|
@@ -393,7 +389,7 @@ def samplemap(
|
|
|
393
389
|
smooth_factor=smooth_factor,
|
|
394
390
|
max_images=max_images,
|
|
395
391
|
max_nodata_percentage=max_nodata_percentage,
|
|
396
|
-
|
|
392
|
+
wms=wms,
|
|
397
393
|
**kwargs,
|
|
398
394
|
)
|
|
399
395
|
|
|
@@ -408,7 +404,7 @@ def clipmap(
|
|
|
408
404
|
browser: bool = False,
|
|
409
405
|
max_images: int = 10,
|
|
410
406
|
max_nodata_percentage: int = 100,
|
|
411
|
-
|
|
407
|
+
wms: WmsLoader | None = None,
|
|
412
408
|
**kwargs,
|
|
413
409
|
) -> Explore | Map:
|
|
414
410
|
"""Shows an interactive map of a of GeoDataFrames clipped to the mask extent.
|
|
@@ -439,9 +435,7 @@ def clipmap(
|
|
|
439
435
|
map. Defaults to 10.
|
|
440
436
|
max_nodata_percentage: Maximum percentage nodata values (e.g. clouds) ro allow in
|
|
441
437
|
image arrays.
|
|
442
|
-
|
|
443
|
-
into the map. Can optionally be set to an instance of NorgeIBilderWms to filter
|
|
444
|
-
years and names.
|
|
438
|
+
wms: A WmsLoader instance for loading image tiles as layers. E.g. NorgeIBilderWms.
|
|
445
439
|
**kwargs: Keyword arguments to pass to geopandas.GeoDataFrame.explore, for
|
|
446
440
|
instance 'cmap' to change the colors, 'scheme' to change how the data
|
|
447
441
|
is grouped. This defaults to 'fisherjenkssampled' for numeric data.
|
|
@@ -477,7 +471,7 @@ def clipmap(
|
|
|
477
471
|
smooth_factor=smooth_factor,
|
|
478
472
|
max_images=max_images,
|
|
479
473
|
max_nodata_percentage=max_nodata_percentage,
|
|
480
|
-
|
|
474
|
+
wms=wms,
|
|
481
475
|
**kwargs,
|
|
482
476
|
)
|
|
483
477
|
m.mask = mask
|
|
@@ -280,7 +280,10 @@ class ThematicMap(Map):
|
|
|
280
280
|
return self
|
|
281
281
|
|
|
282
282
|
def add_background(
|
|
283
|
-
self,
|
|
283
|
+
self,
|
|
284
|
+
gdf: GeoDataFrame,
|
|
285
|
+
color: str | None = None,
|
|
286
|
+
**kwargs,
|
|
284
287
|
) -> "ThematicMap":
|
|
285
288
|
"""Add a GeoDataFrame as a background layer.
|
|
286
289
|
|
|
@@ -288,6 +291,7 @@ class ThematicMap(Map):
|
|
|
288
291
|
gdf: a GeoDataFrame.
|
|
289
292
|
color: Single color. Defaults to gray (shade depends on whether the map
|
|
290
293
|
facecolor is black or white).
|
|
294
|
+
**kwargs: Keyword arguments sent to GeoDataFrame.plot.
|
|
291
295
|
"""
|
|
292
296
|
if color:
|
|
293
297
|
self.bg_gdf_color = color
|
|
@@ -299,6 +303,7 @@ class ThematicMap(Map):
|
|
|
299
303
|
)
|
|
300
304
|
if self.bounds is None:
|
|
301
305
|
self.bounds = to_bbox(self._gdf.total_bounds)
|
|
306
|
+
self.bg_gdf_kwargs = kwargs
|
|
302
307
|
return self
|
|
303
308
|
|
|
304
309
|
def plot(self, **kwargs) -> None:
|
|
@@ -515,7 +520,9 @@ class ThematicMap(Map):
|
|
|
515
520
|
def _actually_add_background(self) -> None:
|
|
516
521
|
self.ax.set_xlim([self.minx - self.diffx * 0.03, self.maxx + self.diffx * 0.03])
|
|
517
522
|
self.ax.set_ylim([self.miny - self.diffy * 0.03, self.maxy + self.diffy * 0.03])
|
|
518
|
-
self._background_gdfs.plot(
|
|
523
|
+
self._background_gdfs.plot(
|
|
524
|
+
ax=self.ax, color=self.bg_gdf_color, **self.bg_gdf_kwargs
|
|
525
|
+
)
|
|
519
526
|
|
|
520
527
|
@staticmethod
|
|
521
528
|
def _get_matplotlib_figure_and_axix(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import abc
|
|
1
2
|
import datetime
|
|
2
3
|
import json
|
|
3
4
|
import re
|
|
@@ -24,7 +25,28 @@ DEFAULT_YEARS: tuple[str] = tuple(
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
@dataclass
|
|
27
|
-
class
|
|
28
|
+
class WmsLoader(abc.ABC):
|
|
29
|
+
"""Abstract base class for wms loaders.
|
|
30
|
+
|
|
31
|
+
Child classes must implement the method 'get_tiles',
|
|
32
|
+
which should return a list of folium.WmsTileLayer.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
@abc.abstractmethod
|
|
36
|
+
def get_tiles(self, bbox: Any, max_zoom: int = 40) -> list[folium.WmsTileLayer]:
|
|
37
|
+
"""Get all tiles intersecting with a bbox."""
|
|
38
|
+
|
|
39
|
+
@abc.abstractmethod
|
|
40
|
+
def load_tiles(self) -> None:
|
|
41
|
+
"""Load all tiles into self.tiles.
|
|
42
|
+
|
|
43
|
+
Not needed in sgis.explore.
|
|
44
|
+
"""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class NorgeIBilderWms(WmsLoader):
|
|
28
50
|
"""Loads Norge i bilder tiles as folium.WmsTiles."""
|
|
29
51
|
|
|
30
52
|
years: Iterable[int | str] = DEFAULT_YEARS
|
|
@@ -590,7 +590,7 @@ class Parallel:
|
|
|
590
590
|
with_neighbors: bool = False,
|
|
591
591
|
funcdict: dict[str, Callable] | None = None,
|
|
592
592
|
file_type: str = "parquet",
|
|
593
|
-
muni_number_col: str = "
|
|
593
|
+
muni_number_col: str = "komm_nr",
|
|
594
594
|
strict: bool = False,
|
|
595
595
|
write_empty: bool = False,
|
|
596
596
|
id_assign_func: Callable | functools.partial = clean_overlay,
|
|
@@ -622,7 +622,7 @@ class Parallel:
|
|
|
622
622
|
the data is read.
|
|
623
623
|
file_type: Defaults to parquet.
|
|
624
624
|
muni_number_col: String column name with municipality
|
|
625
|
-
number/identifier. Defaults to
|
|
625
|
+
number/identifier. Defaults to komm_nr. If the column is not present
|
|
626
626
|
in the data to be split, the data will be intersected with the
|
|
627
627
|
municipalities.
|
|
628
628
|
strict: If False (default), the dictionaries 'out_data' and 'funcdict' does
|
|
@@ -761,7 +761,7 @@ def write_municipality_data(
|
|
|
761
761
|
out_folder: str,
|
|
762
762
|
municipalities: GeoDataFrame | list[str] | None = None,
|
|
763
763
|
with_neighbors: bool = False,
|
|
764
|
-
muni_number_col: str = "
|
|
764
|
+
muni_number_col: str = "komm_nr",
|
|
765
765
|
file_type: str = "parquet",
|
|
766
766
|
func: Callable | None = None,
|
|
767
767
|
write_empty: bool = False,
|
|
@@ -840,7 +840,7 @@ def _write_municipality_data(
|
|
|
840
840
|
data: str | GeoDataFrame | DataFrame,
|
|
841
841
|
out_folder: str,
|
|
842
842
|
municipalities: GeoDataFrame | list[str] | None = None,
|
|
843
|
-
muni_number_col: str = "
|
|
843
|
+
muni_number_col: str = "komm_nr",
|
|
844
844
|
file_type: str = "parquet",
|
|
845
845
|
func: Callable | None = None,
|
|
846
846
|
write_empty: bool = False,
|
|
@@ -896,7 +896,7 @@ def _write_neighbor_municipality_data(
|
|
|
896
896
|
data: str | GeoDataFrame | DataFrame,
|
|
897
897
|
out_folder: str,
|
|
898
898
|
municipalities: GeoDataFrame,
|
|
899
|
-
muni_number_col: str = "
|
|
899
|
+
muni_number_col: str = "komm_nr",
|
|
900
900
|
file_type: str = "parquet",
|
|
901
901
|
func: Callable | None = None,
|
|
902
902
|
write_empty: bool = False,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|