Skip to content

Commit 82a4242

Browse files
Replaced Subarea and Range with Boundary (22 times faster)
1 parent 0eb07f1 commit 82a4242

File tree

7 files changed

+109
-462
lines changed

7 files changed

+109
-462
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (C) 2014-2015 Stichting Mapcode Foundation (http://www.mapcode.com)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mapcode;
18+
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
21+
22+
import javax.annotation.Nonnull;
23+
import javax.annotation.Nullable;
24+
25+
/**
26+
* ----------------------------------------------------------------------------------------------
27+
* Package private implementation class. For internal use within the mapcode implementation only.
28+
* ----------------------------------------------------------------------------------------------
29+
*
30+
* This class handles the territory ractangles for mapcodes.
31+
*/
32+
class Boundaries {
33+
private int minx, maxx, miny, maxy;
34+
35+
/**
36+
* Public interface
37+
* Note that after construction, all calls are safe.
38+
*/
39+
40+
public static Boundaries getBoundaries(final int m) {
41+
Boundaries b = new Boundaries();
42+
b.minx = DataAccess.minx(m);
43+
b.miny = DataAccess.miny(m);
44+
b.maxx = DataAccess.maxx(m);
45+
b.maxy = DataAccess.maxy(m);
46+
return b;
47+
}
48+
49+
public int getMinX() {
50+
return minx;
51+
}
52+
53+
public int getMinY() {
54+
return miny;
55+
}
56+
57+
public int getMaxX() {
58+
return maxx;
59+
}
60+
61+
public int getMaxY() {
62+
return maxy;
63+
}
64+
65+
public Boundaries extendBounds(final int xExtension, final int yExtension) {
66+
minx -= xExtension;
67+
miny -= yExtension;
68+
maxx += xExtension;
69+
maxy += yExtension;
70+
return this;
71+
}
72+
73+
public boolean containsPoint(@Nonnull final Point p) {
74+
final int y = p.getLatMicroDeg();
75+
if ((miny <= y) && (y < maxy)) {
76+
int x = p.getLonMicroDeg();
77+
if ((minx <= x) && (x < maxx)) { return true; }
78+
if (x < minx) { x += 360000000; } else { x -= 360000000; }
79+
if ((minx <= x) && (x < maxx)) { return true; }
80+
}
81+
return false;
82+
}
83+
84+
public String toString() {
85+
return "[" + (miny / 1000000.0) + ", " + (maxy / 1000000.0) +
86+
"), [" + (minx / 1000000.0) + ", " + (maxx / 1000000.0) + ")";
87+
}
88+
}

src/main/java/com/mapcode/Data.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static String headerLetter(final int i) {
6363
return "";
6464
}
6565

66-
static SubArea getBoundaries(final int i) {
67-
return SubArea.getArea(i);
66+
static Boundaries getBoundaries(final int i) {
67+
return Boundaries.getBoundaries(i);
6868
}
6969
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public Point midPoint() {
9696
// returns a non-empty intersection of a mapcode zone and a territory area.
9797
// returns null if no such intersection exists
9898
@Nonnull
99-
public MapcodeZone restrictZoneTo(@Nonnull final SubArea area) {
99+
public MapcodeZone restrictZoneTo(@Nonnull final Boundaries area) {
100100
MapcodeZone z = new MapcodeZone(this);
101101
final double miny = area.getMinY() * Point.MICROLAT_TO_FRACTIONS_FACTOR;
102102
if (z.fminy < miny) {
@@ -195,9 +195,6 @@ static Point decode(@Nonnull final String argMapcode,
195195
final int ccode = territory.getNumber();
196196

197197
final int from = DataAccess.dataFirstRecord(ccode);
198-
if (DataAccess.dataFlags(from) == 0) { // no data for this territory?
199-
return Point.undefined(); // this territory is not in the current data
200-
}
201198
final int upto = DataAccess.dataLastRecord(ccode);
202199

203200
final int incodexhi = mapcode.indexOf('.');
@@ -226,7 +223,7 @@ static Point decode(@Nonnull final String argMapcode,
226223
i, extrapostfix);
227224

228225
// first of all, make sure the zone fits the country
229-
if (!mapcodeZone.isEmpty() && (territory != territory.AAA)) {
226+
if (!mapcodeZone.isEmpty() && (territory != Territory.AAA)) {
230227
mapcodeZone = mapcodeZone.restrictZoneTo(Data.getBoundaries(upto));
231228
}
232229

@@ -294,7 +291,7 @@ static Point decode(@Nonnull final String argMapcode,
294291
}
295292
}
296293

297-
if (territory != territory.AAA) {
294+
if (territory != Territory.AAA) {
298295
mapcodeZone = mapcodeZone.restrictZoneTo(Data.getBoundaries(upto));
299296
}
300297
final Point result = mapcodeZone.midPoint().wrap();

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

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,33 +65,27 @@ private static List<Mapcode> encode(final double argLatDeg, final double argLonD
6565
argLatDeg, argLonDeg, (territory == null) ? null : territory.name(), limitToOneResult,
6666
allowWorld);
6767

68-
final Point pointToEncode = Point.fromDeg(argLatDeg, argLonDeg);
69-
final List<SubArea> areas = SubArea.getAreasForPoint(pointToEncode);
70-
final List<Mapcode> results = new ArrayList<Mapcode>();
68+
final int ccode_earth = Territory.AAA.getNumber();
7169

72-
int lastbasesubareaID = -1;
70+
final Point pointToEncode = Point.fromDeg(argLatDeg, argLonDeg);
7371

74-
for (final SubArea subArea : areas) {
75-
if ((territory != null) && (subArea.getParentTerritory() != territory)) {
76-
continue;
77-
}
72+
final List<Mapcode> results = new ArrayList<Mapcode>();
7873

79-
final Territory currentEncodeTerritory = subArea.getParentTerritory();
74+
int lastbasesubareaID = -1;
8075

81-
if ((currentEncodeTerritory == Territory.AAA) && !allowWorld &&
82-
(territory != Territory.AAA)) {
83-
continue;
84-
}
76+
final int firstNr = (territory != null) ? territory.getNumber() : 0;
77+
final int lastNr = (territory != null) ? territory.getNumber() : (allowWorld ? ccode_earth : (ccode_earth-1) );
78+
for (int ccode = firstNr; ccode <= lastNr; ccode++ ) {
8579

86-
final int from = DataAccess.dataFirstRecord(currentEncodeTerritory.getNumber());
87-
88-
if (DataAccess.dataFlags(from) == 0) { // no data for this territory?
80+
final int upto = DataAccess.dataLastRecord(ccode);
81+
if ((ccode != ccode_earth) && !Data.getBoundaries(upto).containsPoint(pointToEncode)) {
8982
continue;
9083
}
91-
final int upto = DataAccess.dataLastRecord(currentEncodeTerritory.getNumber());
84+
final int from = DataAccess.dataFirstRecord(ccode);
85+
final Territory currentEncodeTerritory = Territory.fromNumber(ccode);
9286

93-
final int i = subArea.getSubAreaID();
94-
if (Data.getBoundaries(i).containsPoint(pointToEncode)) {
87+
for(int i=from; i<=upto; i++) {
88+
if (Data.getBoundaries(i).containsPoint(pointToEncode)) {
9589
String mapcode = "";
9690
if (Data.isNameless(i)) {
9791
mapcode = encodeNameless(pointToEncode, i, from);
@@ -131,6 +125,7 @@ private static List<Mapcode> encode(final double argLatDeg, final double argLonD
131125
return results;
132126
}
133127
}
128+
}
134129
}
135130
}
136131
LOG.trace("encode: results={} items", results.size());

src/main/java/com/mapcode/MapcodeCodec.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public static Point decode(
261261
*/
262262

263263
public static boolean multipleBordersNearby(@Nonnull final Point point, @Nonnull final Territory territory) {
264-
if (territory != territory.AAA) {
264+
if (territory != Territory.AAA) {
265265
final int ccode = territory.getNumber();
266266
if (territory.getParentTerritory() != null) {
267267
// there is a parent! check its borders as well...
@@ -275,7 +275,7 @@ public static boolean multipleBordersNearby(@Nonnull final Point point, @Nonnull
275275
final int upto = DataAccess.dataLastRecord(ccode);
276276
for (int m = upto; m >= from; m--) {
277277
if (!Data.isRestricted(m)) {
278-
final SubArea boundaries = Data.getBoundaries(m);
278+
final Boundaries boundaries = Boundaries.getBoundaries(m);
279279
final int xdiv8 = Common.xDivider(boundaries.getMinY(),boundaries.getMaxY()) / 4;
280280
if (boundaries.extendBounds(xdiv8, 60).containsPoint(point)) {
281281
if (!boundaries.extendBounds(-xdiv8, -60).containsPoint(point)) {

src/main/java/com/mapcode/Range.java

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)