h3 3.4.0 → 3.4.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.
|
3
|
+
[![Build Status](https://travis-ci.com/uber/h3.svg?branch=master)](https://travis-ci.com/uber/h3)
|
4
4
|
[![Build status](https://ci.appveyor.com/api/projects/status/61431y4sc5w0tsuk/branch/master?svg=true)](https://ci.appveyor.com/project/Uber/h3/branch/master)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/github/uber/h3/badge.svg?branch=master)](https://coveralls.io/github/uber/h3?branch=master)
|
6
6
|
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](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
|
}
|