Skip to content

Commit 39ccde5

Browse files
committed
Added decodeToRectangle
1 parent dc7f4a4 commit 39ccde5

File tree

14 files changed

+464
-288
lines changed

14 files changed

+464
-288
lines changed

src/main/java/com/mapcode/Boundary.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,8 @@ class Boundary {
3333

3434
private static final DataModel DATA_MODEL = DataModel.getInstance();
3535

36-
private Boundary(
37-
final int lonMicroDegMin,
38-
final int lonMicroDegMax,
39-
final int latMicroDegMin,
40-
final int latMicroDegMax) {
36+
private Boundary(final int lonMicroDegMin, final int lonMicroDegMax,
37+
final int latMicroDegMin, final int latMicroDegMax) {
4138
this.lonMicroDegMin = lonMicroDegMin;
4239
this.latMicroDegMin = latMicroDegMin;
4340
this.lonMicroDegMax = lonMicroDegMax;
@@ -98,7 +95,7 @@ boolean containsPoint(@Nonnull final Point p) {
9895
}
9996
final int lonMicroDeg = p.getLonMicroDeg();
10097

101-
// Longitude boundaries can extend (slightly) outside the [-180,180) range
98+
// Longitude boundaries can extend (slightly) outside the [-180,180) range.
10299
if (lonMicroDeg < lonMicroDegMin) {
103100
return (lonMicroDegMin <= (lonMicroDeg + Point.MICRO_DEG_360)) && ((lonMicroDeg + Point.MICRO_DEG_360) < lonMicroDegMax);
104101
} else if (lonMicroDeg >= lonMicroDegMax) {

src/main/java/com/mapcode/Common.java

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,23 @@
2929
class Common {
3030
private static final Logger LOG = LoggerFactory.getLogger(Common.class);
3131

32-
static final int[] nc = {
32+
// TODO: Need better name and explanation.
33+
static final int[] NC = {
3334
1, 31, 961, 29791, 923521, 28629151, 887503681
3435
};
35-
static final int[] xSide = {
36+
37+
// TODO: Need better name and explanation.
38+
static final int[] X_SIDE = {
3639
0, 5, 31, 168, 961, 5208, 29791, 165869, 923521, 5141947
3740
};
38-
static final int[] ySide = {
41+
42+
// TODO: Need better name and explanation.
43+
static final int[] Y_SIDE = {
3944
0, 6, 31, 176, 961, 5456, 29791, 165869, 923521, 5141947
4045
};
41-
private static final int[] xDivider19 = {
46+
47+
// TODO: Need better name and explanation.
48+
private static final int[] X_DIVIDER_19 = {
4249
360, 360, 360, 360, 360, 360, 361, 361, 361, 361,
4350
362, 362, 362, 363, 363, 363, 364, 364, 365, 366,
4451
366, 367, 367, 368, 369, 370, 370, 371, 372, 373,
@@ -86,46 +93,48 @@ private Common() {
8693
* @param maxY Longitude.
8794
* @return Divider.
8895
*/
96+
// TODO: Need better names for minY and maxY
8997
static int xDivider(final int minY, final int maxY) {
9098
assert minY < maxY;
9199
if (minY >= 0) {
92100
// maxY > minY > 0
93101
assert (maxY > minY) && (minY > 0);
94-
return xDivider19[minY >> 19];
102+
return X_DIVIDER_19[minY >> 19];
95103
} else if (maxY >= 0) {
96104
// maxY > 0 > minY
97105
assert (maxY > 0) && (0 > minY);
98-
return xDivider19[0];
106+
return X_DIVIDER_19[0];
99107
} else {
100108
// 0 > maxY > minY
101109
assert (0 > maxY) && (maxY > minY);
102-
return xDivider19[(-maxY) >> 19];
110+
return X_DIVIDER_19[(-maxY) >> 19];
103111
}
104112
}
105113

114+
// TODO: Need to explain what a codex is.
106115
static int countCityCoordinatesForCountry(final int codex, final int territoryRecord, final int firstTerritoryRecord) {
107116
assert codex >= 0;
108117
assert territoryRecord >= 0;
109118
assert firstTerritoryRecord >= 0;
110-
final int i = getFirstNamelessRecord(codex, territoryRecord, firstTerritoryRecord);
111-
int e = territoryRecord;
112-
while (Data.getCodex(e) == codex) {
113-
e++;
119+
final int firstRecord = getFirstNamelessRecord(codex, territoryRecord, firstTerritoryRecord);
120+
int record = territoryRecord;
121+
while (Data.getCodex(record) == codex) {
122+
record++;
114123
}
115-
assert i <= e;
116-
return e - i;
124+
assert firstRecord <= record;
125+
return record - firstRecord;
117126
}
118127

119128
static int getFirstNamelessRecord(final int codex, final int territoryRecord, final int firstTerritoryRecord) {
120129
assert codex >= 0;
121130
assert territoryRecord >= 0;
122131
assert firstTerritoryRecord >= 0;
123-
int i = territoryRecord;
124-
while ((i >= firstTerritoryRecord) && Data.isNameless(i) && (Data.getCodex(i) == codex)) {
125-
i--;
132+
int record = territoryRecord;
133+
while ((record >= firstTerritoryRecord) && Data.isNameless(record) && (Data.getCodex(record) == codex)) {
134+
record--;
126135
}
127-
i++;
128-
assert i <= territoryRecord;
129-
return i;
136+
record++;
137+
assert record <= territoryRecord;
138+
return record;
130139
}
131140
}

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,49 @@
2626
* This class the data class for Mapcode codex items.
2727
*/
2828
class Data {
29+
30+
// TODO: Need explanation what this is and how this is used.
2931
static final char[] ENCODE_CHARS = {
3032
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // Numerals.
3133
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', // Consonants.
3234
'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z',
3335
'A', 'E', 'U' // Vowels.
3436
};
3537

38+
// Get direct access to the data model.
3639
private static final DataModel DATA_MODEL = DataModel.getInstance();
3740

3841
private Data() {
3942
// Disabled.
4043
}
4144

45+
// TODO: Explain what these values are. Can we make this an enum instead (safer)?
46+
static final int TERRITORY_RECORD_TYPE_NONE = 0;
47+
static final int TERRITORY_RECORD_TYPE_PIPE = 1;
48+
static final int TERRITORY_RECORD_TYPE_PLUS = 2;
49+
static final int TERRITORY_RECORD_TYPE_STAR = 3;
50+
51+
// TODO: Need to explain what "nameless" means and what a territoryRecord is (different from territoryNumber).
4252
static boolean isNameless(final int territoryRecord) {
4353
assert (0 <= territoryRecord) && (territoryRecord < DATA_MODEL.getNrTerritoryRecords());
4454
return (DATA_MODEL.getDataFlags(territoryRecord) & 64) != 0;
4555
}
4656

57+
// TODO: Need to explain what "special shape" means.
4758
static boolean isSpecialShape(final int territoryRecord) {
4859
assert (0 <= territoryRecord) && (territoryRecord < DATA_MODEL.getNrTerritoryRecords());
60+
61+
// TODO: The "magic" of binary operators and bit shifting should be in class DataModel, not here.
4962
return (DATA_MODEL.getDataFlags(territoryRecord) & 1024) != 0;
5063
}
5164

52-
static final int TERRITORY_RECORD_TYPE_NONE = 0;
53-
static final int TERRITORY_RECORD_TYPE_PIPE = 1;
54-
static final int TERRITORY_RECORD_TYPE_PLUS = 2;
55-
65+
// TODO: Explain what territory record types are. Can they be an enum instead?
5666
static int getTerritoryRecordType(final int territoryRecord) {
5767
assert (0 <= territoryRecord) && (territoryRecord < DATA_MODEL.getNrTerritoryRecords());
5868
return (DATA_MODEL.getDataFlags(territoryRecord) >> 7) & 3; // 1=pipe 2=plus 3=star
5969
}
6070

71+
// TODO: What does "restricted" mean?
6172
static boolean isRestricted(final int territoryRecord) {
6273
assert (0 <= territoryRecord) && (territoryRecord < DATA_MODEL.getNrTerritoryRecords());
6374
return (DATA_MODEL.getDataFlags(territoryRecord) & 512) != 0;
@@ -69,17 +80,15 @@ static int getCodex(final int territoryRecord) {
6980
return (10 * (codexflags / 5)) + (codexflags % 5) + 1;
7081
}
7182

83+
// TODO: What does this method do? What is parameter i (rename)?
7284
@Nonnull
7385
static String headerLetter(final int i) {
7486
final int flags = DATA_MODEL.getDataFlags(i);
87+
88+
// TODO: The "magic" of how to interpret flags must be in DataModel, not here.
7589
if (((flags >> 7) & 3) == 1) {
7690
return Character.toString(ENCODE_CHARS[(flags >> 11) & 31]);
7791
}
7892
return "";
7993
}
80-
81-
@Nonnull
82-
static Boundary getBoundary(final int territoryRecord) {
83-
return Boundary.createBoundaryForTerritoryRecord(territoryRecord);
84-
}
8594
}

src/main/java/com/mapcode/DataModel.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
class DataModel {
3535
private static final Logger LOG = LoggerFactory.getLogger(DataModel.class);
3636

37+
// TODO: This class needs a thorough description of what the data file format looks like and what all bit fields means exactly.
3738
private static final int HEADER_ID_1 = 0;
3839
private static final int HEADER_ID_2 = 1;
3940
private static final int HEADER_VERSION_LO = 2;
@@ -196,11 +197,13 @@ int getNrTerritories() {
196197
*
197198
* @return Number of rectangles per territory.
198199
*/
200+
// TODO: Explain what territory records contain exactly.
199201
int getNrTerritoryRecords() {
200202
return nrTerritoryRecords;
201203
}
202204

203205
@SuppressWarnings("PointlessArithmeticExpression")
206+
// TODO: Explain what this does exactly, why not return a Point or Rectangle?
204207
int getLonMicroDegMin(final int territoryRecord) {
205208
return data[((territoryRecord * DATA_FIELDS_PER_REC) + POS_DATA_LON_MICRO_DEG_MIN)];
206209
}
@@ -221,17 +224,21 @@ int getDataFlags(final int territoryRecord) {
221224
return data[(territoryRecord * DATA_FIELDS_PER_REC) + POS_DATA_DATA_FLAGS] & MASK_DATA_DATA_FLAGS;
222225
}
223226

227+
// TODO: Explain what a "div" and "smart div" is and how you use, and why you need to use it.
224228
int getSmartDiv(final int territoryRecord) {
225229
return data[(territoryRecord * DATA_FIELDS_PER_REC) + POS_DATA_DATA_FLAGS] >> SHIFT_POS_DATA_SMART_DIV;
226230
}
227231

232+
// TODO: Explain what these methods do exactly.
228233
// Low-level routines for data access.
229234
@SuppressWarnings("PointlessArithmeticExpression")
230235
int getDataFirstRecord(final int territoryNumber) {
236+
assert (0 <= territoryNumber) && (territoryNumber <= Territory.AAA.getNumber());
231237
return index[territoryNumber + POS_INDEX_FIRST_RECORD];
232238
}
233239

234240
int getDataLastRecord(final int territoryNumber) {
241+
assert (0 <= territoryNumber) && (territoryNumber <= Territory.AAA.getNumber());
235242
return index[territoryNumber + POS_INDEX_LAST_RECORD] - 1;
236243
}
237244
}

0 commit comments

Comments
 (0)