ssb-sgis 1.2.6__py3-none-any.whl → 1.2.7__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.
@@ -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)
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
@@ -472,8 +473,10 @@ def clipmap(
472
473
  if m.gdfs is None and not len(m.rasters):
473
474
  return m
474
475
 
475
- m._gdfs = {label: gdf.clip(mask) for label, gdf in m._gdfs.items()}
476
- m._gdf = m._gdf.clip(mask)
476
+ m._gdfs = {
477
+ label: sfilter(gdf, mask).clip(mask) for label, gdf in m._gdfs.items()
478
+ }
479
+ m._gdf = sfilter(m._gdf, mask).clip(mask)
477
480
  m._nan_idx = m._gdf[m._column].isna()
478
481
  m._get_unique_values()
479
482
  m.explore(center=center, size=size)
@@ -487,8 +490,10 @@ def clipmap(
487
490
  if m.gdfs is None:
488
491
  return m
489
492
 
490
- m._gdfs = {label: gdf.clip(mask) for label, gdf in m._gdfs.items()}
491
- m._gdf = m._gdf.clip(mask)
493
+ m._gdfs = {
494
+ label: sfilter(gdf, mask).clip(mask) for label, gdf in m._gdfs.items()
495
+ }
496
+ m._gdf = sfilter(m._gdf, mask).clip(mask)
492
497
  m._nan_idx = m._gdf[m._column].isna()
493
498
  m._get_unique_values()
494
499
 
@@ -45,14 +45,12 @@ class Points:
45
45
  return [0 for _ in distances]
46
46
 
47
47
  if rules.nodedist_multiplier and rules.nodedist_kmh:
48
- raise ValueError(
49
- "Can only specify one of 'nodedist_multiplier' and 'nodedist_kmh'"
50
- )
48
+ raise ValueError("Cannot set both 'nodedist_multiplier' and 'nodedist_kmh'")
51
49
 
52
50
  if rules.nodedist_multiplier:
53
- if rules.weight != "meters":
51
+ if rules.weight == "minutes":
54
52
  raise ValueError(
55
- "Can only specify 'nodedist_multiplier' when the 'weight' is meters"
53
+ "Cannot set 'nodedist_multiplier' when the 'weight' is minutes"
56
54
  )
57
55
  return [x * rules.nodedist_multiplier for x in distances]
58
56
 
sgis/raster/base.py CHANGED
@@ -38,10 +38,8 @@ def _get_transform_from_bounds(
38
38
  obj: GeoDataFrame | GeoSeries | Geometry | tuple, shape: tuple[int, ...]
39
39
  ) -> Affine:
40
40
  minx, miny, maxx, maxy = to_bbox(obj)
41
- if len(shape) == 2:
42
- height, width = shape
43
- elif len(shape) == 3:
44
- _, height, width = shape
41
+ if len(shape) in [2, 3]:
42
+ height, width = shape[-2:]
45
43
  else:
46
44
  return None
47
45
  # raise ValueError(shape)
@@ -104,7 +102,7 @@ def _array_to_geojson(
104
102
  return _array_to_geojson_loop(array, transform, mask, processes)
105
103
 
106
104
  except Exception as err:
107
- raise err.__class__(array.shape, err) from err
105
+ raise err.__class__(f"{array.shape}: {err}") from err
108
106
 
109
107
 
110
108
  def _array_to_geojson_loop(array, transform, mask, processes):
@@ -860,7 +860,6 @@ class Band(_ImageBandBase):
860
860
  self.transform = _get_transform_from_bounds(self._bounds, shape=data.shape)
861
861
  self._from_array = True
862
862
  self.values = data
863
-
864
863
  self._res = _get_res_from_bounds(self._bounds, self.values.shape)
865
864
 
866
865
  elif not isinstance(data, (str | Path | os.PathLike)):
@@ -1077,7 +1076,6 @@ class Band(_ImageBandBase):
1077
1076
  self.transform = None
1078
1077
  # activate setter
1079
1078
  self.values = self._values
1080
-
1081
1079
  return self
1082
1080
 
1083
1081
  if self.has_array and bounds_was_none:
@@ -1162,8 +1160,7 @@ class Band(_ImageBandBase):
1162
1160
  values.shape,
1163
1161
  )
1164
1162
 
1165
- width, height = values.shape[-2:]
1166
-
1163
+ height, width = values.shape[-2:]
1167
1164
  if width and height:
1168
1165
  self.transform = rasterio.transform.from_bounds(
1169
1166
  *bounds, width, height
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ssb-sgis
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: GIS functions used at Statistics Norway.
5
5
  Home-page: https://github.com/statisticsnorway/ssb-sgis
6
6
  License: MIT
@@ -10,7 +10,7 @@ sgis/geopandas_tools/cleaning.py,sha256=fST0xFztmyn-QUOAfvjZmu7aO_zPiolWK7gd7TR6
10
10
  sgis/geopandas_tools/conversion.py,sha256=CrasgWHAnUmLC5tP73ZTDjQ6ahKFHQGqWj86PUif24M,24176
11
11
  sgis/geopandas_tools/duplicates.py,sha256=TDDM4u1n7SIkyJrOfl1Lno92AmUPqtXBHsj1IUKC0hI,14992
12
12
  sgis/geopandas_tools/general.py,sha256=YRpNEdwTHyFdQOdAfbCmYXS7PxoDjXxoagwpteXkYdI,43937
13
- sgis/geopandas_tools/geocoding.py,sha256=n47aFQMm4yX1MsPnTM4dFjwegCA1ZmGUDj1uyu7OJV4,691
13
+ sgis/geopandas_tools/geocoding.py,sha256=sZjUW52ULhQWDLmU51C9_itBePkDuWkp8swvYaiYmJk,679
14
14
  sgis/geopandas_tools/geometry_types.py,sha256=ijQDbQaZPqPGjBl707H4yooNXpk21RXyatI7itnvqLk,7603
15
15
  sgis/geopandas_tools/neighbors.py,sha256=qTvnOyQyrcWQd0BDrmOvFQd8csMh005e_idJGmB4g7k,17485
16
16
  sgis/geopandas_tools/overlay.py,sha256=5i9u8GgFuU0fCqzELsbIaoUPhw-E7eZHl_yKB0wEcGM,23464
@@ -18,7 +18,7 @@ sgis/geopandas_tools/point_operations.py,sha256=JM4hvfIVxZaZdGNlGzcCurrKzkgC_b9h
18
18
  sgis/geopandas_tools/polygon_operations.py,sha256=v-B9IgbFfm4dVHKPyzvmnNiqVCdtl9ddpCsQpZZ-9sU,49284
19
19
  sgis/geopandas_tools/polygons_as_rings.py,sha256=BX_GZS6F9I4NbEpiOlNBd7zywJjdfdJVi_MkeONBuiM,14941
20
20
  sgis/geopandas_tools/runners.py,sha256=J4lH0RXYDYTLVeQFgNv8gEY0E97QGIQ4zPW5vfoxgDU,12979
21
- sgis/geopandas_tools/sfilter.py,sha256=BPz6-_9B7QdyYmVatZXavdHj7FIW_ztIyJHQOkKJt7A,10284
21
+ sgis/geopandas_tools/sfilter.py,sha256=CZ_-c4t1CQCwJ7RHCKo1Na9u-aAg18xXnJAMiUqoaj8,10411
22
22
  sgis/geopandas_tools/utils.py,sha256=X0pRvB1tWgV_0BCrRS1HU9LtLGnZCpvVPxyqM9JGb0Y,1415
23
23
  sgis/helpers.py,sha256=4N6vFWQ3TYVzRHNcWY_fNa_GkFuaZB3vtCkkFND-qs0,9628
24
24
  sgis/io/__init__.py,sha256=uyBr20YDqB2bQttrd5q1JuGOvX32A-MSvS7Wmw5f5qg,177
@@ -28,11 +28,11 @@ sgis/io/opener.py,sha256=HWO3G1NB6bpXKM94JadCD513vjat1o1TFjWGWzyVasg,898
28
28
  sgis/io/read_parquet.py,sha256=FvZYv1rLkUlrSaUY6QW6E1yntmntTeQuZ9ZRgCDO4IM,3776
29
29
  sgis/maps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  sgis/maps/examine.py,sha256=Pb0dH8JazU5E2svfQrzHO1Bi-sjy5SeyY6zoeMO34jE,9369
31
- sgis/maps/explore.py,sha256=A6-i0uKYIdfS46zrPIURObJqmt2VuQjXyS8FVk58cHU,47657
31
+ sgis/maps/explore.py,sha256=1kdxHpEPlzgkvsYRoqkJxh0sKyjQLualWy-PhHnEwl4,47812
32
32
  sgis/maps/httpserver.py,sha256=TETSGOgLjKl3TquPGoIP0tCJCz7BIwmXrrzSCT7jhXE,2550
33
33
  sgis/maps/legend.py,sha256=qq2RkebuaNAdFztlXrDOWbN0voeK5w5VycmRKyx0NdM,26512
34
- sgis/maps/map.py,sha256=WZ5JnCpdioBCEh6kmV3XB4xVw41fYsEmQ6v8MIfwzmY,30727
35
- sgis/maps/maps.py,sha256=Zkp-UGj92BCFYhY1_TLXL4FjnvwOjGMAryoWCtFdwPk,22989
34
+ sgis/maps/map.py,sha256=XWf3QJ6a4gZno2NziK1dKLRktJGGr-vn6eHudBlW9Uc,30758
35
+ sgis/maps/maps.py,sha256=66xCarrpvlgsts3ut-SnbIiexEwyy_AIed4O4tysUig,23139
36
36
  sgis/maps/norge_i_bilder.json,sha256=VKmb7rg4jvgc8_Ve1fFnHyZ_Dkv4T5GTA0UCpqpFAi4,492751
37
37
  sgis/maps/thematicmap.py,sha256=Z3o_Bca0oty5Cn35pZfX5Qy52sXDVIMVSFD6IlZrovo,25111
38
38
  sgis/maps/tilesources.py,sha256=F4mFHxPwkiPJdVKzNkScTX6xbJAMIUtlTq4mQ83oguw,1746
@@ -40,7 +40,7 @@ sgis/maps/wms.py,sha256=LSBtKkG5d-sggK_qO8BvOHBvPZZV_7AAo25kHF6kPio,6933
40
40
  sgis/networkanalysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  sgis/networkanalysis/_get_route.py,sha256=dMX4Vm6O90ISIZPjQWuZMVMuEubkeSdC2osMCbFvrRU,7750
42
42
  sgis/networkanalysis/_od_cost_matrix.py,sha256=zkyPX7ObT996ahaFJ2oI0D0SqQWbWyfy_qLtXwValPg,3434
43
- sgis/networkanalysis/_points.py,sha256=ajCy17dAmRq3bWRkNu_0LHreCVJ5Uh8DzAKWxyw7ipw,4481
43
+ sgis/networkanalysis/_points.py,sha256=128QEepBGAyI5XakMUVvNyOnJE0Ts7hvGiVUt1YTXiU,4439
44
44
  sgis/networkanalysis/_service_area.py,sha256=jE0X54yS4eMfZYJXeKe_NgMKPDpau-05xWZaxDi_c6Y,5546
45
45
  sgis/networkanalysis/closing_network_holes.py,sha256=FYZ677nRwLmDkP6bQ1ssQ_h29RzAG463U4xmbu5ksfg,14572
46
46
  sgis/networkanalysis/cutting_lines.py,sha256=ZQAt0cufaPeNAEqUzp-imu26AIL9S5-lw6Xifa8RoWk,9818
@@ -55,13 +55,13 @@ sgis/parallel/__init__.py,sha256=fw_Fl3IJk1bKzrRBhZIoOpznJqwd09NVHJJFj2ZLeIU,32
55
55
  sgis/parallel/parallel.py,sha256=V7O5mEZdfJpcOPrmn2H4bEGtbzA0FggjQ8dGhznjr80,40052
56
56
  sgis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  sgis/raster/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
- sgis/raster/base.py,sha256=tiZEuMcVK6hOm_aIjWhQ1WGshcjsxT1fFkuBSLFiMC0,7785
59
- sgis/raster/image_collection.py,sha256=gbC0V2Xmckrsi1iAKbYgrsb_f9rja6Y7QUqMMJVCy2Y,121700
58
+ sgis/raster/base.py,sha256=8JdXXDj8CgJQt5WIkkNbpM5U0pYyQrWQY9dszfUaUQ4,7743
59
+ sgis/raster/image_collection.py,sha256=H7d9c6f-LsGXBK8oCpWBlgd2zbLxYvfNMYllnbrO_rk,121697
60
60
  sgis/raster/indices.py,sha256=efJmgfPg_VuSzXFosXV661IendF8CwPFWtMhyP4TMUg,222
61
61
  sgis/raster/regex.py,sha256=4idTJ9vFtsGtbxcjJrx2VrpJJuDMP3bLdqF93Vc_cmY,3752
62
62
  sgis/raster/sentinel_config.py,sha256=nySDqn2R8M6W8jguoBeSAK_zzbAsqmaI59i32446FwY,1268
63
63
  sgis/raster/zonal.py,sha256=D4Gyptw-yOLTCO41peIuYbY-DANsJCG19xXDlf1QAz4,2299
64
- ssb_sgis-1.2.6.dist-info/LICENSE,sha256=np3IfD5m0ZUofn_kVzDZqliozuiO6wrktw3LRPjyEiI,1073
65
- ssb_sgis-1.2.6.dist-info/METADATA,sha256=1g2k5KcE4NTLcxfNqL08atchi_udhavHB7YLWfLrbew,11740
66
- ssb_sgis-1.2.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
67
- ssb_sgis-1.2.6.dist-info/RECORD,,
64
+ ssb_sgis-1.2.7.dist-info/LICENSE,sha256=np3IfD5m0ZUofn_kVzDZqliozuiO6wrktw3LRPjyEiI,1073
65
+ ssb_sgis-1.2.7.dist-info/METADATA,sha256=oGAi8NDi4GwCfUxWBbJVgRDROiMrb_xrqf13vwhc-n0,11740
66
+ ssb_sgis-1.2.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
67
+ ssb_sgis-1.2.7.dist-info/RECORD,,