Skip to content

Commit c53faef

Browse files
committed
expose Java integer encoding and conversion functions
1 parent 1f4d5c7 commit c53faef

1 file changed

Lines changed: 29 additions & 27 deletions

File tree

java/src/main/java/com/google/openlocationcode/OpenLocationCode.java

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -195,33 +195,14 @@ public OpenLocationCode(double latitude, double longitude, int codeLength) {
195195
throw new IllegalArgumentException("Illegal code length " + codeLength);
196196
}
197197

198-
// Store the code - we build it in reverse and reorder it afterwards.
199-
StringBuilder revCodeBuilder = new StringBuilder();
200-
201198
// Compute the code.
202-
// This approach converts each value to an integer after multiplying it by
203-
// the final precision. This allows us to use only integer operations, so
204-
// avoiding any accumulation of floating point representation errors.
205-
206-
long latVal = (long) roundAwayFromZero(latitude * LAT_INTEGER_MULTIPLIER);
207-
long lngVal = (long) roundAwayFromZero(longitude * LNG_INTEGER_MULTIPLIER);
208-
209-
// Clip and normalise values.
210-
latVal += LATITUDE_MAX * LAT_INTEGER_MULTIPLIER;
211-
if (latVal < 0) {
212-
latVal = 0;
213-
} else if (latVal >= 2 * LATITUDE_MAX * LAT_INTEGER_MULTIPLIER) {
214-
latVal = 2 * LATITUDE_MAX * LAT_INTEGER_MULTIPLIER - 1;
215-
}
216-
lngVal += LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER;
217-
if (lngVal < 0) {
218-
lngVal =
219-
lngVal % (2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER)
220-
+ 2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER;
221-
} else if (lngVal >= 2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER) {
222-
lngVal = lngVal % (2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER);
223-
}
199+
long[] integers = degreesToIntegers(latitude, longitude);
200+
this.code = encodeIntegers(integers[0], integers[1], codeLength);
201+
}
224202

203+
private static String encodeIntegers(long latVal, long lngVal, int codeLength) {
204+
// Store the code - we build it in reverse and reorder it afterwards.
205+
StringBuilder revCodeBuilder = new StringBuilder();
225206
// Compute the grid part of the code if necessary.
226207
if (codeLength > PAIR_CODE_LENGTH) {
227208
for (int i = 0; i < GRID_CODE_LENGTH; i++) {
@@ -256,8 +237,7 @@ public OpenLocationCode(double latitude, double longitude, int codeLength) {
256237
codeBuilder.setCharAt(i, PADDING_CHARACTER);
257238
}
258239
}
259-
this.code =
260-
codeBuilder.subSequence(0, Math.max(SEPARATOR_POSITION + 1, codeLength + 1)).toString();
240+
return codeBuilder.subSequence(0, Math.max(SEPARATOR_POSITION + 1, codeLength + 1)).toString();
261241
}
262242

263243
/**
@@ -667,6 +647,28 @@ public static boolean isShortCode(String code) {
667647

668648
// Private static methods.
669649

650+
private static long[] degreesToIntegers(double latitude, double longitude) {
651+
long lat = (long) roundAwayFromZero(latitude * LAT_INTEGER_MULTIPLIER);
652+
long lng = (long) roundAwayFromZero(longitude * LNG_INTEGER_MULTIPLIER);
653+
654+
// Clip and normalise values.
655+
lat += LATITUDE_MAX * LAT_INTEGER_MULTIPLIER;
656+
if (lat < 0) {
657+
lat = 0;
658+
} else if (lat >= 2 * LATITUDE_MAX * LAT_INTEGER_MULTIPLIER) {
659+
lat = 2 * LATITUDE_MAX * LAT_INTEGER_MULTIPLIER - 1;
660+
}
661+
lng += LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER;
662+
if (lng < 0) {
663+
lng =
664+
lng % (2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER)
665+
+ 2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER;
666+
} else if (lng >= 2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER) {
667+
lng = lng % (2 * LONGITUDE_MAX * LNG_INTEGER_MULTIPLIER);
668+
}
669+
return new long[]{lat, lng};
670+
}
671+
670672
/**
671673
* Round numbers like C does. This implements rounding away from zero (see
672674
* https://en.wikipedia.org/wiki/Rounding).

0 commit comments

Comments
 (0)