dggrid4py 0.4.2__tar.gz → 0.5.1.dev0__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.
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/PKG-INFO +18 -25
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/README.md +11 -10
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/dggrid4py/__init__.py +3 -2
- dggrid4py-0.5.1.dev0/dggrid4py/auxlat.py +37 -0
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/dggrid4py/dggrid_runner.py +906 -563
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/dggrid4py/tool.py +1 -1
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/pyproject.toml +12 -7
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/LICENSE +0 -0
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/dggrid4py/igeo7.py +0 -0
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/dggrid4py/igeo7_ext.py +0 -0
- {dggrid4py-0.4.2 → dggrid4py-0.5.1.dev0}/dggrid4py/interrupt.py +0 -0
|
@@ -1,38 +1,30 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dggrid4py
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1.dev0
|
|
4
4
|
Summary: a Python library to run highlevel functions of DGGRIDv7 and v8
|
|
5
|
-
License: AGPL-3.0-or-later
|
|
5
|
+
License-Expression: AGPL-3.0-or-later
|
|
6
6
|
License-File: LICENSE
|
|
7
|
-
Keywords: python,GIS,DGGS,DGGRID,hexagons,grids,spatial statistics
|
|
7
|
+
Keywords: python,GIS,DGGS,DGGRID,hexagons,grids,spatial statistics,IGEO7
|
|
8
8
|
Author: Alexander Kmoch
|
|
9
9
|
Author-email: alexander.kmoch@ut.ee
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.9, <4.0.0
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Intended Audience :: Education
|
|
14
14
|
Classifier: Intended Audience :: Science/Research
|
|
15
15
|
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
17
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
18
|
Classifier: Operating System :: POSIX
|
|
18
|
-
Classifier: Operating System :: POSIX :: Linux
|
|
19
19
|
Classifier: Operating System :: Unix
|
|
20
|
-
Classifier:
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
28
21
|
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
29
22
|
Requires-Dist: fiona (>=1.8.0,<2.0.0)
|
|
30
23
|
Requires-Dist: geopandas (>=0.9.0,<=1.1.0)
|
|
31
24
|
Requires-Dist: numpy (>=1.22.0,<=2.3.0)
|
|
32
25
|
Requires-Dist: pandas (>=1.4.0,<2.4.0)
|
|
26
|
+
Requires-Dist: pygeodesy (==25.10.10)
|
|
33
27
|
Requires-Dist: shapely (>=1.8.0,<=2.1.0)
|
|
34
|
-
Project-URL: Homepage, https://github.com/allixender/dggrid4py
|
|
35
|
-
Project-URL: Repository, https://github.com/allixender/dggrid4py
|
|
36
28
|
Description-Content-Type: text/markdown
|
|
37
29
|
|
|
38
30
|
# dggrid4py - a Python library to run highlevel functions of DGGRID
|
|
@@ -48,15 +40,15 @@ GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
48
40
|
- [DGGRID Version 8.3 on GitHub](https://github.com/sahrk/DGGRID)
|
|
49
41
|
- [DGGRID User Manual](https://github.com/sahrk/DGGRID/blob/d08e10d761f7bedd72a253ab1057458f339de51e/dggridManualV81b.pdf)
|
|
50
42
|
|
|
51
|
-
You need the
|
|
43
|
+
You need the `dggrid` tool compiled available on the system.
|
|
52
44
|
|
|
53
|
-
Besides some
|
|
45
|
+
Besides some low-level access influence the dggrid operations' metafile creation, a few high-level functions are integrated to work with the more comfortable geopython libraries, like shapely and geopandas
|
|
54
46
|
|
|
55
47
|
- grid_cell_polygons_for_extent(): fill extent/subset with cells at resolution (clip or world)
|
|
56
48
|
- grid_cell_polygons_from_cellids(): geometry_from_cellid for dggs at resolution (from id list)
|
|
57
49
|
- grid_cellids_for_extent(): get_all_indexes/cell_ids for dggs at resolution (clip or world)
|
|
58
50
|
- cells_for_geo_points(): poly_outline for point/centre at resolution
|
|
59
|
-
- address_transform(): conversion
|
|
51
|
+
- address_transform(): conversion between cell_id address types, like SEQNUM, Z7, or Q2DI
|
|
60
52
|
|
|
61
53
|
|
|
62
54
|
```python
|
|
@@ -66,7 +58,7 @@ import shapely
|
|
|
66
58
|
from dggrid4py import DGGRIDv7
|
|
67
59
|
|
|
68
60
|
|
|
69
|
-
# create an
|
|
61
|
+
# create an initial instance that knows where the dggrid tool lives, configure temp workspace and log/stdout output
|
|
70
62
|
# if you have
|
|
71
63
|
dggrid_instance = DGGRIDv7(executable='<path_to>/dggrid', working_dir='.', capture_logs=False, silent=False, tmp_geo_out_legacy=False, debug=False)
|
|
72
64
|
|
|
@@ -79,10 +71,10 @@ gdf1.to_file('isea4t_5.shp')
|
|
|
79
71
|
gdf_centroids = dggrid_instance.grid_cell_centroids_for_extent(dggs_type='ISEA7H', resolution=4, mixed_aperture_level=None, clip_geom=None)
|
|
80
72
|
|
|
81
73
|
# clip extent
|
|
82
|
-
clip_bound = shapely.geometry.box(20.2,57.00, 28.4,60.0
|
|
74
|
+
clip_bound = shapely.geometry.box(20.2,57.00, 28.4,60.0)
|
|
83
75
|
|
|
84
76
|
# ISEA7H grid at resolution 9, for extent of provided WGS84 rectangle into GeoDataFrame to Shapefile
|
|
85
|
-
gdf3 = dggrid_instance.grid_cell_polygons_for_extent('ISEA7H', 9, clip_geom=
|
|
77
|
+
gdf3 = dggrid_instance.grid_cell_polygons_for_extent('ISEA7H', 9, clip_geom=clip_bound)
|
|
86
78
|
print(gdf3.head())
|
|
87
79
|
gdf3.to_file('grids/est_shape_isea7h_9.shp')
|
|
88
80
|
|
|
@@ -92,6 +84,8 @@ print(df1.head(8))
|
|
|
92
84
|
df1.to_csv('isea7h_8_stats.csv', index=False)
|
|
93
85
|
|
|
94
86
|
# generate the DGGS grid cells that would cover a GeoDataFrame of points, return Polygons with cell IDs as GeoDataFrame
|
|
87
|
+
points = [shapely.Point(20.5, 57.5), shapely.Point(21.0, 58.0)]
|
|
88
|
+
geodf_points_wgs84 = geopandas.GeoDataFrame({'name': ['A', 'B']}, geometry=points, crs='EPSG:4326')
|
|
95
89
|
gdf4 = dggrid_instance.cells_for_geo_points(geodf_points_wgs84, False, 'ISEA7H', 5)
|
|
96
90
|
print(gdf4.head())
|
|
97
91
|
gdf4.to_file('polycells_from_points_isea7h_5.shp')
|
|
@@ -102,7 +96,7 @@ print(gdf5.head())
|
|
|
102
96
|
gdf5.to_file('geopoint_cellids_from_points_isea4h_8.shp')
|
|
103
97
|
|
|
104
98
|
# generate DGGS grid cell polygons based on 'cell_id_list' (a list or np.array of provided cell_ids)
|
|
105
|
-
gdf6 = dggrid_instance.grid_cell_polygons_from_cellids(cell_id_list=[1, 4, 8], 'ISEA7H', 5)
|
|
99
|
+
gdf6 = dggrid_instance.grid_cell_polygons_from_cellids(cell_id_list=[1, 4, 8], dggs_type='ISEA7H', resolution=5)
|
|
106
100
|
print(gdf6.head())
|
|
107
101
|
gdf6.to_file('from_seqnums_isea7h_5.shp')
|
|
108
102
|
|
|
@@ -110,7 +104,7 @@ gdf6.to_file('from_seqnums_isea7h_5.shp')
|
|
|
110
104
|
gdf7 = dggrid_instance.grid_cell_polygons_for_extent('ISEA7H', 3, split_dateline=True)
|
|
111
105
|
gdf7.to_file('global_isea7h_3_interrupted.shp')
|
|
112
106
|
|
|
113
|
-
gdf_z1 = dggrid_instance.grid_cell_polygons_for_extent('IGEO7', 5, clip_geom=
|
|
107
|
+
gdf_z1 = dggrid_instance.grid_cell_polygons_for_extent('IGEO7', 5, clip_geom=clip_bound, output_address_type='Z7_STRING')
|
|
114
108
|
print(gdf_z1.head(3))
|
|
115
109
|
|
|
116
110
|
df_z1 = dggrid_instance.guess_zstr_resolution(gdf_z1['name'].values, 'IGEO7', input_address_type='Z7_STRING')
|
|
@@ -131,7 +125,7 @@ if you don't have a special local distribution of the dggrid-tool or if you didn
|
|
|
131
125
|
|
|
132
126
|
```python
|
|
133
127
|
|
|
134
|
-
from dggrid4py import tool
|
|
128
|
+
from dggrid4py import DGGRIDv7, tool
|
|
135
129
|
|
|
136
130
|
dggrid_exec = tool.get_portable_executable(".")
|
|
137
131
|
dggrid_instance_portable = DGGRIDv7(executable=dggrid_exec, working_dir='.', capture_logs=False, silent=True, has_gdal=False, tmp_geo_out_legacy=True, debug=False)
|
|
@@ -163,4 +157,3 @@ working on an updated conda package. Currently DGGRID v8.3 is available on conda
|
|
|
163
157
|
|
|
164
158
|
Some reading to be excited about: [discourse.pangeo.io](https://discourse.pangeo.io/t/discrete-global-grid-systems-dggs-use-with-pangeo/2274)
|
|
165
159
|
|
|
166
|
-
|
|
@@ -11,15 +11,15 @@ GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
11
11
|
- [DGGRID Version 8.3 on GitHub](https://github.com/sahrk/DGGRID)
|
|
12
12
|
- [DGGRID User Manual](https://github.com/sahrk/DGGRID/blob/d08e10d761f7bedd72a253ab1057458f339de51e/dggridManualV81b.pdf)
|
|
13
13
|
|
|
14
|
-
You need the
|
|
14
|
+
You need the `dggrid` tool compiled available on the system.
|
|
15
15
|
|
|
16
|
-
Besides some
|
|
16
|
+
Besides some low-level access influence the dggrid operations' metafile creation, a few high-level functions are integrated to work with the more comfortable geopython libraries, like shapely and geopandas
|
|
17
17
|
|
|
18
18
|
- grid_cell_polygons_for_extent(): fill extent/subset with cells at resolution (clip or world)
|
|
19
19
|
- grid_cell_polygons_from_cellids(): geometry_from_cellid for dggs at resolution (from id list)
|
|
20
20
|
- grid_cellids_for_extent(): get_all_indexes/cell_ids for dggs at resolution (clip or world)
|
|
21
21
|
- cells_for_geo_points(): poly_outline for point/centre at resolution
|
|
22
|
-
- address_transform(): conversion
|
|
22
|
+
- address_transform(): conversion between cell_id address types, like SEQNUM, Z7, or Q2DI
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
```python
|
|
@@ -29,7 +29,7 @@ import shapely
|
|
|
29
29
|
from dggrid4py import DGGRIDv7
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
# create an
|
|
32
|
+
# create an initial instance that knows where the dggrid tool lives, configure temp workspace and log/stdout output
|
|
33
33
|
# if you have
|
|
34
34
|
dggrid_instance = DGGRIDv7(executable='<path_to>/dggrid', working_dir='.', capture_logs=False, silent=False, tmp_geo_out_legacy=False, debug=False)
|
|
35
35
|
|
|
@@ -42,10 +42,10 @@ gdf1.to_file('isea4t_5.shp')
|
|
|
42
42
|
gdf_centroids = dggrid_instance.grid_cell_centroids_for_extent(dggs_type='ISEA7H', resolution=4, mixed_aperture_level=None, clip_geom=None)
|
|
43
43
|
|
|
44
44
|
# clip extent
|
|
45
|
-
clip_bound = shapely.geometry.box(20.2,57.00, 28.4,60.0
|
|
45
|
+
clip_bound = shapely.geometry.box(20.2,57.00, 28.4,60.0)
|
|
46
46
|
|
|
47
47
|
# ISEA7H grid at resolution 9, for extent of provided WGS84 rectangle into GeoDataFrame to Shapefile
|
|
48
|
-
gdf3 = dggrid_instance.grid_cell_polygons_for_extent('ISEA7H', 9, clip_geom=
|
|
48
|
+
gdf3 = dggrid_instance.grid_cell_polygons_for_extent('ISEA7H', 9, clip_geom=clip_bound)
|
|
49
49
|
print(gdf3.head())
|
|
50
50
|
gdf3.to_file('grids/est_shape_isea7h_9.shp')
|
|
51
51
|
|
|
@@ -55,6 +55,8 @@ print(df1.head(8))
|
|
|
55
55
|
df1.to_csv('isea7h_8_stats.csv', index=False)
|
|
56
56
|
|
|
57
57
|
# generate the DGGS grid cells that would cover a GeoDataFrame of points, return Polygons with cell IDs as GeoDataFrame
|
|
58
|
+
points = [shapely.Point(20.5, 57.5), shapely.Point(21.0, 58.0)]
|
|
59
|
+
geodf_points_wgs84 = geopandas.GeoDataFrame({'name': ['A', 'B']}, geometry=points, crs='EPSG:4326')
|
|
58
60
|
gdf4 = dggrid_instance.cells_for_geo_points(geodf_points_wgs84, False, 'ISEA7H', 5)
|
|
59
61
|
print(gdf4.head())
|
|
60
62
|
gdf4.to_file('polycells_from_points_isea7h_5.shp')
|
|
@@ -65,7 +67,7 @@ print(gdf5.head())
|
|
|
65
67
|
gdf5.to_file('geopoint_cellids_from_points_isea4h_8.shp')
|
|
66
68
|
|
|
67
69
|
# generate DGGS grid cell polygons based on 'cell_id_list' (a list or np.array of provided cell_ids)
|
|
68
|
-
gdf6 = dggrid_instance.grid_cell_polygons_from_cellids(cell_id_list=[1, 4, 8], 'ISEA7H', 5)
|
|
70
|
+
gdf6 = dggrid_instance.grid_cell_polygons_from_cellids(cell_id_list=[1, 4, 8], dggs_type='ISEA7H', resolution=5)
|
|
69
71
|
print(gdf6.head())
|
|
70
72
|
gdf6.to_file('from_seqnums_isea7h_5.shp')
|
|
71
73
|
|
|
@@ -73,7 +75,7 @@ gdf6.to_file('from_seqnums_isea7h_5.shp')
|
|
|
73
75
|
gdf7 = dggrid_instance.grid_cell_polygons_for_extent('ISEA7H', 3, split_dateline=True)
|
|
74
76
|
gdf7.to_file('global_isea7h_3_interrupted.shp')
|
|
75
77
|
|
|
76
|
-
gdf_z1 = dggrid_instance.grid_cell_polygons_for_extent('IGEO7', 5, clip_geom=
|
|
78
|
+
gdf_z1 = dggrid_instance.grid_cell_polygons_for_extent('IGEO7', 5, clip_geom=clip_bound, output_address_type='Z7_STRING')
|
|
77
79
|
print(gdf_z1.head(3))
|
|
78
80
|
|
|
79
81
|
df_z1 = dggrid_instance.guess_zstr_resolution(gdf_z1['name'].values, 'IGEO7', input_address_type='Z7_STRING')
|
|
@@ -94,7 +96,7 @@ if you don't have a special local distribution of the dggrid-tool or if you didn
|
|
|
94
96
|
|
|
95
97
|
```python
|
|
96
98
|
|
|
97
|
-
from dggrid4py import tool
|
|
99
|
+
from dggrid4py import DGGRIDv7, tool
|
|
98
100
|
|
|
99
101
|
dggrid_exec = tool.get_portable_executable(".")
|
|
100
102
|
dggrid_instance_portable = DGGRIDv7(executable=dggrid_exec, working_dir='.', capture_logs=False, silent=True, has_gdal=False, tmp_geo_out_legacy=True, debug=False)
|
|
@@ -125,4 +127,3 @@ working on an updated conda package. Currently DGGRID v8.3 is available on conda
|
|
|
125
127
|
## greater context DGGS in Earth Sciences and GIS
|
|
126
128
|
|
|
127
129
|
Some reading to be excited about: [discourse.pangeo.io](https://discourse.pangeo.io/t/discrete-global-grid-systems-dggs-use-with-pangeo/2274)
|
|
128
|
-
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
# Date: 07-12-2022
|
|
9
9
|
#
|
|
10
10
|
|
|
11
|
-
from .dggrid_runner import DGGRIDv7, Dggs, dgselect, dggs_types
|
|
11
|
+
from .dggrid_runner import DGGRIDv7, DGGRIDv8, Dggs, dgselect, dggs_types
|
|
12
12
|
import dggrid4py.igeo7 as igeo7
|
|
13
13
|
import dggrid4py.tool as tool
|
|
14
|
+
from .auxlat import geoseries_to_authalic, geoseries_to_geodetic, geodetic_to_authalic, authalic_to_geodetic
|
|
14
15
|
|
|
15
|
-
__version__ = "0.
|
|
16
|
+
__version__ = "0.5.1-dev"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from pygeodesy.ellipsoids import Ellipsoids
|
|
2
|
+
from shapely.geometry import Point, Polygon
|
|
3
|
+
|
|
4
|
+
wgs84 = Ellipsoids.WGS84
|
|
5
|
+
|
|
6
|
+
def authalic_to_geodetic(lat_authalic):
|
|
7
|
+
return wgs84.auxAuthalic(lat_authalic, inverse=True)
|
|
8
|
+
|
|
9
|
+
def geodetic_to_authalic(lat_geodetic):
|
|
10
|
+
return wgs84.auxAuthalic(lat_geodetic, inverse=False)
|
|
11
|
+
|
|
12
|
+
def _apply_to_simple_shapely_polygon(polygon, func):
|
|
13
|
+
# cannot be a complex polygon, e.g. with holes, just a simple one like the hexagons or bbox
|
|
14
|
+
# multigeometries should be treated separately
|
|
15
|
+
# it is assumed that coordinates are in lat/lon (either on authalic sphere or ellipsoid/wgs84)
|
|
16
|
+
return Polygon([ (lon, func(lat)) for (lon, lat) in polygon.exterior.coords])
|
|
17
|
+
|
|
18
|
+
def _apply_to_shapely_point(point, func):
|
|
19
|
+
# points is a list of shapely Point objects
|
|
20
|
+
return Point(point.x, func(point.y))
|
|
21
|
+
|
|
22
|
+
def _apply_to_shapely_points(points, func):
|
|
23
|
+
# points is a list of shapely Point objects
|
|
24
|
+
return [ Point(point.x, func(point.y)) for point in points]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def geoseries_to_authalic(geoseries):
|
|
28
|
+
# geoseries is a geopandas GeoSeries of shapely geometries
|
|
29
|
+
return geoseries.apply(lambda geom: geom if geom.is_empty else
|
|
30
|
+
(_apply_to_shapely_point(geom, geodetic_to_authalic) if isinstance(geom, Point) else
|
|
31
|
+
_apply_to_simple_shapely_polygon(geom, geodetic_to_authalic)))
|
|
32
|
+
|
|
33
|
+
def geoseries_to_geodetic(geoseries):
|
|
34
|
+
# geoseries is a geopandas GeoSeries of shapely geometries
|
|
35
|
+
return geoseries.apply(lambda geom: geom if geom.is_empty else
|
|
36
|
+
(_apply_to_shapely_point(geom, authalic_to_geodetic) if isinstance(geom, Point) else
|
|
37
|
+
_apply_to_simple_shapely_polygon(geom, authalic_to_geodetic)))
|