ssb-sgis 1.0.2__tar.gz → 1.0.4__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.
Files changed (67) hide show
  1. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/PKG-INFO +6 -7
  2. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/pyproject.toml +11 -12
  3. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/__init__.py +20 -9
  4. ssb_sgis-1.0.4/src/sgis/debug_config.py +24 -0
  5. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/exceptions.py +2 -2
  6. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/bounds.py +33 -36
  7. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/buffer_dissolve_explode.py +136 -35
  8. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/centerlines.py +4 -91
  9. ssb_sgis-1.0.4/src/sgis/geopandas_tools/cleaning.py +1734 -0
  10. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/conversion.py +38 -19
  11. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/duplicates.py +29 -8
  12. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/general.py +263 -100
  13. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/geometry_types.py +4 -4
  14. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/neighbors.py +19 -15
  15. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/overlay.py +2 -2
  16. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/point_operations.py +5 -5
  17. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/polygon_operations.py +510 -105
  18. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/polygons_as_rings.py +40 -8
  19. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/sfilter.py +29 -12
  20. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/helpers.py +3 -3
  21. ssb_sgis-1.0.4/src/sgis/io/dapla_functions.py +486 -0
  22. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/io/read_parquet.py +1 -1
  23. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/examine.py +27 -12
  24. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/explore.py +450 -65
  25. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/legend.py +177 -76
  26. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/map.py +206 -103
  27. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/maps.py +178 -105
  28. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/thematicmap.py +243 -83
  29. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/_service_area.py +6 -1
  30. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/closing_network_holes.py +2 -2
  31. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/cutting_lines.py +15 -8
  32. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/directednetwork.py +1 -1
  33. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/finding_isolated_networks.py +15 -8
  34. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/networkanalysis.py +17 -19
  35. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/networkanalysisrules.py +1 -1
  36. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/traveling_salesman.py +1 -1
  37. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/parallel/parallel.py +64 -27
  38. ssb_sgis-1.0.4/src/sgis/raster/base.py +260 -0
  39. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/raster/cube.py +54 -8
  40. ssb_sgis-1.0.4/src/sgis/raster/image_collection.py +3257 -0
  41. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/raster/indices.py +17 -5
  42. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/raster/raster.py +138 -243
  43. ssb_sgis-1.0.4/src/sgis/raster/sentinel_config.py +120 -0
  44. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/raster/zonal.py +0 -1
  45. ssb_sgis-1.0.2/src/sgis/geopandas_tools/cleaning.py +0 -741
  46. ssb_sgis-1.0.2/src/sgis/io/dapla_functions.py +0 -267
  47. ssb_sgis-1.0.2/src/sgis/raster/__init__.py +0 -6
  48. ssb_sgis-1.0.2/src/sgis/raster/base.py +0 -52
  49. ssb_sgis-1.0.2/src/sgis/raster/torchgeo.py +0 -171
  50. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/LICENSE +0 -0
  51. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/README.md +0 -0
  52. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/__init__.py +0 -0
  53. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/geopandas_tools/geocoding.py +0 -0
  54. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/io/_is_dapla.py +0 -0
  55. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/io/opener.py +0 -0
  56. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/__init__.py +0 -0
  57. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/httpserver.py +0 -0
  58. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/maps/tilesources.py +0 -0
  59. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/__init__.py +0 -0
  60. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/_get_route.py +0 -0
  61. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/_od_cost_matrix.py +0 -0
  62. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/_points.py +0 -0
  63. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/network.py +0 -0
  64. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/networkanalysis/nodes.py +0 -0
  65. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/py.typed +0 -0
  66. /ssb_sgis-1.0.2/src/sgis/raster/methods_as_functions.py → /ssb_sgis-1.0.4/src/sgis/raster/__init__.py +0 -0
  67. {ssb_sgis-1.0.2 → ssb_sgis-1.0.4}/src/sgis/raster/cubebase.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ssb-sgis
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: GIS functions used at Statistics Norway.
5
5
  Home-page: https://github.com/statisticsnorway/ssb-sgis
6
6
  License: MIT
@@ -21,12 +21,10 @@ Provides-Extra: torch
21
21
  Provides-Extra: xarray
22
22
  Requires-Dist: affine (>=2.4.0)
23
23
  Requires-Dist: branca (>=0.6.0)
24
- Requires-Dist: dapla-toolbelt (>=2.0.12) ; extra == "all" or extra == "bucket"
25
- Requires-Dist: dask (>=2024.1.1)
26
- Requires-Dist: dask-geopandas (>=0.3.0)
24
+ Requires-Dist: dapla-toolbelt (>=3.0.1) ; extra == "all" or extra == "bucket"
25
+ Requires-Dist: dask (>=2024.1.1) ; extra == "all" or extra == "test"
27
26
  Requires-Dist: folium (>=0.14.0)
28
27
  Requires-Dist: gcsfs (>=2024.3.1) ; extra == "all" or extra == "bucket"
29
- Requires-Dist: geocoder (>=1.38.1)
30
28
  Requires-Dist: geopandas (>=0.14.0)
31
29
  Requires-Dist: igraph (>=0.11.2)
32
30
  Requires-Dist: ipython (>=8.13.2)
@@ -36,7 +34,8 @@ Requires-Dist: joblib (>=1.4.0)
36
34
  Requires-Dist: mapclassify (>=2.5.0)
37
35
  Requires-Dist: matplotlib (>=3.7.0)
38
36
  Requires-Dist: networkx (>=3.0)
39
- Requires-Dist: numpy (>=1.24.2)
37
+ Requires-Dist: numba (>=0.60.0)
38
+ Requires-Dist: numpy (>=1.26.4)
40
39
  Requires-Dist: pandas (>=2.2.1)
41
40
  Requires-Dist: pyarrow (>=11.0.0)
42
41
  Requires-Dist: pyproj (>=3.6.1)
@@ -46,7 +45,7 @@ Requires-Dist: rioxarray (>=0.15.5) ; extra == "all" or extra == "xarray" or ext
46
45
  Requires-Dist: rtree (>=1.0.1)
47
46
  Requires-Dist: scikit-learn (>=1.2.1)
48
47
  Requires-Dist: shapely (>=2.0.1)
49
- Requires-Dist: torch (==2.2.2) ; extra == "all" or extra == "torch" or extra == "test"
48
+ Requires-Dist: torch (>=2.4.0) ; extra == "all" or extra == "torch" or extra == "test"
50
49
  Requires-Dist: torchgeo (>=0.5.2) ; extra == "all" or extra == "torch" or extra == "test"
51
50
  Requires-Dist: typing-extensions (>=4.11.0)
52
51
  Requires-Dist: xarray (>=2024.3.0) ; extra == "all" or extra == "xarray" or extra == "test"
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "ssb-sgis"
3
- version = "1.0.2"
3
+ version = "1.0.4"
4
4
  description = "GIS functions used at Statistics Norway."
5
5
  authors = ["Morten Letnes <morten.letnes@ssb.no>"]
6
6
  license = "MIT"
@@ -21,10 +21,8 @@ Changelog = "https://github.com/statisticsnorway/ssb-sgis/releases"
21
21
  python = ">=3.10,<4"
22
22
  affine = ">=2.4.0"
23
23
  branca = ">=0.6.0"
24
- dask = ">=2024.1.1"
25
- dask-geopandas = ">=0.3.0"
24
+ dask = { version = ">=2024.1.1", optional = true }
26
25
  folium = ">=0.14.0"
27
- geocoder = ">=1.38.1"
28
26
  geopandas = ">=0.14.0"
29
27
  igraph = ">=0.11.2"
30
28
  ipython = ">=8.13.2"
@@ -34,7 +32,8 @@ joblib = ">=1.4.0"
34
32
  mapclassify = ">=2.5.0"
35
33
  matplotlib = ">=3.7.0"
36
34
  networkx = ">=3.0"
37
- numpy = ">=1.24.2"
35
+ numba = { version = ">=0.60.0", optional = true }
36
+ numpy = ">=1.26.4"
38
37
  pandas = ">=2.2.1"
39
38
  pyarrow = ">=11.0.0"
40
39
  pyproj = ">=3.6.1"
@@ -47,18 +46,17 @@ typing-extensions = ">=4.11.0"
47
46
  xyzservices = ">=2023.2.0"
48
47
  xarray = { version = ">=2024.3.0", optional = true }
49
48
  rioxarray = { version = ">=0.15.5", optional = true }
50
- torch = { version = "==2.2.2", optional = true } # Until this is fixed https://github.com/pytorch/pytorch/issues/124897
49
+ torch = { version = ">=2.4.0", optional = true }
51
50
  torchgeo = { version = ">=0.5.2", optional = true }
52
- dapla-toolbelt = { version = ">=2.0.12", optional = true }
51
+ dapla-toolbelt = { version = ">=3.0.1", optional = true }
53
52
  gcsfs = { version = ">=2024.3.1", optional = true }
54
53
 
55
54
  [tool.poetry.extras]
56
- all = ["pyogrio", "xarray", "rioxarray", "torch", "torchgeo", "dapla-toolbelt", "gcsfs"]
55
+ all = ["pyogrio", "xarray", "rioxarray", "torch", "torchgeo", "dapla-toolbelt", "gcsfs", "dask"]
57
56
  bucket = ["dapla-toolbelt", "gcsfs"]
58
57
  torch = ["torch", "torchgeo"]
59
58
  xarray = ["xarray", "rioxarray"]
60
- test = ["xarray", "rioxarray", "torch", "torchgeo"]
61
-
59
+ test = ["xarray", "rioxarray", "torch", "torchgeo", "dask"]
62
60
  [tool.poetry.group.dev.dependencies]
63
61
  pygments = ">=2.10.0"
64
62
  black = { extras = ["jupyter"], version = ">=23.1.0" }
@@ -84,7 +82,8 @@ jupytext = ">=1.16.1"
84
82
  pytest-cov = ">=5.0.0"
85
83
  pandas-stubs = ">=2.2.1.240316"
86
84
  types-requests = ">=2.31.0.20240406"
87
-
85
+ # bitsandbytes not released for macos for version > 0.42
86
+ bitsandbytes = { version = "0.42.0", markers = "sys_platform == 'darwin'" }
88
87
 
89
88
  [tool.pytest.ini_options]
90
89
  pythonpath = ["src"]
@@ -114,7 +113,6 @@ module = [
114
113
  "affine.*",
115
114
  "branca.*",
116
115
  "dapla.*",
117
- "dask_geopandas.*",
118
116
  "folium.*",
119
117
  "gcsfs.*",
120
118
  "geocoder.*",
@@ -180,6 +178,7 @@ ignore = [
180
178
  "ANN001", # TODO temporary. Missing type annotation for function argument ...
181
179
  "D103", # TODO temporary. Missing docstring in public function
182
180
  "B018", # Found useless expression
181
+ "E712", # Avoid equality comparisons to `True`; use `if x:` for truth checks (because 'is' doesn't work with numpy/pandas)
183
182
  ]
184
183
 
185
184
  [tool.ruff.lint.isort]
@@ -2,6 +2,7 @@ config = {
2
2
  "n_jobs": 1,
3
3
  }
4
4
 
5
+
5
6
  import sgis.raster.indices as indices
6
7
  from sgis.raster.raster import Raster
7
8
  from sgis.raster.raster import get_shape_from_bounds
@@ -15,7 +16,6 @@ from .geopandas_tools.bounds import gridloop
15
16
  from .geopandas_tools.bounds import make_grid
16
17
  from .geopandas_tools.bounds import make_grid_from_bbox
17
18
  from .geopandas_tools.bounds import make_ssb_grid
18
- from .geopandas_tools.bounds import points_in_bounds
19
19
  from .geopandas_tools.buffer_dissolve_explode import buff
20
20
  from .geopandas_tools.buffer_dissolve_explode import buffdiss
21
21
  from .geopandas_tools.buffer_dissolve_explode import buffdissexp
@@ -26,9 +26,9 @@ from .geopandas_tools.buffer_dissolve_explode import dissexp
26
26
  from .geopandas_tools.buffer_dissolve_explode import dissexp_by_cluster
27
27
  from .geopandas_tools.centerlines import get_rough_centerlines
28
28
  from .geopandas_tools.cleaning import coverage_clean
29
- from .geopandas_tools.cleaning import remove_spikes
30
29
  from .geopandas_tools.cleaning import split_and_eliminate_by_longest
31
- from .geopandas_tools.cleaning import split_by_neighbors
30
+
31
+ # from .geopandas_tools.cleaning import split_by_neighbors
32
32
  from .geopandas_tools.conversion import coordinate_array
33
33
  from .geopandas_tools.conversion import from_4326
34
34
  from .geopandas_tools.conversion import to_4326
@@ -44,6 +44,8 @@ from .geopandas_tools.general import clean_geoms
44
44
  from .geopandas_tools.general import drop_inactive_geometry_columns
45
45
  from .geopandas_tools.general import get_common_crs
46
46
  from .geopandas_tools.general import get_grouped_centroids
47
+ from .geopandas_tools.general import get_line_segments
48
+ from .geopandas_tools.general import points_in_bounds
47
49
  from .geopandas_tools.general import random_points
48
50
  from .geopandas_tools.general import random_points_in_polygons
49
51
  from .geopandas_tools.general import sort_large_first
@@ -66,6 +68,7 @@ from .geopandas_tools.neighbors import sjoin_within_distance
66
68
  from .geopandas_tools.overlay import clean_overlay
67
69
  from .geopandas_tools.point_operations import snap_all
68
70
  from .geopandas_tools.point_operations import snap_within_distance
71
+ from .geopandas_tools.polygon_operations import clean_dissexp
69
72
  from .geopandas_tools.polygon_operations import close_all_holes
70
73
  from .geopandas_tools.polygon_operations import close_small_holes
71
74
  from .geopandas_tools.polygon_operations import close_thin_holes
@@ -76,6 +79,7 @@ from .geopandas_tools.polygon_operations import get_cluster_mapper
76
79
  from .geopandas_tools.polygon_operations import get_gaps
77
80
  from .geopandas_tools.polygon_operations import get_holes
78
81
  from .geopandas_tools.polygon_operations import get_polygon_clusters
82
+ from .geopandas_tools.polygon_operations import split_polygons_by_lines
79
83
  from .geopandas_tools.polygons_as_rings import PolygonsAsRings
80
84
  from .geopandas_tools.sfilter import sfilter
81
85
  from .geopandas_tools.sfilter import sfilter_inverse
@@ -115,15 +119,22 @@ from .networkanalysis.traveling_salesman import traveling_salesman_problem
115
119
  from .parallel.parallel import Parallel
116
120
  from .parallel.parallel import parallel_overlay
117
121
  from .raster.cube import DataCube
118
-
119
- try:
120
- import sgis.raster.torchgeo as torchgeo
121
- except ImportError:
122
- pass
123
-
122
+ from .raster.cube import concat_cubes
123
+ from .raster.image_collection import Band
124
+ from .raster.image_collection import Image
125
+ from .raster.image_collection import ImageCollection
126
+ from .raster.image_collection import NDVIBand
127
+ from .raster.image_collection import Sentinel2Band
128
+ from .raster.image_collection import Sentinel2CloudlessBand
129
+ from .raster.image_collection import Sentinel2CloudlessCollection
130
+ from .raster.image_collection import Sentinel2CloudlessImage
131
+ from .raster.image_collection import Sentinel2Collection
132
+ from .raster.image_collection import Sentinel2Image
133
+ from .raster.image_collection import concat_image_collections
124
134
 
125
135
  try:
126
136
  from .io.dapla_functions import check_files
137
+ from .io.dapla_functions import get_bounds_series
127
138
  from .io.dapla_functions import read_geopandas
128
139
  from .io.dapla_functions import write_geopandas
129
140
  except ImportError:
@@ -0,0 +1,24 @@
1
+ from typing import Any
2
+
3
+
4
+ class _NoExplore:
5
+ """Simply so signal that explore functions should be immediately exited."""
6
+
7
+
8
+ _DEBUG_CONFIG = {
9
+ # "center": (5.3719398, 59.00999914, 0.01),
10
+ # "center": (5.27306727, 59.44232754, 200),
11
+ # "center": (5.85575588, 62.33991158, 200),
12
+ # "center": (26.02870514, 70.68108478, 200),
13
+ "center": _NoExplore(),
14
+ "print": False,
15
+ }
16
+
17
+
18
+ def _try_debug_print(*args: Any) -> None:
19
+ if not _DEBUG_CONFIG["print"]:
20
+ return
21
+ try:
22
+ print(*args)
23
+ except Exception:
24
+ pass
@@ -1,7 +1,7 @@
1
1
  """Some small exception classes."""
2
2
 
3
3
 
4
- class NoPointsWithinSearchToleranceError(Exception):
4
+ class NoPointsWithinSearchToleranceError(ValueError):
5
5
  """Exception for when the points are too far away from the network."""
6
6
 
7
7
  def __init__(
@@ -19,5 +19,5 @@ class NoPointsWithinSearchToleranceError(Exception):
19
19
  )
20
20
 
21
21
 
22
- class ZeroLinesError(Exception):
22
+ class ZeroLinesError(ValueError):
23
23
  """DataFrame has 0 rows."""
@@ -18,7 +18,7 @@ from ..parallel.parallel import Parallel
18
18
  from .conversion import to_bbox
19
19
  from .conversion import to_gdf
20
20
  from .general import clean_clip
21
- from .general import is_bbox_like
21
+ from .general import get_common_crs
22
22
 
23
23
 
24
24
  @dataclass
@@ -37,7 +37,7 @@ class Gridlooper:
37
37
  Defaults to True.
38
38
 
39
39
  Examples:
40
- --------
40
+ ---------
41
41
  Get some points and some polygons.
42
42
 
43
43
  >>> import sgis as sg
@@ -133,11 +133,7 @@ class Gridlooper:
133
133
  )
134
134
  results = self.parallelizer.map(func_with_clip, buffered_grid)
135
135
  if not self.gridbuffer or not self.clip:
136
- return (
137
- results
138
- if not self.concat
139
- else pd.concat(results, ignore_index=True)
140
- )
136
+ return self._return(results, args, kwargs)
141
137
  out = []
142
138
  for cell_res, unbuffered in zip(results, grid, strict=True):
143
139
  out.append(
@@ -145,7 +141,7 @@ class Gridlooper:
145
141
  cell_res, unbuffered, self.keep_geom_type
146
142
  )
147
143
  )
148
- return out if not self.concat else pd.concat(out, ignore_index=True)
144
+ return self._return(out, args, kwargs)
149
145
 
150
146
  results = []
151
147
  for i, (unbuffered, buffered) in enumerate(
@@ -175,7 +171,18 @@ class Gridlooper:
175
171
  if self.verbose:
176
172
  print(f"Done with {i+1} of {n} grid cells", end="\r")
177
173
 
178
- return results if not self.concat else pd.concat(results, ignore_index=True)
174
+ return self._return(results, args, kwargs)
175
+
176
+ def _return(
177
+ self, results: list[Any], args: tuple[Any], kwargs: dict[str, Any]
178
+ ) -> list[Any] | GeoDataFrame:
179
+ if self.concat and len(results):
180
+ return pd.concat(results, ignore_index=True)
181
+ elif self.concat:
182
+ crs = get_common_crs(list(args) + list(kwargs.values()))
183
+ return GeoDataFrame({"geometry": []}, crs=crs)
184
+ else:
185
+ return results
179
186
 
180
187
 
181
188
  def gridloop(
@@ -222,7 +229,7 @@ def gridloop(
222
229
  TypeError: If args or kwargs has a wrong type
223
230
 
224
231
  Examples:
225
- --------
232
+ ---------
226
233
  Get some points and some polygons.
227
234
 
228
235
  >>> import sgis as sg
@@ -442,7 +449,7 @@ def make_grid(
442
449
  obj: GeoDataFrame | GeoSeries | Geometry | tuple,
443
450
  gridsize: int | float,
444
451
  *,
445
- crs: CRS = None,
452
+ crs: CRS | None = None,
446
453
  clip_to_bounds: bool = False,
447
454
  ) -> GeoDataFrame:
448
455
  """Create a polygon grid around geometries.
@@ -467,10 +474,6 @@ def make_grid(
467
474
  """
468
475
  if isinstance(obj, (GeoDataFrame | GeoSeries)):
469
476
  crs = obj.crs or crs
470
- elif not crs:
471
- raise ValueError(
472
- "'crs' cannot be None when 'obj' is not GeoDataFrame/GeoSeries."
473
- )
474
477
  if hasattr(obj, "__len__") and not len(obj):
475
478
  return GeoDataFrame({"geometry": []}, crs=crs)
476
479
 
@@ -617,7 +620,7 @@ def bounds_to_polygon(
617
620
  GeoDataFrame of box polygons with length and index of 'gdf'.
618
621
 
619
622
  Examples:
620
- --------
623
+ ---------
621
624
  >>> import sgis as sg
622
625
  >>> gdf = sg.to_gdf([MultiPoint([(0, 0), (1, 1)]), Point(0, 0)])
623
626
  >>> gdf
@@ -652,8 +655,9 @@ def bounds_to_points(
652
655
  GeoDataFrame of multipoints with same length and index as 'gdf'.
653
656
 
654
657
  Examples:
655
- --------
658
+ ---------
656
659
  >>> import sgis as sg
660
+ >>> from shapely.geometry import MultiPoint, Point
657
661
  >>> gdf = sg.to_gdf([MultiPoint([(0, 0), (1, 1)]), Point(0, 0)])
658
662
  >>> gdf
659
663
  geometry
@@ -680,24 +684,17 @@ def get_total_bounds(
680
684
  for obj in geometries:
681
685
  try:
682
686
  minx, miny, maxx, maxy = to_bbox(obj)
687
+ xs += [minx, maxx]
688
+ ys += [miny, maxy]
683
689
  except Exception as e:
684
- if strict:
685
- raise e
686
- else:
687
- continue
688
- xs += [minx, maxx]
689
- ys += [miny, maxy]
690
+ try:
691
+ for x in obj:
692
+ minx, miny, maxx, maxy = to_bbox(x)
693
+ xs += [minx, maxx]
694
+ ys += [miny, maxy]
695
+ except Exception as e2:
696
+ if strict:
697
+ raise e2 from e
698
+ else:
699
+ continue
690
700
  return min(xs), min(ys), max(xs), max(ys)
691
-
692
-
693
- def points_in_bounds(gdf: GeoDataFrame | GeoSeries, n2: int) -> GeoDataFrame:
694
- """Get a GeoDataFrame of points within the bounds of the GeoDataFrame."""
695
- if not isinstance(gdf, (GeoDataFrame | GeoSeries)) and is_bbox_like(gdf):
696
- minx, miny, maxx, maxy = gdf
697
- else:
698
- minx, miny, maxx, maxy = gdf.total_bounds
699
- xs = np.linspace(minx, maxx, num=n2)
700
- ys = np.linspace(miny, maxy, num=n2)
701
- x_coords, y_coords = np.meshgrid(xs, ys, indexing="ij")
702
- coords = np.concatenate((x_coords.reshape(-1, 1), y_coords.reshape(-1, 1)), axis=1)
703
- return to_gdf(coords, crs=gdf.crs)