Common.java
/*
* Copyright (C) 2014-2017, Stichting Mapcode Foundation (http://www.mapcode.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mapcode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// ----------------------------------------------------------------------------------------------
// Package private implementation class. For internal use within the Mapcode implementation only.
// ----------------------------------------------------------------------------------------------
/**
* This class contains common data structures and methods used by the Mapcode implementation.
*/
@SuppressWarnings("MagicNumber")
final class Common {
private static final Logger LOG = LoggerFactory.getLogger(Common.class);
// TODO: Need better name and explanation.
static final int[] NC = {
1, 31, 961, 29791, 923521, 28629151, 887503681
};
// TODO: Need better name and explanation.
static final int[] X_SIDE = {
0, 5, 31, 168, 961, 5208, 29791, 165869, 923521, 5141947
};
// TODO: Need better name and explanation.
static final int[] Y_SIDE = {
0, 6, 31, 176, 961, 5456, 29791, 165869, 923521, 5141947
};
// TODO: Need better name and explanation.
private static final int[] X_DIVIDER_19 = {
360, 360, 360, 360, 360, 360, 361, 361, 361, 361,
362, 362, 362, 363, 363, 363, 364, 364, 365, 366,
366, 367, 367, 368, 369, 370, 370, 371, 372, 373,
374, 375, 376, 377, 378, 379, 380, 382, 383, 384,
386, 387, 388, 390, 391, 393, 394, 396, 398, 399,
401, 403, 405, 407, 409, 411, 413, 415, 417, 420,
422, 424, 427, 429, 432, 435, 437, 440, 443, 446,
449, 452, 455, 459, 462, 465, 469, 473, 476, 480,
484, 488, 492, 496, 501, 505, 510, 515, 520, 525,
530, 535, 540, 546, 552, 558, 564, 570, 577, 583,
590, 598, 605, 612, 620, 628, 637, 645, 654, 664,
673, 683, 693, 704, 715, 726, 738, 751, 763, 777,
791, 805, 820, 836, 852, 869, 887, 906, 925, 946,
968, 990, 1014, 1039, 1066, 1094, 1123, 1154, 1187, 1223,
1260, 1300, 1343, 1389, 1438, 1490, 1547, 1609, 1676, 1749,
1828, 1916, 2012, 2118, 2237, 2370, 2521, 2691, 2887, 3114,
3380, 3696, 4077, 4547, 5139, 5910, 6952, 8443, 10747, 14784,
23681, 59485
};
private Common() {
// Prevent instantiation.
}
static {
// This code shows a message when assertions are active or disabled. It (ab)uses assert for that...
// Some of the methods (and tests) take considerably longer with assertions checking, so it's useful
// to have this information in the log file.
boolean debug = false;
//noinspection AssertWithSideEffects
assert debug = true;
//noinspection ConstantConditions
if (debug) {
LOG.info("Common: assertions are active (JVM runtime option '-ea')");
} else {
LOG.debug("Common: assertions are not active, they are bypassed");
}
}
// This method returns a divider for longitude (multiplied by 4), for a given latitude.
// TODO: Need better names for minY and maxY.
@SuppressWarnings("ConstantConditions")
static int xDivider(final int latMin, final int latMax) {
assert latMin < latMax;
if (latMin >= 0) {
assert (latMax > latMin) && (latMin > 0);
return X_DIVIDER_19[latMin >> 19];
} else if (latMax >= 0) {
assert (latMax > 0) && (0 > latMin);
return X_DIVIDER_19[0];
} else {
assert (0 > latMax) && (latMax > latMin);
return X_DIVIDER_19[(-latMax) >> 19];
}
}
// TODO: Need to explain what a codex is.
static int countCityCoordinatesForCountry(final int codex, final int territoryRecord, final int firstTerritoryRecord) {
assert codex >= 0;
assert territoryRecord >= 0;
assert firstTerritoryRecord >= 0;
final int firstRecord = getFirstNamelessRecord(codex, territoryRecord, firstTerritoryRecord);
int record = territoryRecord;
while (Data.getCodex(record) == codex) {
record++;
}
assert firstRecord <= record;
return record - firstRecord;
}
static int getFirstNamelessRecord(final int codex, final int territoryRecord, final int firstTerritoryRecord) {
assert codex >= 0;
assert territoryRecord >= 0;
assert firstTerritoryRecord >= 0;
int record = territoryRecord;
while ((record >= firstTerritoryRecord) && Data.isNameless(record) && (Data.getCodex(record) == codex)) {
record--;
}
record++;
assert record <= territoryRecord;
return record;
}
}