Skip to content

Commit a9b8e17

Browse files
authored
Prepare for v4.4.0 (#192)
* prepare for 4.4.0 * format * wip * readme * fix coverage, fix jacoco error about java 24 * copy tests for addresses variant * change to match c * bump to 4.4.1 * adjust construct cell api * jint comment update * fix format * prepare for release
1 parent c833c42 commit a9b8e17

File tree

13 files changed

+441
-11
lines changed

13 files changed

+441
-11
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ file [H3Core.java](./src/main/java/com/uber/h3core/H3Core.java), and support
66
for the Linux x64 and Darwin x64 platforms.
77

88
## Unreleased Changes
9+
10+
## [4.4.0] - 2025-12-12
11+
### Added
12+
- `constructCell`, `isValidIndex`, and `getIndexDigit` functions.
13+
914
### Changed
1015
- Restored benchmark target to the build script. (#188)
16+
- Upgraded the core library to v4.4.1. (#192)
1117

1218
## [4.3.2] - 2025-10-10
1319
### Changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![Coverage Status](https://coveralls.io/repos/github/uber/h3-java/badge.svg?branch=master)](https://coveralls.io/github/uber/h3-java?branch=master)
77
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
88
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.uber/h3/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.uber/h3)
9-
[![H3 Version](https://img.shields.io/badge/h3-v4.3.0-blue.svg)](https://github.com/uber/h3/releases/tag/v4.3.0)
9+
[![H3 Version](https://img.shields.io/badge/h3-v4.4.1-blue.svg)](https://github.com/uber/h3/releases/tag/v4.4.1)
1010

1111
This library provides Java bindings for the [H3 Core Library](https://github.com/uber/h3). For API reference, please see the [H3 Documentation](https://h3geo.org/).
1212

@@ -18,14 +18,14 @@ Add it to your pom.xml:
1818
<dependency>
1919
<groupId>com.uber</groupId>
2020
<artifactId>h3</artifactId>
21-
<version>4.3.2</version>
21+
<version>4.4.0</version>
2222
</dependency>
2323
```
2424

2525
Or, using Gradle:
2626

2727
```gradle
28-
compile("com.uber:h3:4.3.2")
28+
compile("com.uber:h3:4.4.0")
2929
```
3030

3131
Encode a location into a hexagon address:

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ spotless {
133133
}
134134

135135
jacoco {
136-
toolVersion = '0.8.12'
136+
toolVersion = '0.8.14'
137137
}
138138

139139
jacocoTestReport {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
org.gradle.configuration-cache=false
66

77
# No spaces on the following line, needed by release.yml:
8-
version=4.3.3-SNAPSHOT
8+
version=4.4.0

h3version.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
h3.git.reference=v4.3.0
1+
h3.git.reference=v4.4.1

src/main/c/h3-java/src/jniapi.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,33 @@ void DestroyGeoPolygon(JNIEnv *env, jdoubleArray verts,
218218
}
219219
}
220220

221+
/*
222+
* Class: com_uber_h3core_NativeMethods
223+
* Method: constructCell
224+
* Signature: (II[I)J
225+
*/
226+
JNIEXPORT jlong JNICALL Java_com_uber_h3core_NativeMethods_constructCell(
227+
JNIEnv *env, jobject thiz, jint res, jint baseCell, jintArray digits) {
228+
H3Index result = 0;
229+
jint *digitsElements = (**env).GetIntArrayElements(env, digits, 0);
230+
231+
if (digitsElements != NULL) {
232+
// if sz is too small, bad things will happen
233+
// note: We assume int can at least contain `jint` on the current
234+
// platform. This may not be true if sizeof(int) < 32, but we don't
235+
// support any platforms where this would be the case.
236+
H3Error err = constructCell(res, baseCell, digitsElements, &result);
237+
238+
(**env).ReleaseIntArrayElements(env, digits, digitsElements, 0);
239+
if (err) {
240+
ThrowH3Exception(env, err);
241+
}
242+
} else {
243+
ThrowOutOfMemoryError(env);
244+
}
245+
return result;
246+
}
247+
221248
/*
222249
* Class: com_uber_h3core_NativeMethods
223250
* Method: isValidCell
@@ -228,6 +255,16 @@ JNIEXPORT jboolean JNICALL Java_com_uber_h3core_NativeMethods_isValidCell(
228255
return isValidCell(h3);
229256
}
230257

258+
/*
259+
* Class: com_uber_h3core_NativeMethods
260+
* Method: isValidIndex
261+
* Signature: (J)Z
262+
*/
263+
JNIEXPORT jboolean JNICALL Java_com_uber_h3core_NativeMethods_isValidIndex(
264+
JNIEnv *env, jobject thiz, jlong h3) {
265+
return isValidIndex(h3);
266+
}
267+
231268
/*
232269
* Class: com_uber_h3core_NativeMethods
233270
* Method: getBaseCellNumber

src/main/java/com/uber/h3core/H3Core.java

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,59 @@ private H3Core(NativeMethods h3Api) {
103103
this.h3Api = h3Api;
104104
}
105105

106-
/** Returns true if this is a valid H3 index. */
106+
/** Returns true if this is a valid H3 cell index. */
107107
public boolean isValidCell(long h3) {
108108
return h3Api.isValidCell(h3);
109109
}
110110

111-
/** Returns true if this is a valid H3 index. */
111+
/** Returns true if this is a valid H3 cell index. */
112112
public boolean isValidCell(String h3Address) {
113113
return isValidCell(stringToH3(h3Address));
114114
}
115115

116+
/** Returns true if this is a valid H3 index. */
117+
public boolean isValidIndex(long h3) {
118+
return h3Api.isValidIndex(h3);
119+
}
120+
121+
/** Returns true if this is a valid H3 index. */
122+
public boolean isValidIndex(String h3Address) {
123+
return isValidIndex(stringToH3(h3Address));
124+
}
125+
126+
/** Construct a cell index from component parts */
127+
public long constructCell(int baseCellNumber, List<Integer> digits, int res) {
128+
int[] digitsArray = digits.stream().mapToInt(Integer::intValue).toArray();
129+
if (digitsArray.length != res) {
130+
throw new IllegalArgumentException(
131+
String.format(
132+
"Number of provided digits is incorrect, must be %d, was %d",
133+
res, digitsArray.length));
134+
}
135+
if (digitsArray.length > 15) {
136+
throw new IllegalArgumentException(
137+
String.format(
138+
"Additional unused digits provided, must be at most 15 but was %d",
139+
digitsArray.length));
140+
}
141+
return h3Api.constructCell(res, baseCellNumber, digitsArray);
142+
}
143+
144+
/** Construct a cell index from component parts */
145+
public long constructCell(int baseCellNumber, List<Integer> digits) {
146+
return constructCell(baseCellNumber, digits, digits.size());
147+
}
148+
149+
/** Construct a cell index from component parts */
150+
public String constructCellAddress(int baseCellNumber, List<Integer> digits) {
151+
return h3ToString(constructCell(baseCellNumber, digits, digits.size()));
152+
}
153+
154+
/** Construct a cell index from component parts */
155+
public String constructCellAddress(int baseCellNumber, List<Integer> digits, int res) {
156+
return h3ToString(constructCell(baseCellNumber, digits, res));
157+
}
158+
116159
/** Returns the base cell number for this index. */
117160
public int getBaseCellNumber(long h3) {
118161
return h3Api.getBaseCellNumber(h3);
@@ -727,11 +770,37 @@ public int getResolution(String h3Address) {
727770
return getResolution(stringToH3(h3Address));
728771
}
729772

730-
/** Returns the resolution of the provided index */
773+
/** Returns the resolution of the provided index. */
731774
public int getResolution(long h3) {
732775
return (int) ((h3 & H3_RES_MASK) >> H3_RES_OFFSET);
733776
}
734777

778+
/**
779+
* Returns the indexing digit of the index at `res`
780+
*
781+
* @param h3 H3 index.
782+
* @param res Resolution of the digit, <code>1 &lt;= res &lt;= 15</code>
783+
* @throws IllegalArgumentException <code>res</code> is not between 0 and 15, inclusive.
784+
*/
785+
public int getIndexDigit(String h3Address, int res) {
786+
return getIndexDigit(stringToH3(h3Address), res);
787+
}
788+
789+
/**
790+
* Returns the indexing digit of the index at `res`
791+
*
792+
* @param h3 H3 index.
793+
* @param res Resolution of the digit, <code>1 &lt;= res &lt;= 15</code>
794+
* @throws IllegalArgumentException <code>res</code> is not between 0 and 15, inclusive.
795+
*/
796+
public int getIndexDigit(long h3, int res) {
797+
if (res < 1 || res > 15) {
798+
throw new IllegalArgumentException(
799+
String.format("resolution %d is out of range (must be 1 <= res <= 15)", res));
800+
}
801+
return (int) ((h3 >> ((15 - res) * 3)) & 7);
802+
}
803+
735804
/**
736805
* Returns the parent of the index at the given resolution.
737806
*

src/main/java/com/uber/h3core/NativeMethods.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@ final class NativeMethods {
3434

3535
native long cellToCenterChild(long h3, int childRes);
3636

37+
native long constructCell(int res, int baseCell, int[] digits);
38+
3739
native boolean isValidCell(long h3);
3840

41+
native boolean isValidIndex(long h3);
42+
3943
native int getBaseCellNumber(long h3);
4044

4145
native boolean isPentagon(long h3);

src/main/java/com/uber/h3core/exceptions/H3Exception.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ public static String codeToMessage(int code) {
6868
return "Bounds of provided memory were insufficient";
6969
case 15:
7070
return "Mode or flags argument was not valid";
71+
case 16:
72+
return "Index argument was not valid";
73+
case 17:
74+
return "Base cell number was outside of acceptable range";
75+
case 18:
76+
return "Child indexing digits invalid";
77+
case 19:
78+
return "Child indexing digits refer to a deleted subsequence";
7179
default:
7280
return "Unknown error";
7381
}

src/test/java/com/uber/h3core/TestDirectedEdges.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ void unidirectionalEdges() {
4343

4444
assertTrue(h3.isValidDirectedEdge(edge));
4545
assertFalse(h3.isValidDirectedEdge(start));
46+
assertTrue(h3.isValidIndex(edge));
47+
assertFalse(h3.isValidCell(edge));
4648

4749
assertEquals(start, h3.getDirectedEdgeOrigin(edge));
4850
assertEquals(adjacent, h3.getDirectedEdgeDestination(edge));

0 commit comments

Comments
 (0)