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.
@@ -1,38 +1,30 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dggrid4py
3
- Version: 0.4.2
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.8,<4.0.0
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: Programming Language :: Python :: 3
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 ddgrid tool compiled available on the system.
43
+ You need the `dggrid` tool compiled available on the system.
52
44
 
53
- Besides some lowlevel access influence the dggrid operations' metafile creation, a few highlevel functions are integrated to work with the more comfortable geopython libraries, like shapely and geopandas
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 betwenn cell_id address types, like SEQNUM, Z7, or Q2DI
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 inital instance that knows where the dggrid tool lives, configure temp workspace and log/stdout output
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=est_bound)
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=est_bound, output_address_type='Z7_STRING')
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 ddgrid tool compiled available on the system.
14
+ You need the `dggrid` tool compiled available on the system.
15
15
 
16
- Besides some lowlevel access influence the dggrid operations' metafile creation, a few highlevel functions are integrated to work with the more comfortable geopython libraries, like shapely and geopandas
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 betwenn cell_id address types, like SEQNUM, Z7, or Q2DI
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 inital instance that knows where the dggrid tool lives, configure temp workspace and log/stdout output
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=est_bound)
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=est_bound, output_address_type='Z7_STRING')
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.4.2"
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)))