vector2dggs 0.10.1__py3-none-any.whl → 0.11.0__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.
- vector2dggs/__init__.py +1 -1
- vector2dggs/common.py +85 -33
- vector2dggs/constants.py +80 -14
- vector2dggs/geohash.py +3 -5
- vector2dggs/h3.py +3 -5
- vector2dggs/katana.py +7 -4
- vector2dggs/rHP.py +4 -6
- vector2dggs/s2.py +5 -5
- {vector2dggs-0.10.1.dist-info → vector2dggs-0.11.0.dist-info}/METADATA +27 -12
- vector2dggs-0.11.0.dist-info/RECORD +15 -0
- {vector2dggs-0.10.1.dist-info → vector2dggs-0.11.0.dist-info}/WHEEL +1 -1
- vector2dggs-0.10.1.dist-info/RECORD +0 -15
- {vector2dggs-0.10.1.dist-info → vector2dggs-0.11.0.dist-info}/COPYING +0 -0
- {vector2dggs-0.10.1.dist-info → vector2dggs-0.11.0.dist-info}/COPYING.LESSER +0 -0
- {vector2dggs-0.10.1.dist-info → vector2dggs-0.11.0.dist-info}/entry_points.txt +0 -0
vector2dggs/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__: str = "0.
|
|
1
|
+
__version__: str = "0.11.0"
|
vector2dggs/common.py
CHANGED
|
@@ -18,7 +18,7 @@ from pathlib import Path, PurePath
|
|
|
18
18
|
from urllib.parse import urlparse
|
|
19
19
|
from tqdm import tqdm
|
|
20
20
|
from tqdm.dask import TqdmCallback
|
|
21
|
-
from
|
|
21
|
+
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed
|
|
22
22
|
from shapely.geometry import GeometryCollection
|
|
23
23
|
|
|
24
24
|
import vector2dggs.constants as const
|
|
@@ -313,6 +313,47 @@ def polyfill(
|
|
|
313
313
|
def polyfill_star(args) -> None:
|
|
314
314
|
return polyfill(*args)
|
|
315
315
|
|
|
316
|
+
def bisection_preparation(df: pd.DataFrame, dggs: str, parent_res: int, cut_crs: pyproj.CRS = None, cut_threshold: Union[None, float] = None) -> tuple[pd.DataFrame, pyproj.CRS, Union[None, float]]:
|
|
317
|
+
cut_threshold = float(cut_threshold) if cut_threshold != None else None
|
|
318
|
+
|
|
319
|
+
if cut_threshold and cut_crs:
|
|
320
|
+
df = df.to_crs(cut_crs)
|
|
321
|
+
else:
|
|
322
|
+
cut_crs = df.crs
|
|
323
|
+
|
|
324
|
+
if cut_crs is None:
|
|
325
|
+
LOGGER.warning("Input has no defined CRS, and cut_crs is not specified")
|
|
326
|
+
elif cut_threshold != 0:
|
|
327
|
+
LOGGER.debug("Cutting with CRS: %s", df.crs)
|
|
328
|
+
|
|
329
|
+
if not cut_crs.is_projected and cut_threshold != 0:
|
|
330
|
+
LOGGER.warning(
|
|
331
|
+
f"CRS {cut_crs} is not a projected coordinate system. (units: {cut_crs.axis_info[0].unit_name}) Bisection will result in sections of varying area"
|
|
332
|
+
)
|
|
333
|
+
elif cut_threshold != 0:
|
|
334
|
+
LOGGER.debug(
|
|
335
|
+
f"Using CRS units for input polygon bisection: {cut_crs.axis_info[0].unit_name}"
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
if cut_threshold == None:
|
|
339
|
+
unit_name = cut_crs.axis_info[0].unit_name
|
|
340
|
+
cut_threshold_m2 = const.DEFAULT_AREA_THRESHOLD_M2(dggs, (int(parent_res)))
|
|
341
|
+
if unit_name == "metre":
|
|
342
|
+
cut_threshold = cut_threshold_m2
|
|
343
|
+
elif unit_name == "feet":
|
|
344
|
+
cut_threshold = cut_threshold_m2 * 3.28084
|
|
345
|
+
else:
|
|
346
|
+
cut_threshold = 100000000 if cut_crs.is_projected else 0.5
|
|
347
|
+
LOGGER.warning(
|
|
348
|
+
f'Unspecified cut_threshold for {"projected" if cut_crs.is_projected else "geographic"} CRS: {cut_crs}, with squared units: {unit_name}'
|
|
349
|
+
)
|
|
350
|
+
LOGGER.debug(f"Using default cut_threshold of {cut_threshold} ({unit_name}^2)")
|
|
351
|
+
|
|
352
|
+
return df, cut_crs, cut_threshold
|
|
353
|
+
|
|
354
|
+
def bisect_geometry(geometry, cut_threshold):
|
|
355
|
+
return GeometryCollection(katana.katana(geometry, cut_threshold))
|
|
356
|
+
|
|
316
357
|
|
|
317
358
|
def index(
|
|
318
359
|
dggs: str,
|
|
@@ -326,7 +367,7 @@ def index(
|
|
|
326
367
|
keep_attributes: bool,
|
|
327
368
|
chunksize: int,
|
|
328
369
|
spatial_sorting: str,
|
|
329
|
-
cut_threshold:
|
|
370
|
+
cut_threshold: Union[None, float],
|
|
330
371
|
processes: int,
|
|
331
372
|
compression: str = "snappy",
|
|
332
373
|
id_field: str = None,
|
|
@@ -356,9 +397,7 @@ def index(
|
|
|
356
397
|
# Read file
|
|
357
398
|
df = gpd.read_file(input_file, layer=layer)
|
|
358
399
|
|
|
359
|
-
|
|
360
|
-
df = df.to_crs(cut_crs)
|
|
361
|
-
LOGGER.debug("Cutting with CRS: %s", df.crs)
|
|
400
|
+
df, cut_crs, cut_threshold = bisection_preparation(df, dggs, parent_res, cut_crs, cut_threshold)
|
|
362
401
|
|
|
363
402
|
if id_field:
|
|
364
403
|
df = df.set_index(id_field)
|
|
@@ -370,13 +409,21 @@ def index(
|
|
|
370
409
|
# Remove all attributes except the geometry
|
|
371
410
|
df = df.loc[:, ["geometry"]]
|
|
372
411
|
|
|
373
|
-
LOGGER.debug("
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
)
|
|
379
|
-
|
|
412
|
+
LOGGER.debug("Bisecting large geometries")
|
|
413
|
+
|
|
414
|
+
if cut_threshold is not None and cut_threshold > 0:
|
|
415
|
+
with ThreadPoolExecutor(max_workers=max(1, processes)) as executor:
|
|
416
|
+
futures = []
|
|
417
|
+
for index, row in df.iterrows():
|
|
418
|
+
future = executor.submit(bisect_geometry, row.geometry, cut_threshold)
|
|
419
|
+
futures.append((index, future))
|
|
420
|
+
|
|
421
|
+
with tqdm(total=len(futures), desc="Bisection") as pbar:
|
|
422
|
+
for index, future in futures:
|
|
423
|
+
df.at[index, "geometry"] = future.result()
|
|
424
|
+
pbar.update(1)
|
|
425
|
+
else:
|
|
426
|
+
LOGGER.debug("No bisection applied to input.")
|
|
380
427
|
|
|
381
428
|
LOGGER.debug("Exploding geometry collections and multipolygons")
|
|
382
429
|
df = (
|
|
@@ -427,28 +474,33 @@ def index(
|
|
|
427
474
|
resolution,
|
|
428
475
|
)
|
|
429
476
|
with tempfile.TemporaryDirectory(suffix=".parquet") as tmpdir2:
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
)
|
|
443
|
-
for filepath in filepaths
|
|
444
|
-
]
|
|
445
|
-
list(
|
|
446
|
-
tqdm(
|
|
447
|
-
pool.imap(polyfill_star, args),
|
|
448
|
-
total=len(args),
|
|
449
|
-
desc="DGGS indexing",
|
|
450
|
-
)
|
|
477
|
+
|
|
478
|
+
args = [
|
|
479
|
+
(
|
|
480
|
+
dggs,
|
|
481
|
+
dggsfunc,
|
|
482
|
+
secondary_index_func,
|
|
483
|
+
filepath,
|
|
484
|
+
spatial_sort_col,
|
|
485
|
+
resolution,
|
|
486
|
+
parent_res,
|
|
487
|
+
tmpdir2,
|
|
488
|
+
compression,
|
|
451
489
|
)
|
|
490
|
+
for filepath in filepaths
|
|
491
|
+
]
|
|
492
|
+
|
|
493
|
+
with ProcessPoolExecutor(max_workers=processes) as executor:
|
|
494
|
+
futures = {executor.submit(polyfill_star, arg): arg for arg in args}
|
|
495
|
+
|
|
496
|
+
for future in tqdm(
|
|
497
|
+
as_completed(futures), total=len(futures), desc="DGGS indexing"
|
|
498
|
+
):
|
|
499
|
+
try:
|
|
500
|
+
future.result()
|
|
501
|
+
except Exception as e:
|
|
502
|
+
LOGGER.error(f"Task failed with {e}")
|
|
503
|
+
raise (e)
|
|
452
504
|
|
|
453
505
|
parent_partitioning(
|
|
454
506
|
dggs,
|
vector2dggs/constants.py
CHANGED
|
@@ -8,20 +8,6 @@ MIN_RHP, MAX_RHP = 0, 15
|
|
|
8
8
|
MIN_S2, MAX_S2 = 0, 30
|
|
9
9
|
MIN_GEOHASH, MAX_GEOHASH = 1, 12
|
|
10
10
|
|
|
11
|
-
DEFAULTS = {
|
|
12
|
-
"id": None,
|
|
13
|
-
"k": False,
|
|
14
|
-
"ch": 50,
|
|
15
|
-
"s": "none",
|
|
16
|
-
"crs": None,
|
|
17
|
-
"c": 5000,
|
|
18
|
-
"t": (multiprocessing.cpu_count() - 1),
|
|
19
|
-
"cp": "snappy",
|
|
20
|
-
"lyr": None,
|
|
21
|
-
"g": "geom",
|
|
22
|
-
"tempdir": tempfile.tempdir,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
11
|
SPATIAL_SORTING_METHODS = ["hilbert", "morton", "geohash", "none"]
|
|
26
12
|
|
|
27
13
|
DEFAULT_DGGS_PARENT_RES = {
|
|
@@ -70,6 +56,86 @@ S2_CELLS_MAX_AREA_M2_BY_LEVEL = {
|
|
|
70
56
|
30: 0.93 * 1e-4,
|
|
71
57
|
}
|
|
72
58
|
|
|
59
|
+
# https://h3geo.org/docs/core-library/restable/
|
|
60
|
+
H3_CELLS_MAX_AREA_KM2_BY_LEVEL = {
|
|
61
|
+
0: 4977807.027442012,
|
|
62
|
+
1: 729486.875275344,
|
|
63
|
+
2: 104599.807218925,
|
|
64
|
+
3: 14950.773301379,
|
|
65
|
+
4: 2135.986983965,
|
|
66
|
+
5: 305.144308779,
|
|
67
|
+
6: 43.592111685,
|
|
68
|
+
7: 6.227445905,
|
|
69
|
+
8: 0.889635157,
|
|
70
|
+
9: 0.127090737,
|
|
71
|
+
10: 0.018155820,
|
|
72
|
+
11: 0.002593689,
|
|
73
|
+
12: 0.000370527,
|
|
74
|
+
13: 0.000052932,
|
|
75
|
+
14: 0.000007562,
|
|
76
|
+
15: 0.000001080,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
RHP_CELLS_AREA_KM2_BY_LEVEL = {
|
|
80
|
+
0: 100151150.62856922,
|
|
81
|
+
1: 11127905.62539658,
|
|
82
|
+
2: 1236433.9583773974,
|
|
83
|
+
3: 137381.55093082195,
|
|
84
|
+
4: 15264.616770091328,
|
|
85
|
+
5: 1696.0685300101482,
|
|
86
|
+
6: 188.4520588900164,
|
|
87
|
+
7: 20.939117654446267,
|
|
88
|
+
8: 2.326568628271808,
|
|
89
|
+
9: 0.25850762536353417,
|
|
90
|
+
10: 0.02872306948483713,
|
|
91
|
+
11: 0.003191452164981904,
|
|
92
|
+
12: 0.0003546057961091004,
|
|
93
|
+
13: 3.940064401212227 * 1e-5,
|
|
94
|
+
14: 4.377849334680252 * 1e-6,
|
|
95
|
+
15: 4.864277038533613 * 1e-7,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# https://www.movable-type.co.uk/scripts/geohash.html
|
|
99
|
+
GEOHASH_MAX_CELL_AREA_KM2_BY_LEVEL = {
|
|
100
|
+
1: 5000 * 5000,
|
|
101
|
+
2: 1250 * 625,
|
|
102
|
+
3: 156 * 156,
|
|
103
|
+
4: 39.1 * 19.5,
|
|
104
|
+
5: 4.89 * 4.89,
|
|
105
|
+
6: 1.22 * 0.61,
|
|
106
|
+
7: 153 * 153 / 1e6,
|
|
107
|
+
8: 38.2 * 19.1 / 1e6,
|
|
108
|
+
9: 4.77 * 4.77 / 1e6,
|
|
109
|
+
10: 1.19 * 0.596 / 1e6,
|
|
110
|
+
11: 149 * 149 / 1e9,
|
|
111
|
+
12: 37.2 * 18.6 / 1e9,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
DGGS_CELL_AREA_M2_BY_RES = {
|
|
115
|
+
"s2": lambda res: S2_CELLS_MAX_AREA_M2_BY_LEVEL[res],
|
|
116
|
+
"h3": lambda res: H3_CELLS_MAX_AREA_KM2_BY_LEVEL[res] * 1e6,
|
|
117
|
+
"rhp": lambda res: RHP_CELLS_AREA_KM2_BY_LEVEL[res] * 1e6,
|
|
118
|
+
"geohash": lambda res: GEOHASH_MAX_CELL_AREA_KM2_BY_LEVEL[res] * 1e6,
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
DEFAULT_AREA_THRESHOLD_M2 = lambda dggs, parent_res: DGGS_CELL_AREA_M2_BY_RES[dggs](
|
|
122
|
+
parent_res
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
DEFAULTS = {
|
|
126
|
+
"id": None,
|
|
127
|
+
"k": False,
|
|
128
|
+
"ch": 50,
|
|
129
|
+
"s": "none",
|
|
130
|
+
"crs": None,
|
|
131
|
+
"c": None,
|
|
132
|
+
"t": (multiprocessing.cpu_count() - 1),
|
|
133
|
+
"cp": "snappy",
|
|
134
|
+
"lyr": None,
|
|
135
|
+
"g": "geom",
|
|
136
|
+
"tempdir": tempfile.tempdir,
|
|
137
|
+
}
|
|
138
|
+
|
|
73
139
|
|
|
74
140
|
warnings.filterwarnings(
|
|
75
141
|
"ignore"
|
vector2dggs/geohash.py
CHANGED
|
@@ -217,10 +217,10 @@ def gh_compaction(
|
|
|
217
217
|
@click.option(
|
|
218
218
|
"-c",
|
|
219
219
|
"--cut_threshold",
|
|
220
|
-
required=
|
|
220
|
+
required=False,
|
|
221
221
|
default=const.DEFAULTS["c"],
|
|
222
|
-
type=
|
|
223
|
-
help="Cutting up large geometries into smaller geometries based on a target
|
|
222
|
+
type=float,
|
|
223
|
+
help="Cutting up large geometries into smaller geometries based on a target area. Units are assumed to match the input CRS units unless the `--cut_crs` is also given, in which case units match the units of the supplied CRS. If left unspecified, the threshold will be the maximum area of a cell at the parent resolution, in square metres or feet according to the CRS. A threshold of 0 will skip bissection entirely (effectively ignoring --cut_crs).",
|
|
224
224
|
nargs=1,
|
|
225
225
|
)
|
|
226
226
|
@click.option(
|
|
@@ -333,5 +333,3 @@ def geohash(
|
|
|
333
333
|
)
|
|
334
334
|
except:
|
|
335
335
|
raise
|
|
336
|
-
else:
|
|
337
|
-
sys.exit(0)
|
vector2dggs/h3.py
CHANGED
|
@@ -136,10 +136,10 @@ def h3compaction(
|
|
|
136
136
|
@click.option(
|
|
137
137
|
"-c",
|
|
138
138
|
"--cut_threshold",
|
|
139
|
-
required=
|
|
139
|
+
required=False,
|
|
140
140
|
default=const.DEFAULTS["c"],
|
|
141
|
-
type=
|
|
142
|
-
help="Cutting up large geometries into smaller geometries based on a target
|
|
141
|
+
type=float,
|
|
142
|
+
help="Cutting up large geometries into smaller geometries based on a target area. Units are assumed to match the input CRS units unless the `--cut_crs` is also given, in which case units match the units of the supplied CRS. If left unspecified, the threshold will be the maximum area of a cell at the parent resolution, in square metres or feet according to the CRS. A threshold of 0 will skip bissection entirely (effectively ignoring --cut_crs).",
|
|
143
143
|
nargs=1,
|
|
144
144
|
)
|
|
145
145
|
@click.option(
|
|
@@ -253,5 +253,3 @@ def h3(
|
|
|
253
253
|
)
|
|
254
254
|
except:
|
|
255
255
|
raise
|
|
256
|
-
else:
|
|
257
|
-
sys.exit(0)
|
vector2dggs/katana.py
CHANGED
|
@@ -30,14 +30,17 @@ def katana(
|
|
|
30
30
|
geometry: Union[BaseGeometry, None],
|
|
31
31
|
threshold: float,
|
|
32
32
|
count: int = 0,
|
|
33
|
+
max_recursion_depth: int = 250,
|
|
33
34
|
check_2D: bool = True,
|
|
34
35
|
) -> List[BaseGeometry]:
|
|
35
36
|
"""
|
|
36
37
|
Recursively split a geometry into two parts across its shortest dimension.
|
|
37
38
|
Invalid input `geometry` will silently be made valid (if possible).
|
|
38
39
|
Any LinearRings will be converted to Polygons.
|
|
40
|
+
`threshold`: maximum acceptable area of the bounding box for any output geometry.
|
|
41
|
+
`count`: used to track recursion depth
|
|
39
42
|
"""
|
|
40
|
-
if geometry is None:
|
|
43
|
+
if (geometry is None) or (geometry.is_empty):
|
|
41
44
|
return []
|
|
42
45
|
if isinstance(geometry, LinearRing):
|
|
43
46
|
geometry = Polygon(geometry)
|
|
@@ -52,9 +55,7 @@ def katana(
|
|
|
52
55
|
bounds = geometry.bounds
|
|
53
56
|
width = bounds[2] - bounds[0]
|
|
54
57
|
height = bounds[3] - bounds[1]
|
|
55
|
-
if
|
|
56
|
-
# either the polygon is smaller than the threshold, or the maximum
|
|
57
|
-
# number of recursions has been reached
|
|
58
|
+
if ((width * height) <= threshold) or (count >= max_recursion_depth):
|
|
58
59
|
return [geometry]
|
|
59
60
|
if height >= width:
|
|
60
61
|
# split left to right
|
|
@@ -64,6 +65,8 @@ def katana(
|
|
|
64
65
|
# split top to bottom
|
|
65
66
|
a = box(bounds[0], bounds[1], bounds[0] + width / 2, bounds[3])
|
|
66
67
|
b = box(bounds[0] + width / 2, bounds[1], bounds[2], bounds[3])
|
|
68
|
+
# Add additional vertices to help prevent indexing errors from use of EPSG:4386 later under the presence of long edges
|
|
69
|
+
a, b = map(lambda g: g.segmentize(min(width, height) / 4), [a, b])
|
|
67
70
|
result = []
|
|
68
71
|
for d in (
|
|
69
72
|
a,
|
vector2dggs/rHP.py
CHANGED
|
@@ -153,17 +153,17 @@ def rhpcompaction(
|
|
|
153
153
|
@click.option(
|
|
154
154
|
"-c",
|
|
155
155
|
"--cut_threshold",
|
|
156
|
-
required=
|
|
156
|
+
required=False,
|
|
157
157
|
default=const.DEFAULTS["c"],
|
|
158
|
-
type=
|
|
159
|
-
help="Cutting up large geometries into smaller geometries based on a target
|
|
158
|
+
type=float,
|
|
159
|
+
help="Cutting up large geometries into smaller geometries based on a target area. Units are assumed to match the input CRS units unless the `--cut_crs` is also given, in which case units match the units of the supplied CRS. If left unspecified, the threshold will be the maximum area of a cell at the parent resolution, in square metres or feet according to the CRS. A threshold of 0 will skip bissection entirely (effectively ignoring --cut_crs).",
|
|
160
160
|
nargs=1,
|
|
161
161
|
)
|
|
162
162
|
@click.option(
|
|
163
163
|
"-t",
|
|
164
164
|
"--threads",
|
|
165
165
|
required=False,
|
|
166
|
-
default=
|
|
166
|
+
default=1,
|
|
167
167
|
type=int,
|
|
168
168
|
help="Amount of threads used for operation",
|
|
169
169
|
nargs=1,
|
|
@@ -270,5 +270,3 @@ def rhp(
|
|
|
270
270
|
)
|
|
271
271
|
except:
|
|
272
272
|
raise
|
|
273
|
-
else:
|
|
274
|
-
sys.exit(0)
|
vector2dggs/s2.py
CHANGED
|
@@ -9,6 +9,7 @@ from s2geometry import pywraps2 as S2
|
|
|
9
9
|
|
|
10
10
|
import pandas as pd
|
|
11
11
|
import geopandas as gpd
|
|
12
|
+
from shapely import force_2d
|
|
12
13
|
from shapely.geometry import box, Polygon, LineString, Point
|
|
13
14
|
from shapely.ops import transform
|
|
14
15
|
from pyproj import CRS, Transformer
|
|
@@ -71,6 +72,7 @@ def s2_polyfill_polygons(df: gpd.GeoDataFrame, level: int) -> gpd.GeoDataFrame:
|
|
|
71
72
|
def generate_s2_covering(
|
|
72
73
|
geom: Polygon, level: int, centroid_inside: bool = True
|
|
73
74
|
) -> set[S2.S2CellId]:
|
|
75
|
+
geom = force_2d(geom)
|
|
74
76
|
# Prepare loops: first the exterior loop, then the interior loops
|
|
75
77
|
loops = []
|
|
76
78
|
# Exterior ring
|
|
@@ -296,10 +298,10 @@ def s2_compaction(
|
|
|
296
298
|
@click.option(
|
|
297
299
|
"-c",
|
|
298
300
|
"--cut_threshold",
|
|
299
|
-
required=
|
|
301
|
+
required=False,
|
|
300
302
|
default=const.DEFAULTS["c"],
|
|
301
|
-
type=
|
|
302
|
-
help="Cutting up large geometries into smaller geometries based on a target
|
|
303
|
+
type=float,
|
|
304
|
+
help="Cutting up large geometries into smaller geometries based on a target area. Units are assumed to match the input CRS units unless the `--cut_crs` is also given, in which case units match the units of the supplied CRS. If left unspecified, the threshold will be the maximum area of a cell at the parent resolution, in square metres or feet according to the CRS. A threshold of 0 will skip bissection entirely (effectively ignoring --cut_crs).",
|
|
303
305
|
nargs=1,
|
|
304
306
|
)
|
|
305
307
|
@click.option(
|
|
@@ -412,5 +414,3 @@ def s2(
|
|
|
412
414
|
)
|
|
413
415
|
except:
|
|
414
416
|
raise
|
|
415
|
-
else:
|
|
416
|
-
sys.exit(0)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: vector2dggs
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: CLI DGGS indexer for vector geospatial data
|
|
5
|
+
Home-page: https://github.com/manaakiwhenua/vector2dggs
|
|
5
6
|
License: LGPL-3.0-or-later
|
|
6
7
|
Keywords: dggs,vector,h3,rHEALPix,cli
|
|
7
8
|
Author: James Ardo
|
|
@@ -12,8 +13,6 @@ Requires-Python: >=3.11,<4.0
|
|
|
12
13
|
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
|
|
13
14
|
Classifier: Programming Language :: Python :: 3
|
|
14
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
17
16
|
Classifier: Topic :: Scientific/Engineering
|
|
18
17
|
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
19
18
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
@@ -122,12 +121,17 @@ Options:
|
|
|
122
121
|
used for cutting large geometries (see
|
|
123
122
|
`--cut_threshold`). Defaults to the same CRS
|
|
124
123
|
as the input. Should be a valid EPSG code.
|
|
125
|
-
-c, --cut_threshold
|
|
126
|
-
geometries based on a target
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
-c, --cut_threshold FLOAT Cutting up large geometries into smaller
|
|
125
|
+
geometries based on a target area. Units are
|
|
126
|
+
assumed to match the input CRS units unless
|
|
127
|
+
the `--cut_crs` is also given, in which case
|
|
128
|
+
units match the units of the supplied CRS.
|
|
129
|
+
If left unspecified, the threshold will be
|
|
130
|
+
the maximum area of a cell at the parent
|
|
131
|
+
resolution, in square metres or feet
|
|
132
|
+
according to the CRS. A threshold of 0 will
|
|
133
|
+
skip bissection entirely (effectively
|
|
134
|
+
ignoring --cut_crs).
|
|
131
135
|
-t, --threads INTEGER Amount of threads used for operation
|
|
132
136
|
[default: NUM_CPUS - 1]
|
|
133
137
|
-cp, --compression TEXT Compression method to use for the output
|
|
@@ -240,6 +244,17 @@ Alternatively, it is also possible to install using pip with `pip install -e .`,
|
|
|
240
244
|
|
|
241
245
|
Please run `black .` before committing.
|
|
242
246
|
|
|
247
|
+
#### Tests
|
|
248
|
+
|
|
249
|
+
Tests are included. To run them, set up a poetry environment, then follow these instructons:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
cd tests
|
|
253
|
+
python ./test_vector2dggs.py
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Test data are included at `tests/data/`.
|
|
257
|
+
|
|
243
258
|
## Example commands
|
|
244
259
|
|
|
245
260
|
With a local GPKG:
|
|
@@ -262,14 +277,14 @@ vector2dggs h3 -v DEBUG -id ogc_fid -r 9 -p 5 -t 4 --overwrite -lyr topo50_lake
|
|
|
262
277
|
title={{vector2dggs}},
|
|
263
278
|
author={Ardo, James and Law, Richard},
|
|
264
279
|
url={https://github.com/manaakiwhenua/vector2dggs},
|
|
265
|
-
version={0.
|
|
280
|
+
version={0.11.0},
|
|
266
281
|
date={2023-04-20}
|
|
267
282
|
}
|
|
268
283
|
```
|
|
269
284
|
|
|
270
285
|
APA/Harvard
|
|
271
286
|
|
|
272
|
-
> Ardo, J., & Law, R. (2023). vector2dggs (0.
|
|
287
|
+
> Ardo, J., & Law, R. (2023). vector2dggs (0.11.0) [Computer software]. https://github.com/manaakiwhenua/vector2dggs
|
|
273
288
|
|
|
274
289
|
[](https://github.com/manaakiwhenua/manaakiwhenua-standards)
|
|
275
290
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
vector2dggs/__init__.py,sha256=NhOfSRUl_Py_CNCpR3FsS3g_Mf4pHgA87tFPBLl3BQM,28
|
|
2
|
+
vector2dggs/cli.py,sha256=d_4skD62k6pXUWgDdVHbDwpe4A4yo62ZFx8Cp_6GpBA,767
|
|
3
|
+
vector2dggs/common.py,sha256=hHhO_BZVL8GLFpzwm9Jw5cSaIy1bNk_hs0snEcNNVjQ,16893
|
|
4
|
+
vector2dggs/constants.py,sha256=UIQoS8IsfeFR1eoIkmByq9UgoJkkqI3pbUqSNCEfFmo,3476
|
|
5
|
+
vector2dggs/geohash.py,sha256=Px4EcRJ1cFFVMHJB7zgZLZXKYXhLQObxvE_QqMYLEKw,10593
|
|
6
|
+
vector2dggs/h3.py,sha256=UnCH0m0Z9zGc_kSg5igFEz565f7Nr3aVe5Vex01WKRw,7603
|
|
7
|
+
vector2dggs/katana.py,sha256=xD8BJ5hRQZyioStIMRJ_Gt1D9x9RotqP-YrB3TKHCSM,3850
|
|
8
|
+
vector2dggs/rHP.py,sha256=KILnXvAzSinied3mLw4IURLlcK78U7xcSnKQ5afPzn4,8286
|
|
9
|
+
vector2dggs/s2.py,sha256=6i6ecnPykgGRG-ZiyUP7JjgQzPUUklMZwd-JYs4X8K8,13063
|
|
10
|
+
vector2dggs-0.11.0.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
11
|
+
vector2dggs-0.11.0.dist-info/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
12
|
+
vector2dggs-0.11.0.dist-info/METADATA,sha256=hZhgdrp7LiRGfIPbWyC3nl1ri1RtOLN9BE85CgqyCQg,13170
|
|
13
|
+
vector2dggs-0.11.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
|
14
|
+
vector2dggs-0.11.0.dist-info/entry_points.txt,sha256=5h8LB9L2oOE5u_N7FRGtu4JDwa553iPs4u0XhcLeLZU,52
|
|
15
|
+
vector2dggs-0.11.0.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
vector2dggs/__init__.py,sha256=zkryc4Uha10GTKJDVvFVRKEySO4-gejqb9sTlyYC-EE,28
|
|
2
|
-
vector2dggs/cli.py,sha256=d_4skD62k6pXUWgDdVHbDwpe4A4yo62ZFx8Cp_6GpBA,767
|
|
3
|
-
vector2dggs/common.py,sha256=rQL1_rFr1VTyILffOZgdwPzZS1JThn4TBPswfCkMjbM,14471
|
|
4
|
-
vector2dggs/constants.py,sha256=KdmBQCP_GCygzvDLtS8AMQM9i6QqOkf-9YQkh_AzrKc,1779
|
|
5
|
-
vector2dggs/geohash.py,sha256=PVLkaaSVLgzDZNfuL0y3Xioh4pyvom845HuyLIAsLUY,10398
|
|
6
|
-
vector2dggs/h3.py,sha256=Juvc8g4QWfDIco9RQHaX8p9S9rkW5QvusxpyO-G7eSs,7408
|
|
7
|
-
vector2dggs/katana.py,sha256=v4BRzVCsroC6RzIYdxLfrr9eFOdmXb5S9jXBMs5tgSo,3571
|
|
8
|
-
vector2dggs/rHP.py,sha256=UoRdidkkVGhGP85wrfBE_5BNrx1Xg5skQQe1F5X0LZ8,8109
|
|
9
|
-
vector2dggs/s2.py,sha256=SOXMHQQq86bM88MDgBBemGiXIbuEIbrhLSgPwLKceLY,12809
|
|
10
|
-
vector2dggs-0.10.1.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
11
|
-
vector2dggs-0.10.1.dist-info/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
12
|
-
vector2dggs-0.10.1.dist-info/METADATA,sha256=MNgUCPkWdxUte-n8iRQUgCFAdv_rOXp-GtPvK7vaTNU,12652
|
|
13
|
-
vector2dggs-0.10.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
14
|
-
vector2dggs-0.10.1.dist-info/entry_points.txt,sha256=5h8LB9L2oOE5u_N7FRGtu4JDwa553iPs4u0XhcLeLZU,52
|
|
15
|
-
vector2dggs-0.10.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|