h3 3.4.0 → 3.4.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/ext/h3/src/.travis.yml +5 -0
- data/ext/h3/src/CHANGELOG.md +25 -0
- data/ext/h3/src/CMakeLists.txt +5 -8
- data/ext/h3/src/CONTRIBUTING.md +2 -0
- data/ext/h3/src/README.md +6 -2
- data/ext/h3/src/VERSION +1 -1
- data/ext/h3/src/appveyor.yml +6 -1
- data/ext/h3/src/docs/api/misc.md +16 -0
- data/ext/h3/src/docs/community/bindings.md +9 -0
- data/ext/h3/src/docs/community/tutorials.md +4 -0
- data/ext/h3/src/scripts/binding_functions.ps1 +1 -2
- data/ext/h3/src/scripts/binding_functions.sh +3 -2
- data/ext/h3/src/scripts/coverage.sh.in +3 -3
- data/ext/h3/src/src/apps/applib/include/utility.h +60 -0
- data/ext/h3/src/src/apps/applib/lib/utility.c +196 -2
- data/ext/h3/src/src/apps/benchmarks/benchmarkPolyfill.c +7 -4
- data/ext/h3/src/src/apps/filters/geoToH3.c +73 -27
- data/ext/h3/src/src/apps/filters/h3ToGeo.c +63 -47
- data/ext/h3/src/src/apps/filters/h3ToGeoBoundary.c +64 -48
- data/ext/h3/src/src/apps/filters/h3ToLocalIj.c +4 -5
- data/ext/h3/src/src/apps/filters/hexRange.c +0 -1
- data/ext/h3/src/src/apps/filters/kRing.c +60 -28
- data/ext/h3/src/src/apps/filters/localIjToH3.c +75 -0
- data/ext/h3/src/src/apps/miscapps/generateBaseCellNeighbors.c +2 -2
- data/ext/h3/src/src/apps/testapps/testBBox.c +18 -0
- data/ext/h3/src/src/apps/testapps/testCompact.c +41 -0
- data/ext/h3/src/src/apps/testapps/testCoordIj.c +0 -1
- data/ext/h3/src/src/apps/testapps/testCoordIjk.c +53 -0
- data/ext/h3/src/src/apps/testapps/testH3Api.c +20 -0
- data/ext/h3/src/src/apps/testapps/testH3Distance.c +5 -3
- data/ext/h3/src/src/apps/testapps/testH3Line.c +18 -6
- data/ext/h3/src/src/apps/testapps/testH3ToLocalIj.c +75 -3
- data/ext/h3/src/src/apps/testapps/testH3UniEdge.c +17 -11
- data/ext/h3/src/src/apps/testapps/testHexRanges.c +10 -0
- data/ext/h3/src/src/apps/testapps/testKRing.c +11 -7
- data/ext/h3/src/src/h3lib/lib/algos.c +2 -1
- data/ext/h3/src/src/h3lib/lib/geoCoord.c +10 -10
- data/ext/h3/src/src/h3lib/lib/h3Index.c +1 -2
- data/ext/h3/src/src/h3lib/lib/localij.c +32 -36
- data/lib/h3/version.rb +1 -1
- metadata +4 -7
- data/ext/h3/src/cmake/CheckAlloca.cmake +0 -33
- data/ext/h3/src/cmake/CheckVLA.cmake +0 -33
- data/ext/h3/src/cmake/alloca_test.c +0 -29
- data/ext/h3/src/cmake/vla_test.c +0 -26
- data/ext/h3/src/src/h3lib/include/stackAlloc.h +0 -64
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f9855fbbfa15205895e0467ef2561ec63580395d72c2cacf535c727dfca25e41
|
|
4
|
+
data.tar.gz: 2b92de2e824682fcaee25176007799203afb24180da11cac5d63d463d3649e90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '08630f598e940bd5f28f86292de45c50a84ac8bcd6965fd406b52cba745d825d8c3fcd18bf687831785a087f2a461a63c230b2a8bd599d26e2c9199c6516f4e3'
|
|
7
|
+
data.tar.gz: aa9fb82ed82cda98c56d75d89240cc556ca9568562d791aceaee5df084bb95b050c1d314a157d53a400020b25516ea86cf14f5e2ad18b56a0e74af4b67768aa9
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
We track the MAJOR and MINOR version levels of Uber's H3 project (https://github.com/uber/h3) but maintain independent patch levels so we can make small fixes and non breaking changes.
|
|
8
8
|
|
|
9
|
+
## [3.4.0] - 2019-1-24
|
|
10
|
+
### Added
|
|
11
|
+
- `res_0_indexes` and `res_0_index_count` support (#51).
|
|
12
|
+
|
|
9
13
|
## [3.3.1] - 2019-1-4
|
|
10
14
|
### Added
|
|
11
15
|
- `h3_line` and `h3_line_size` support (#43).
|
|
@@ -19,4 +23,4 @@ We track the MAJOR and MINOR version levels of Uber's H3 project (https://github
|
|
|
19
23
|
|
|
20
24
|
## [3.2.0] - 2018-12-21
|
|
21
25
|
|
|
22
|
-
Initial release.
|
|
26
|
+
Initial release.
|
data/ext/h3/src/.travis.yml
CHANGED
|
@@ -57,6 +57,11 @@ matrix:
|
|
|
57
57
|
- coveralls --lcov-file coverage.cleaned.info --verbose
|
|
58
58
|
- env: NAME="Mac OSX (Xcode 8)"
|
|
59
59
|
os: osx
|
|
60
|
+
- env: NAME="binding-functions target"
|
|
61
|
+
script:
|
|
62
|
+
- make binding-functions
|
|
63
|
+
# Check that the file exists and has contents
|
|
64
|
+
- test -s binding-functions
|
|
60
65
|
|
|
61
66
|
# Configure the build script, out of source.
|
|
62
67
|
before_script:
|
data/ext/h3/src/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,31 @@ The public API of this library consists of the functions declared in file
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.4.4] - 2019-05-30
|
|
11
|
+
### Changed
|
|
12
|
+
- Local coordinate spaces cannot cross more than one icosahedron edge. (#234)
|
|
13
|
+
- All dynamic internal memory allocations happen on the heap instead of the stack. (#235)
|
|
14
|
+
- Argument parsing for `h3ToGeo`, `geoToH3`, and `h3ToGeoBoundary` is more flexible. (#227)
|
|
15
|
+
|
|
16
|
+
## [3.4.3] - 2019-05-02
|
|
17
|
+
### Added
|
|
18
|
+
- `localIjToH3` filter application (#222)
|
|
19
|
+
- An option to print distances in the `kRing` filter application (#222)
|
|
20
|
+
### Changed
|
|
21
|
+
- Arguments parsing for `kRing` filter application is more flexible. (#224)
|
|
22
|
+
### Fixed
|
|
23
|
+
- `benchmarkPolyfill` allocates its memory on the heap (#198)
|
|
24
|
+
- Fixed constraints of vertex longitudes (#213)
|
|
25
|
+
- Zero only input to `uncompact` does not produce an error (#223)
|
|
26
|
+
|
|
27
|
+
## [3.4.2] - 2019-02-21
|
|
28
|
+
### Changed
|
|
29
|
+
- `binding-functions` build target generates an ASCII file on Windows (#193)
|
|
30
|
+
|
|
31
|
+
## [3.4.1] - 2019-02-15
|
|
32
|
+
### Fixed
|
|
33
|
+
- `binding-functions` build target fixed when running the build out of source (#188)
|
|
34
|
+
|
|
10
35
|
## [3.4.0] - 2019-01-23
|
|
11
36
|
### Added
|
|
12
37
|
- `getRes0Indexes` function for getting all base cells, and helper function `res0IndexCount` (#174)
|
data/ext/h3/src/CMakeLists.txt
CHANGED
|
@@ -79,12 +79,6 @@ include(CMakeDependentOption)
|
|
|
79
79
|
include(CheckIncludeFile)
|
|
80
80
|
include(CTest)
|
|
81
81
|
|
|
82
|
-
include(CheckAlloca)
|
|
83
|
-
include(CheckVLA)
|
|
84
|
-
|
|
85
|
-
check_alloca(have_alloca)
|
|
86
|
-
check_vla(have_vla)
|
|
87
|
-
|
|
88
82
|
set(LIB_SOURCE_FILES
|
|
89
83
|
src/h3lib/include/bbox.h
|
|
90
84
|
src/h3lib/include/polygon.h
|
|
@@ -103,7 +97,6 @@ set(LIB_SOURCE_FILES
|
|
|
103
97
|
src/h3lib/include/constants.h
|
|
104
98
|
src/h3lib/include/coordijk.h
|
|
105
99
|
src/h3lib/include/algos.h
|
|
106
|
-
src/h3lib/include/stackAlloc.h
|
|
107
100
|
src/h3lib/lib/algos.c
|
|
108
101
|
src/h3lib/lib/coordijk.c
|
|
109
102
|
src/h3lib/lib/bbox.c
|
|
@@ -136,6 +129,7 @@ set(EXAMPLE_SOURCE_FILES
|
|
|
136
129
|
set(OTHER_SOURCE_FILES
|
|
137
130
|
src/apps/filters/h3ToGeo.c
|
|
138
131
|
src/apps/filters/h3ToLocalIj.c
|
|
132
|
+
src/apps/filters/localIjToH3.c
|
|
139
133
|
src/apps/filters/h3ToComponents.c
|
|
140
134
|
src/apps/filters/geoToH3.c
|
|
141
135
|
src/apps/filters/h3ToGeoBoundary.c
|
|
@@ -171,6 +165,7 @@ set(OTHER_SOURCE_FILES
|
|
|
171
165
|
src/apps/testapps/testH3Distance.c
|
|
172
166
|
src/apps/testapps/testH3Line.c
|
|
173
167
|
src/apps/testapps/testCoordIj.c
|
|
168
|
+
src/apps/testapps/testCoordIjk.c
|
|
174
169
|
src/apps/miscapps/h3ToGeoBoundaryHier.c
|
|
175
170
|
src/apps/miscapps/h3ToGeoHier.c
|
|
176
171
|
src/apps/miscapps/generateBaseCellNeighbors.c
|
|
@@ -310,6 +305,7 @@ add_h3_executable(geoToH3 src/apps/filters/geoToH3.c ${APP_SOURCE_FILES})
|
|
|
310
305
|
add_h3_executable(h3ToComponents src/apps/filters/h3ToComponents.c ${APP_SOURCE_FILES})
|
|
311
306
|
add_h3_executable(h3ToGeo src/apps/filters/h3ToGeo.c ${APP_SOURCE_FILES})
|
|
312
307
|
add_h3_executable(h3ToLocalIj src/apps/filters/h3ToLocalIj.c ${APP_SOURCE_FILES})
|
|
308
|
+
add_h3_executable(localIjToH3 src/apps/filters/localIjToH3.c ${APP_SOURCE_FILES})
|
|
313
309
|
add_h3_executable(h3ToGeoBoundary src/apps/filters/h3ToGeoBoundary.c ${APP_SOURCE_FILES})
|
|
314
310
|
add_h3_executable(hexRange src/apps/filters/hexRange.c ${APP_SOURCE_FILES})
|
|
315
311
|
add_h3_executable(kRing src/apps/filters/kRing.c ${APP_SOURCE_FILES})
|
|
@@ -363,7 +359,7 @@ if(BUILD_TESTING)
|
|
|
363
359
|
COMMAND bash "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/scripts/coverage.sh" "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
|
|
364
360
|
add_custom_target(clean-coverage
|
|
365
361
|
# Before running coverage, clear all counters
|
|
366
|
-
COMMAND lcov --directory '${CMAKE_CURRENT_BINARY_DIR}' --zerocounters
|
|
362
|
+
COMMAND lcov --rc lcov_branch_coverage=1 --directory '${CMAKE_CURRENT_BINARY_DIR}' --zerocounters
|
|
367
363
|
COMMENT "Zeroing counters"
|
|
368
364
|
)
|
|
369
365
|
endif()
|
|
@@ -485,6 +481,7 @@ if(BUILD_TESTING)
|
|
|
485
481
|
add_h3_test(testH3Distance src/apps/testapps/testH3Distance.c)
|
|
486
482
|
add_h3_test(testH3Line src/apps/testapps/testH3Line.c)
|
|
487
483
|
add_h3_test(testCoordIj src/apps/testapps/testCoordIj.c)
|
|
484
|
+
add_h3_test(testCoordIjk src/apps/testapps/testCoordIjk.c)
|
|
488
485
|
add_h3_test(testBaseCells src/apps/testapps/testBaseCells.c)
|
|
489
486
|
|
|
490
487
|
add_h3_test_with_arg(testH3NeighborRotations src/apps/testapps/testH3NeighborRotations.c 0)
|
data/ext/h3/src/CONTRIBUTING.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Pull requests and Github issues are welcome!
|
|
4
4
|
|
|
5
|
+
Planned improvements and changes are listed on the [H3 Roadmap](https://github.com/uber/h3/wiki/Roadmap). Roadmap items are currently discussed in Github issues. Feel free to open a discussion about an existing roadmap item or proposing a new one.
|
|
6
|
+
|
|
5
7
|
## Pull requests
|
|
6
8
|
|
|
7
9
|
* Please include tests that show the bug is fixed or feature works as intended.
|
data/ext/h3/src/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# H3: A Hexagonal Hierarchical Geospatial Indexing System
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.com/uber/h3)
|
|
4
4
|
[](https://ci.appveyor.com/project/Uber/h3/branch/master)
|
|
5
5
|
[](https://coveralls.io/github/uber/h3?branch=master)
|
|
6
6
|
[](LICENSE)
|
|
@@ -16,7 +16,11 @@ Documentation is available at [https://uber.github.io/h3/](https://uber.github.i
|
|
|
16
16
|
|
|
17
17
|
We recommend using prebuilt bindings if they are available for your programming language. Bindings for [Go](https://github.com/uber/h3-go), [Java](https://github.com/uber/h3-java), [JavaScript](https://github.com/uber/h3-js), [Python](https://github.com/uber/h3-py), and [others](https://uber.github.io/h3/#/documentation/community/bindings) are available.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
On macOS, you can install H3 using brew:
|
|
20
|
+
```
|
|
21
|
+
brew install h3
|
|
22
|
+
```
|
|
23
|
+
Otherwise, to build H3 from source, please see the following instructions.
|
|
20
24
|
|
|
21
25
|
### Building from source
|
|
22
26
|
|
data/ext/h3/src/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.4.
|
|
1
|
+
3.4.4
|
data/ext/h3/src/appveyor.yml
CHANGED
|
@@ -39,7 +39,12 @@ environment:
|
|
|
39
39
|
build_script:
|
|
40
40
|
- cmake "-G%GENERATOR%" -H. -Bbuild
|
|
41
41
|
- cmake --build build --config "%CONFIG%"
|
|
42
|
+
- cmake --build build --config "%CONFIG%" --target binding-functions
|
|
42
43
|
|
|
43
44
|
test_script:
|
|
44
45
|
- ps: cd build
|
|
45
|
-
- ctest -
|
|
46
|
+
- ctest -C "%CONFIG%"
|
|
47
|
+
# Check that binding-functions was generated and has content
|
|
48
|
+
- ps: |
|
|
49
|
+
$ErrorActionPreference = "Stop"
|
|
50
|
+
if ((Get-Item "binding-functions").Length -lt 10) { $host.SetShouldExit(1) }
|
data/ext/h3/src/docs/api/misc.md
CHANGED
|
@@ -55,3 +55,19 @@ int64_t numHexagons(int res);
|
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
Number of unique **H3** indexes at the given resolution.
|
|
58
|
+
|
|
59
|
+
## getRes0Indexes
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
void getRes0Indexes(H3Index *out);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
All the resolution 0 **H3** indexes.
|
|
66
|
+
|
|
67
|
+
## res0IndexCount
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
int res0IndexCount();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Number of resolution 0 **H3** indexes.
|
|
@@ -6,6 +6,10 @@ As a C library, bindings can be made to call H3 functions from different program
|
|
|
6
6
|
|
|
7
7
|
- [entrepreneur-interet-general/h3.standard](https://github.com/entrepreneur-interet-general/H3.Standard)
|
|
8
8
|
|
|
9
|
+
## ECL
|
|
10
|
+
|
|
11
|
+
- [hpcc-systems/HPCC-Platform](https://github.com/hpcc-systems/HPCC-Platform/tree/master/plugins/h3)
|
|
12
|
+
|
|
9
13
|
## Erlang
|
|
10
14
|
|
|
11
15
|
- [helium/erlang-h3](https://github.com/helium/erlang-h3)
|
|
@@ -23,6 +27,10 @@ As a C library, bindings can be made to call H3 functions from different program
|
|
|
23
27
|
- [uber/h3-js](https://github.com/uber/h3-js)
|
|
24
28
|
- [dfellis/h3-node](https://github.com/dfellis/h3-node)
|
|
25
29
|
|
|
30
|
+
## Julia
|
|
31
|
+
|
|
32
|
+
- [wookay/H3.jl](https://github.com/wookay/H3.jl)
|
|
33
|
+
|
|
26
34
|
## OCaml
|
|
27
35
|
|
|
28
36
|
- [travisbrady/ocaml-h3](https://github.com/travisbrady/ocaml-h3)
|
|
@@ -43,6 +51,7 @@ As a C library, bindings can be made to call H3 functions from different program
|
|
|
43
51
|
## R
|
|
44
52
|
|
|
45
53
|
- [scottmmjackson/h3r](https://github.com/scottmmjackson/h3r)
|
|
54
|
+
- [crazycapivara/h3-r](https://github.com/crazycapivara/h3-r)
|
|
46
55
|
|
|
47
56
|
## Ruby
|
|
48
57
|
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
This page lists further learning materials and code walkthroughs for the H3 library and bindings. Contributions to this list are welcome, please feel free to open a [pull request](https://github.com/uber/h3/tree/master/docs/community/tutorials.md).
|
|
4
4
|
|
|
5
|
+
## Java
|
|
6
|
+
|
|
7
|
+
- [H3 Measurements](https://github.com/isaacbrodsky/h3measurements): Measurements of average cell area, average cell perimeter length, truncation error, and so on.
|
|
8
|
+
|
|
5
9
|
## JavaScript
|
|
6
10
|
|
|
7
11
|
- [H3 Tutorials on Observable](https://beta.observablehq.com/collection/@nrabinowitz/h3-tutorial)
|
|
@@ -16,5 +16,4 @@
|
|
|
16
16
|
# by bindings of the H3 library. It is invoked by the `binding-functions`
|
|
17
17
|
# make target and produces a file `binding-functions`.
|
|
18
18
|
|
|
19
|
-
$
|
|
20
|
-
Get-Content "$scriptDir/../src/h3lib/include/h3api.h" | Where-Object {$_ -match "@defgroup ([A-Za-z0-9_]*)"} | Foreach {$Matches[1]} > binding-functions
|
|
19
|
+
Get-Content "src/h3lib/include/h3api.h" | Where-Object {$_ -match "@defgroup ([A-Za-z0-9_]*)"} | Foreach {$Matches[1]} | Out-File -FilePath binding-functions -Encoding ASCII
|
|
@@ -17,5 +17,6 @@
|
|
|
17
17
|
# by bindings of the H3 library. It is invoked by the `binding-functions`
|
|
18
18
|
# make target and produces a file `binding-functions`.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
set -eo pipefail
|
|
21
|
+
|
|
22
|
+
cat "src/h3lib/include/h3api.h" | sed -n '/@defgroup/s/.*@defgroup \([A-Za-z0-9_]*\) .*/\1/gp' > binding-functions
|
|
@@ -45,6 +45,6 @@ src_dir=${1:-"Missing source directory"}
|
|
|
45
45
|
binary_dir=${2:-"Missing binary directory"}
|
|
46
46
|
|
|
47
47
|
cd "${binary_dir}"
|
|
48
|
-
lcov --directory . --capture --output-file coverage.info
|
|
49
|
-
lcov --extract coverage.info "${src_dir}/src/h3lib/*" --output-file coverage.cleaned.info
|
|
50
|
-
genhtml -o coverage coverage.cleaned.info --title 'h3 coverage'
|
|
48
|
+
lcov --rc lcov_branch_coverage=1 --directory . --capture --output-file coverage.info
|
|
49
|
+
lcov --rc lcov_branch_coverage=1 --extract coverage.info "${src_dir}/src/h3lib/*" --output-file coverage.cleaned.info
|
|
50
|
+
genhtml --branch-coverage -o coverage coverage.cleaned.info --title 'h3 coverage'
|
|
@@ -29,7 +29,63 @@
|
|
|
29
29
|
/** Macro: Get the size of a fixed-size array */
|
|
30
30
|
#define ARRAY_SIZE(x) sizeof(x) / sizeof(x[0])
|
|
31
31
|
|
|
32
|
+
/** Maximum number of names an argument may have. */
|
|
33
|
+
#define NUM_ARG_NAMES 2
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* An argument accepted by on the command line of an H3 application. Specifies
|
|
37
|
+
* how the argument is presented, parsed, and where parsed values are stored.
|
|
38
|
+
*/
|
|
39
|
+
typedef struct {
|
|
40
|
+
/**
|
|
41
|
+
* Both short and long names of the argument. A name may be null, but the
|
|
42
|
+
* first name must be non-null.
|
|
43
|
+
*/
|
|
44
|
+
const char* const names[NUM_ARG_NAMES];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* If true, this argument must be specified. If the argument is not
|
|
48
|
+
* specified, argument parsing will fail.
|
|
49
|
+
*/
|
|
50
|
+
const bool required;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Scan format for the argument, which will be passed to sscanf. May be null
|
|
54
|
+
* to indicate the argument does not take a value.
|
|
55
|
+
*/
|
|
56
|
+
const char* const scanFormat;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Name to present the value as when printing help.
|
|
60
|
+
*/
|
|
61
|
+
const char* const valueName;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Value will be placed here if the argument is present and scanFormat is
|
|
65
|
+
* not null.
|
|
66
|
+
*/
|
|
67
|
+
void* const value;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Will be set to true if the argument is present. Should be false when
|
|
71
|
+
* passed in to parseArgs.
|
|
72
|
+
*/
|
|
73
|
+
bool found;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Help text for this argument.
|
|
77
|
+
*/
|
|
78
|
+
const char* const helpText;
|
|
79
|
+
} Arg;
|
|
80
|
+
|
|
32
81
|
// prototypes
|
|
82
|
+
|
|
83
|
+
int parseArgs(int argc, char* argv[], int numArgs, Arg* args[],
|
|
84
|
+
const Arg* helpArg, const char* helpText);
|
|
85
|
+
void printHelp(FILE* out, const char* programName, const char* helpText,
|
|
86
|
+
int numArgs, Arg* args[], const char* errorMessage,
|
|
87
|
+
const char* errorDetails);
|
|
88
|
+
|
|
33
89
|
void error(const char* msg);
|
|
34
90
|
void h3Print(H3Index h); // prints as integer
|
|
35
91
|
void h3Println(H3Index h); // prints as integer
|
|
@@ -52,4 +108,8 @@ void iterateAllIndexesAtRes(int res, void (*callback)(H3Index));
|
|
|
52
108
|
void iterateAllIndexesAtResPartial(int res, void (*callback)(H3Index),
|
|
53
109
|
int maxBaseCell);
|
|
54
110
|
|
|
111
|
+
int _parseArgsList(int argc, char* argv[], int numArgs, Arg* args[],
|
|
112
|
+
const Arg* helpArg, const char** errorMessage,
|
|
113
|
+
const char** errorDetail);
|
|
114
|
+
|
|
55
115
|
#endif
|
|
@@ -20,14 +20,206 @@
|
|
|
20
20
|
#include "utility.h"
|
|
21
21
|
#include <assert.h>
|
|
22
22
|
#include <inttypes.h>
|
|
23
|
-
#include <
|
|
23
|
+
#include <stdbool.h>
|
|
24
24
|
#include <stdio.h>
|
|
25
25
|
#include <stdlib.h>
|
|
26
|
+
#include <string.h>
|
|
26
27
|
#include "coordijk.h"
|
|
27
28
|
#include "geoCoord.h"
|
|
28
29
|
#include "h3Index.h"
|
|
29
30
|
#include "h3api.h"
|
|
30
31
|
|
|
32
|
+
/*
|
|
33
|
+
* Return codes from parseArgs.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
#define PARSE_ARGS_SUCCESS 0
|
|
37
|
+
#define PARSE_ARGS_HELP 1
|
|
38
|
+
#define PARSE_ARGS_REPEATED_ARGUMENT 2
|
|
39
|
+
#define PARSE_ARGS_MISSING_VALUE 3
|
|
40
|
+
#define PARSE_ARGS_FAILED_PARSE 4
|
|
41
|
+
#define PARSE_ARGS_UNKNOWN_ARGUMENT 5
|
|
42
|
+
#define PARSE_ARGS_MISSING_REQUIRED 6
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parse command line arguments and prints help, if needed.
|
|
46
|
+
*
|
|
47
|
+
* Uses the provided arguments to populate argument values and records in the
|
|
48
|
+
* argument if it is found.
|
|
49
|
+
*
|
|
50
|
+
* Returns non-zero if all required arguments are not present, an argument fails
|
|
51
|
+
* to parse, is missing its associated value, or arguments are specified more
|
|
52
|
+
* than once.
|
|
53
|
+
*
|
|
54
|
+
* Help is printed to stdout if a argument with isHelp = true is found, and help
|
|
55
|
+
* is printed to stderr if argument parsing fails.
|
|
56
|
+
*
|
|
57
|
+
* @param argc argc from main
|
|
58
|
+
* @param argv argv from main
|
|
59
|
+
* @param numArgs Number of elements in the args array
|
|
60
|
+
* @param args Pointer to each argument to parse
|
|
61
|
+
* @param helpArg Pointer to the argument for "--help"
|
|
62
|
+
* @param helpText Explanatory text for this program printed with help
|
|
63
|
+
* @return 0 if argument parsing succeeded, otherwise non-0. If help is printed,
|
|
64
|
+
* return value is non-0.
|
|
65
|
+
*/
|
|
66
|
+
int parseArgs(int argc, char* argv[], int numArgs, Arg* args[],
|
|
67
|
+
const Arg* helpArg, const char* helpText) {
|
|
68
|
+
const char* errorMessage = NULL;
|
|
69
|
+
const char* errorDetails = NULL;
|
|
70
|
+
|
|
71
|
+
int failed = _parseArgsList(argc, argv, numArgs, args, helpArg,
|
|
72
|
+
&errorMessage, &errorDetails);
|
|
73
|
+
|
|
74
|
+
if (failed || helpArg->found) {
|
|
75
|
+
printHelp(helpArg->found ? stdout : stderr, argv[0], helpText, numArgs,
|
|
76
|
+
args, errorMessage, errorDetails);
|
|
77
|
+
return failed != PARSE_ARGS_SUCCESS ? failed : PARSE_ARGS_HELP;
|
|
78
|
+
}
|
|
79
|
+
return PARSE_ARGS_SUCCESS;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Parse command line arguments.
|
|
84
|
+
*
|
|
85
|
+
* Uses the provided arguments to populate argument values.
|
|
86
|
+
*
|
|
87
|
+
* Returns non-zero if all required arguments are not present, an argument fails
|
|
88
|
+
* to parse, is missing its associated value, or arguments are specified more
|
|
89
|
+
* than once.
|
|
90
|
+
*
|
|
91
|
+
* @param argc argc from main
|
|
92
|
+
* @param argv argv from main
|
|
93
|
+
* @param numArgs Number of elements in the args array
|
|
94
|
+
* @param args Pointer to each argument to parse.
|
|
95
|
+
* @param helpArg Pointer to the argument for "--help" that suppresses checking
|
|
96
|
+
* for required arguments.
|
|
97
|
+
* @param errorMessage Error message to display, if returning non-zero.
|
|
98
|
+
* @param errorDetail Additional error details, if returning non-zero. May be
|
|
99
|
+
* null, and may be a pointer from `argv` or `args`.
|
|
100
|
+
* @return 0 if argument parsing succeeded, otherwise non-0.
|
|
101
|
+
*/
|
|
102
|
+
int _parseArgsList(int argc, char* argv[], int numArgs, Arg* args[],
|
|
103
|
+
const Arg* helpArg, const char** errorMessage,
|
|
104
|
+
const char** errorDetail) {
|
|
105
|
+
// Whether help was found and required arguments do not need to be checked
|
|
106
|
+
bool foundHelp = false;
|
|
107
|
+
|
|
108
|
+
for (int i = 1; i < argc; i++) {
|
|
109
|
+
bool foundMatch = false;
|
|
110
|
+
|
|
111
|
+
for (int j = 0; j < numArgs; j++) {
|
|
112
|
+
// Test this argument, which may have multiple names, for whether it
|
|
113
|
+
// matches. argName will be set to the name used for this argument
|
|
114
|
+
// if it matches.
|
|
115
|
+
const char* argName = NULL;
|
|
116
|
+
for (int k = 0; k < NUM_ARG_NAMES; k++) {
|
|
117
|
+
if (args[j]->names[k] == NULL) continue;
|
|
118
|
+
|
|
119
|
+
if (strcmp(argv[i], args[j]->names[k]) == 0) {
|
|
120
|
+
argName = args[j]->names[k];
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// argName unchanged from NULL indicates this didn't match, try the
|
|
125
|
+
// next argument.
|
|
126
|
+
if (argName == NULL) continue;
|
|
127
|
+
|
|
128
|
+
if (args[j]->found) {
|
|
129
|
+
*errorMessage = "Argument specified multiple times";
|
|
130
|
+
*errorDetail = argName;
|
|
131
|
+
return PARSE_ARGS_REPEATED_ARGUMENT;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (args[j]->scanFormat != NULL) {
|
|
135
|
+
// Argument has a value, need to advance one and read the value.
|
|
136
|
+
i++;
|
|
137
|
+
if (i >= argc) {
|
|
138
|
+
*errorMessage = "Argument value not present";
|
|
139
|
+
*errorDetail = argName;
|
|
140
|
+
return PARSE_ARGS_MISSING_VALUE;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!sscanf(argv[i], args[j]->scanFormat, args[j]->value)) {
|
|
144
|
+
*errorMessage = "Failed to parse argument";
|
|
145
|
+
*errorDetail = argName;
|
|
146
|
+
return PARSE_ARGS_FAILED_PARSE;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (args[j] == helpArg) {
|
|
151
|
+
foundHelp = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
args[j]->found = true;
|
|
155
|
+
foundMatch = true;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!foundMatch) {
|
|
160
|
+
*errorMessage = "Unknown argument";
|
|
161
|
+
// Don't set errorDetail, since the input could be unprintable.
|
|
162
|
+
return PARSE_ARGS_UNKNOWN_ARGUMENT;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Check for missing required arguments.
|
|
167
|
+
if (!foundHelp) {
|
|
168
|
+
for (int i = 0; i < numArgs; i++) {
|
|
169
|
+
if (args[i]->required && !args[i]->found) {
|
|
170
|
+
*errorMessage = "Required argument missing";
|
|
171
|
+
*errorDetail = args[i]->names[0];
|
|
172
|
+
return PARSE_ARGS_MISSING_REQUIRED;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return PARSE_ARGS_SUCCESS;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Print a help message.
|
|
182
|
+
*
|
|
183
|
+
* @param out Stream to print to, e.g. stdout
|
|
184
|
+
* @param programName Program name, such as from argv[0]
|
|
185
|
+
* @param helpText Explanation of what the program does
|
|
186
|
+
* @param numArgs Number of arguments to print help for
|
|
187
|
+
* @param args Pointer to arguments to print help for
|
|
188
|
+
* @param errorMessage Error message, or null
|
|
189
|
+
* @param errorDetails Additional error detail message, or null
|
|
190
|
+
*/
|
|
191
|
+
void printHelp(FILE* out, const char* programName, const char* helpText,
|
|
192
|
+
int numArgs, Arg* args[], const char* errorMessage,
|
|
193
|
+
const char* errorDetails) {
|
|
194
|
+
if (errorMessage != NULL) {
|
|
195
|
+
fprintf(out, "%s: %s", programName, errorMessage);
|
|
196
|
+
if (errorDetails != NULL) {
|
|
197
|
+
fprintf(out, ": %s", errorDetails);
|
|
198
|
+
}
|
|
199
|
+
fprintf(out, "\n");
|
|
200
|
+
}
|
|
201
|
+
fprintf(out, "%s: %s\n", programName, helpText);
|
|
202
|
+
fprintf(out, "H3 %d.%d.%d\n\n", H3_VERSION_MAJOR, H3_VERSION_MINOR,
|
|
203
|
+
H3_VERSION_PATCH);
|
|
204
|
+
|
|
205
|
+
for (int i = 0; i < numArgs; i++) {
|
|
206
|
+
fprintf(out, "\t");
|
|
207
|
+
for (int j = 0; j < NUM_ARG_NAMES; j++) {
|
|
208
|
+
if (args[i]->names[j] == NULL) continue;
|
|
209
|
+
if (j != 0) fprintf(out, ", ");
|
|
210
|
+
fprintf(out, "%s", args[i]->names[j]);
|
|
211
|
+
}
|
|
212
|
+
if (args[i]->scanFormat != NULL) {
|
|
213
|
+
fprintf(out, " <%s>", args[i]->valueName);
|
|
214
|
+
}
|
|
215
|
+
fprintf(out, "\t");
|
|
216
|
+
if (args[i]->required) {
|
|
217
|
+
fprintf(out, "Required. ");
|
|
218
|
+
}
|
|
219
|
+
fprintf(out, "%s\n", args[i]->helpText);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
31
223
|
void error(const char* msg) {
|
|
32
224
|
fflush(stdout);
|
|
33
225
|
fflush(stderr);
|
|
@@ -193,7 +385,7 @@ void iterateAllIndexesAtResPartial(int res, void (*callback)(H3Index),
|
|
|
193
385
|
H3Index bc;
|
|
194
386
|
setH3Index(&bc, 0, i, 0);
|
|
195
387
|
int childrenSz = H3_EXPORT(maxUncompactSize)(&bc, 1, res);
|
|
196
|
-
|
|
388
|
+
H3Index* children = calloc(childrenSz, sizeof(H3Index));
|
|
197
389
|
H3_EXPORT(uncompact)(&bc, 1, children, childrenSz, res);
|
|
198
390
|
|
|
199
391
|
for (int j = 0; j < childrenSz; j++) {
|
|
@@ -203,5 +395,7 @@ void iterateAllIndexesAtResPartial(int res, void (*callback)(H3Index),
|
|
|
203
395
|
|
|
204
396
|
(*callback)(children[j]);
|
|
205
397
|
}
|
|
398
|
+
|
|
399
|
+
free(children);
|
|
206
400
|
}
|
|
207
401
|
}
|