Skip to content

Commit 95df628

Browse files
Added 8 precision digit support in preparation for v2.1.0
1 parent 413f1a7 commit 95df628

File tree

9 files changed

+317
-166
lines changed

9 files changed

+317
-166
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
target/
22
out/
3+
_build*.*
34
*.versionsBackup

src/main/java/com/mapcode/Decoder.java

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ private static Point decodeGrid(final String str, final int minx, final int miny
342342
final int cornery = rely + (dify * dividery);
343343
final int cornerx = relx + (difx * dividerx);
344344

345-
return decodeExtension(cornery, cornerx, dividerx << 2, dividery, 1, extrapostfix);
345+
return decodeExtension(cornery, cornerx, dividerx << 2, dividery, extrapostfix, 0); // grid
346346
}
347347

348348
@Nonnull
@@ -447,7 +447,7 @@ private static Point decodeNameless(final String str, final int firstrec, final
447447

448448
final int cornerx = minx + ((dx * dividerx4) / 4);
449449
final int cornery = maxy - (dy * dividery);
450-
return decodeExtension(cornery, cornerx, dividerx4, dividery, -1, extrapostfix);
450+
return decodeExtension(cornery, cornerx, dividerx4, -dividery, extrapostfix, ((dx * dividerx4) % 4) ); // nameless
451451
}
452452

453453
@Nonnull
@@ -506,7 +506,7 @@ private static Point decodeAutoHeader(final String input, final int m, final Str
506506
return Point.undefined(); // corner out of bounds
507507
}
508508

509-
return decodeExtension(cornery, cornerx, dividerx << 2, dividery, -1, extrapostfix);
509+
return decodeExtension(cornery, cornerx, dividerx << 2, -dividery, extrapostfix, 0); // autoheader
510510
}
511511
storageStart += product;
512512
i++;
@@ -717,28 +717,65 @@ private static int decodeBase31(final String code) {
717717
}
718718

719719
@Nonnull
720-
private static Point decodeExtension(final int y, final int x, final int dividerx4, final int dividery, final int ydirection, final String extrapostfix) {
721-
if (!extrapostfix.isEmpty()) {
722-
int c1 = (int) extrapostfix.charAt(0);
720+
private static Point decodeExtension(final int y, final int x, final int dividerx4, final int dividery, final String extrapostfix, final int lon_offset4) {
721+
final double dividerx = dividerx4 / 4;
722+
double processor = 1;
723+
double lon32 = 0;
724+
double lat32 = 0;
725+
boolean odd = false;
726+
int idx = 0;
727+
// decode up to 8 characters
728+
final int len = extrapostfix.length() > 8 ? 8 : extrapostfix.length();
729+
while (idx < len) {
730+
int c1 = (int) extrapostfix.charAt(idx++);
723731
c1 = DECODE_CHARS[c1];
724732
if (c1 < 0 || c1 == 30) {
725733
return Point.undefined();
726734
}
727735
final int y1 = c1 / 5;
728736
final int x1 = c1 % 5;
729-
int c2 = (extrapostfix.length() == 2) ? (int) extrapostfix.charAt(1) : 72;
730-
c2 = DECODE_CHARS[c2];
731-
if (c2 < 0 || c2 == 30) {
732-
return Point.undefined();
737+
final int y2;
738+
final int x2;
739+
if (idx < len) {
740+
int c2 = (int) extrapostfix.charAt(idx++);
741+
c2 = DECODE_CHARS[c2];
742+
if (c2 < 0 || c2 == 30) {
743+
return Point.undefined();
744+
}
745+
y2 = c2 / 6;
746+
x2 = c2 % 6;
747+
} else {
748+
odd = true;
749+
y2 = 0;
750+
x2 = 0;
733751
}
734-
final int y2 = c2 / 6;
735-
final int x2 = c2 % 6;
736752

737-
final int extrax = ((((x1 * 12) + (2 * x2) + 1) * dividerx4) + 120) / 240;
738-
final int extray = ((((y1 * 10) + (2 * y2) + 1) * dividery) + 30) / 60;
739-
740-
return Point.fromMicroDeg(y + (extray * ydirection), x + extrax);
753+
processor *= 30;
754+
lon32 = lon32 * 30 + (x1 * 6) + x2;
755+
lat32 = lat32 * 30 + (y1 * 5) + y2;
741756
}
742-
return Point.fromMicroDeg(y + ((dividery / 2) * ydirection), x + (dividerx4 / 8));
757+
758+
double lat = y + ((lat32 * dividery) / processor);
759+
double lon = x + ((lon32 * dividerx) / processor) + ( lon_offset4 / 4.0 );
760+
761+
/* FORCE_RECODE : TO DO!
762+
var range = {minlon:lon, maxlon:lon, minlat:lat, maxlat:lat};
763+
if (odd) {
764+
range.maxlon += (dividerx / (processor / 6));
765+
range.maxlat += (dividery / (processor / 5));
766+
} else {
767+
range.maxlon += (dividerx / processor);
768+
range.maxlat += (dividery / processor);
769+
} // FORCE_RECODE */
770+
771+
if (odd) {
772+
lon += (dividerx / (2 * (processor / 6)));
773+
lat += (dividery / (2 * (processor / 5)));
774+
} else {
775+
lon += (dividerx / (2 * processor));
776+
lat += (dividery / (2 * processor));
777+
} // not odd
778+
779+
return Point.fromDeg( lat / 1000000.0, lon / 1000000.0 );
743780
}
744781
}

src/main/java/com/mapcode/Encoder.java

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ private static List<Mapcode> encode(final double argLatDeg, final double argLonD
105105

106106
if (!isRecursive) {
107107
stateOverride = currentEncodeTerritory;
108-
results.addAll(encode(latDeg, lonDeg, currentEncodeTerritory.getParentTerritory(), true, limitToOneResult,
108+
results.addAll(encode(argLatDeg, argLonDeg, currentEncodeTerritory.getParentTerritory(), true, limitToOneResult,
109109
allowWorld, stateOverride));
110110
stateOverride = null;
111111
}
@@ -151,15 +151,36 @@ private static List<Mapcode> encode(final double argLatDeg, final double argLonD
151151
return results;
152152
}
153153

154-
private static String encodeExtension(final int extrax4, final int extray, final int dividerx4, final int dividery) {
155-
final int gx = ((30 * extrax4) / dividerx4);
156-
final int gy = ((30 * extray) / dividery);
157-
final int x1 = (gx / 6);
158-
final int y1 = (gy / 5);
159-
String s = "-" + ENCODE_CHARS[((y1 * 5) + x1)];
160-
final int x2 = (gx % 6);
161-
final int y2 = (gy % 5);
162-
s += ENCODE_CHARS[((y2 * 6) + x2)];
154+
private static String encodeExtension(final int extrax4, final int extray, final int dividerx4, final int dividery, final int ydirection) {
155+
int extraDigits = 8; // always generate 8 digits
156+
final double MAX_PRECISION_FACTOR = 810000; // 30^4 (correct for 8 precision digits)
157+
158+
final double encfraclon = 0; // TODO @@@ should be the fraction (of millionths)
159+
final double encfraclat = 0; // TODO @@@
160+
161+
double factorx = MAX_PRECISION_FACTOR * dividerx4;
162+
double factory = MAX_PRECISION_FACTOR * dividery;
163+
double valx = (MAX_PRECISION_FACTOR * extrax4) + encfraclon;
164+
double valy = (MAX_PRECISION_FACTOR * extray ) + (ydirection * encfraclat);
165+
166+
String s = "-";
167+
168+
while (true) {
169+
factorx /= 30;
170+
final int gx = (int)(valx / factorx);
171+
172+
factory /= 30;
173+
final int gy = (int)(valy / factory);
174+
175+
s += ENCODE_CHARS[((gy / 5) * 5) + (gx / 6)];
176+
if (--extraDigits == 0) break;
177+
178+
s += ENCODE_CHARS[(((gy % 5) * 6) + (gx % 6))];
179+
if (--extraDigits == 0) break;
180+
181+
valx -= factorx * gx;
182+
valy -= factory * gy;
183+
}
163184
return s;
164185
}
165186

@@ -258,7 +279,7 @@ else if (codexm == 14) {
258279
result = result.charAt(0) + "." + result.charAt(1) + result.substring(3);
259280
}
260281

261-
result += encodeExtension(extrax << 2, extray, dividerx << 2, dividery); // grid
282+
result += encodeExtension(extrax << 2, extray, dividerx << 2, dividery, 1); // grid
262283

263284
return Data.headerLetter(m) + result;
264285
}
@@ -317,7 +338,7 @@ private static String encodeAutoHeader(final Point pointToEncode, final int this
317338
autoheader_result.append(encodeTriple(vx % 168, vy % 176));
318339

319340
autoheader_result.append(
320-
encodeExtension(extrax << 2, extray, dividerx << 2, dividery)); // for encodeAutoHeader
341+
encodeExtension(extrax << 2, extray, dividerx << 2, dividery, -1)); // for encodeAutoHeader
321342
return autoheader_result.toString();
322343
}
323344

@@ -407,7 +428,7 @@ private static String encodeNameless(final Point pointToEncode, final int index,
407428
result = result.substring(0, 3) + '.' + result.substring(3);
408429
}
409430
}
410-
result += encodeExtension(extrax4, extray, dividerx4, dividery); // for encodeNameless
431+
result += encodeExtension(extrax4, extray, dividerx4, dividery, -1); // for encodeNameless
411432

412433
return result;
413434
}

0 commit comments

Comments
 (0)