ssb-sgis 1.2.6__py3-none-any.whl → 1.2.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.
@@ -432,7 +432,7 @@ def _run_func_by_cluster(
432
432
 
433
433
  def get_group_clusters(group: GeoDataFrame):
434
434
  """Adds cluster column. Applied to each group because much faster."""
435
- group = group.reset_index(drop=True)
435
+ group = group[~group.is_empty].reset_index(drop=True)
436
436
  group["_cluster"] = get_cluster_mapper(group, predicate=predicate)
437
437
  group["_cluster"] = get_grouped_centroids(group, groupby="_cluster")
438
438
  return group
@@ -1,7 +1,3 @@
1
- try:
2
- import geocoder
3
- except ImportError:
4
- pass
5
1
  from geopandas import GeoDataFrame
6
2
 
7
3
  from .conversion import to_gdf
@@ -9,6 +5,8 @@ from .conversion import to_gdf
9
5
 
10
6
  def address_to_gdf(address: str, crs=4326) -> GeoDataFrame:
11
7
  """Takes an address and returns a point GeoDataFrame."""
8
+ import geocoder
9
+
12
10
  g = geocoder.osm(address).json
13
11
  coords = g["lng"], g["lat"]
14
12
  return to_gdf(coords, crs=4326).to_crs(crs)
@@ -16,6 +14,8 @@ def address_to_gdf(address: str, crs=4326) -> GeoDataFrame:
16
14
 
17
15
  def address_to_coords(address: str, crs=4326) -> tuple[float, float]:
18
16
  """Takes an address and returns a tuple of xy coordinates."""
17
+ import geocoder
18
+
19
19
  g = geocoder.osm(address).json
20
20
  coords = g["lng"], g["lat"]
21
21
  point = to_gdf(coords, crs=4326).to_crs(crs)
@@ -83,6 +83,8 @@ def sfilter(
83
83
  """
84
84
  if not isinstance(gdf, (GeoDataFrame | GeoSeries)):
85
85
  raise TypeError(gdf_type_error_message)
86
+ if not len(gdf):
87
+ return gdf
86
88
 
87
89
  other = _sfilter_checks(other, crs=gdf.crs)
88
90
 
@@ -159,6 +161,9 @@ def sfilter_split(
159
161
  >>> not_intersecting = df1.loc[~filt]
160
162
 
161
163
  """
164
+ if not len(gdf):
165
+ return gdf, gdf
166
+
162
167
  if not isinstance(gdf, (GeoDataFrame | GeoSeries)):
163
168
  raise TypeError(gdf_type_error_message)
164
169
 
@@ -235,6 +240,9 @@ def sfilter_inverse(
235
240
  """
236
241
  if not isinstance(gdf, (GeoDataFrame | GeoSeries)):
237
242
  raise TypeError(gdf_type_error_message)
243
+ if not len(gdf):
244
+ return gdf
245
+
238
246
  other = _sfilter_checks(other, crs=gdf.crs)
239
247
  indices = _get_sfilter_indices(
240
248
  gdf, other, predicate, distance, n_jobs, rtree_runner
sgis/maps/explore.py CHANGED
@@ -43,6 +43,7 @@ from ..geopandas_tools.general import clean_geoms
43
43
  from ..geopandas_tools.general import make_all_singlepart
44
44
  from ..geopandas_tools.geometry_types import get_geom_type
45
45
  from ..geopandas_tools.geometry_types import to_single_geom_type
46
+ from ..geopandas_tools.sfilter import sfilter
46
47
  from ..helpers import _get_file_system
47
48
  from ..helpers import dict_zip
48
49
  from .wms import WmsLoader
@@ -487,10 +488,13 @@ class Explore(Map):
487
488
  if not isinstance(center, GeoDataFrame)
488
489
  else center
489
490
  )
491
+ centerbuffer = centerpoint.buffer(size)
490
492
 
491
493
  for label, gdf in self._gdfs.items():
492
494
  keep_geom_type = False if get_geom_type(gdf) == "mixed" else True
493
- gdf = gdf.clip(centerpoint.buffer(size), keep_geom_type=keep_geom_type)
495
+ gdf = sfilter(gdf, centerbuffer).clip(
496
+ centerbuffer, keep_geom_type=keep_geom_type
497
+ )
494
498
  self._gdfs[label] = gdf
495
499
  self._gdf = pd.concat(self._gdfs.values(), ignore_index=True)
496
500
 
@@ -547,7 +551,7 @@ class Explore(Map):
547
551
  kwargs.pop("column", None)
548
552
 
549
553
  for label, gdf in self._gdfs.items():
550
- gdf = gdf.clip(self.mask)
554
+ gdf = sfilter(gdf, self.mask).clip(self.mask)
551
555
  collections = gdf.loc[gdf.geom_type == "GeometryCollection"]
552
556
  if len(collections):
553
557
  collections = make_all_singlepart(collections)
@@ -775,9 +779,13 @@ class Explore(Map):
775
779
  for tile in tiles:
776
780
  to_tile(tile, max_zoom=self.max_zoom).add_to(mapobj)
777
781
 
778
- def _add_wms(self, map_: folium.Map, bbox: Any) -> None:
782
+ def _add_wms(self, map_: folium.Map) -> None:
783
+ try:
784
+ gdf = self._gdf.to_crs(4326)
785
+ except Exception:
786
+ gdf = self._gdf.set_crs(4326)
779
787
  for wms in self.wms:
780
- tiles = wms.get_tiles(bbox, max_zoom=self.max_zoom)
788
+ tiles = wms.get_tiles(gdf, max_zoom=self.max_zoom)
781
789
  for tile in tiles.values():
782
790
  map_.add_child(tile)
783
791
 
@@ -991,7 +999,7 @@ class Explore(Map):
991
999
  # folium.LayerControl(collapsed=False).add_to(m)
992
1000
 
993
1001
  if self.wms:
994
- self._add_wms(m, bounds)
1002
+ self._add_wms(m)
995
1003
 
996
1004
  return m
997
1005
 
sgis/maps/map.py CHANGED
@@ -295,9 +295,10 @@ class Map:
295
295
  else:
296
296
  return series.astype("string")
297
297
 
298
- for i, gdf in enumerate(self._gdfs):
298
+ for label, gdf in self._gdfs.items():
299
299
  if self.column in gdf:
300
- self._gdfs[i][self.column] = to_string_via_int(gdf[self.column])
300
+ gdf[self.column] = to_string_via_int(gdf[self.column])
301
+ self._gdfs[label] = gdf
301
302
  self._gdf[self.column] = to_string_via_int(self._gdf[self.column])
302
303
 
303
304
  def __bool__(self) -> bool:
sgis/maps/maps.py CHANGED
@@ -29,6 +29,7 @@ from ..geopandas_tools.general import get_common_crs
29
29
  from ..geopandas_tools.general import is_wkt
30
30
  from ..geopandas_tools.geocoding import address_to_gdf
31
31
  from ..geopandas_tools.geometry_types import get_geom_type
32
+ from ..geopandas_tools.sfilter import sfilter
32
33
  from .explore import Explore
33
34
  from .map import Map
34
35
  from .thematicmap import ThematicMap
@@ -196,10 +197,13 @@ def explore(
196
197
 
197
198
  bounds: Polygon = box(*get_total_bounds(*gdfs, *list(kwargs.values())))
198
199
 
199
- any_intersections: bool = mask.intersects(bounds).any()
200
+ if bounds is not None:
201
+ any_intersections: bool = mask.intersects(bounds).any()
202
+ else:
203
+ any_intersections = False
200
204
  if not any_intersections and to_crs is None:
201
205
  mask = to_gdf(Polygon(), to_crs)
202
- elif not any_intersections:
206
+ elif not any_intersections and bounds is not None:
203
207
  bounds4326 = to_gdf(bounds, to_crs).to_crs(25833).geometry.iloc[0]
204
208
  mask4326 = mask.set_crs(4326, allow_override=True).to_crs(25833)
205
209
 
@@ -472,8 +476,10 @@ def clipmap(
472
476
  if m.gdfs is None and not len(m.rasters):
473
477
  return m
474
478
 
475
- m._gdfs = {label: gdf.clip(mask) for label, gdf in m._gdfs.items()}
476
- m._gdf = m._gdf.clip(mask)
479
+ m._gdfs = {
480
+ label: sfilter(gdf, mask).clip(mask) for label, gdf in m._gdfs.items()
481
+ }
482
+ m._gdf = sfilter(m._gdf, mask).clip(mask)
477
483
  m._nan_idx = m._gdf[m._column].isna()
478
484
  m._get_unique_values()
479
485
  m.explore(center=center, size=size)
@@ -487,8 +493,10 @@ def clipmap(
487
493
  if m.gdfs is None:
488
494
  return m
489
495
 
490
- m._gdfs = {label: gdf.clip(mask) for label, gdf in m._gdfs.items()}
491
- m._gdf = m._gdf.clip(mask)
496
+ m._gdfs = {
497
+ label: sfilter(gdf, mask).clip(mask) for label, gdf in m._gdfs.items()
498
+ }
499
+ m._gdf = sfilter(m._gdf, mask).clip(mask)
492
500
  m._nan_idx = m._gdf[m._column].isna()
493
501
  m._get_unique_values()
494
502