Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<artifactId>mapcode</artifactId>

<packaging>jar</packaging>
<version>2.0.1-SNAPSHOT</version>
<version>2.0.1</version>

<name>Mapcode Java Library</name>
<description>
Expand Down Expand Up @@ -68,7 +68,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jdk.version>1.8</jdk.version>
<jdk.version>1.6</jdk.version>

<gson.version>2.3.1</gson.version>
<jsr305.version>3.0.0</jsr305.version>
Expand Down
40 changes: 24 additions & 16 deletions src/main/java/com/mapcode/DataAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,31 @@ class DataAccess {
final int bufferSize = 100000;
final byte[] readBuffer = new byte[bufferSize];
int total = 0;
try (final InputStream inputStream = DataAccess.class.getResourceAsStream(FILE_NAME)) {
try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
int nrBytes = inputStream.read(readBuffer);
while (nrBytes >= 0) {
total += nrBytes;
outputStream.write(readBuffer, 0, nrBytes);
nrBytes = inputStream.read(readBuffer);
}

// Copy stream as unsigned bytes (ints).
final byte[] bytes = outputStream.toByteArray();
assert total == bytes.length;
FILE_DATA = new int[total];
for (int i = 0; i < total; ++i) {
FILE_DATA[i] = (bytes[i] < 0) ? (bytes[i] + 256) : bytes[i];

try {
final InputStream inputStream = DataAccess.class.getResourceAsStream(FILE_NAME);
try {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
int nrBytes = inputStream.read(readBuffer);
while (nrBytes >= 0) {
total += nrBytes;
outputStream.write(readBuffer, 0, nrBytes);
nrBytes = inputStream.read(readBuffer);
}

// Copy stream as unsigned bytes (ints).
final byte[] bytes = outputStream.toByteArray();
assert total == bytes.length;
FILE_DATA = new int[total];
for (int i = 0; i < total; ++i) {
FILE_DATA[i] = (bytes[i] < 0) ? (bytes[i] + 256) : bytes[i];

}
} finally {
outputStream.close();
}
} finally {
inputStream.close();
}
} catch (final IOException e) {
throw new ExceptionInInitializerError("Cannot initialize static data structure from: " +
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/mapcode/Encoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private static List<Mapcode> encode(final double argLatDeg, final double argLonD

final Point pointToEncode = Point.fromDeg(latDeg, lonDeg);
final List<SubArea> areas = SubArea.getAreasForPoint(pointToEncode);
final List<Mapcode> results = new ArrayList<>();
final List<Mapcode> results = new ArrayList<Mapcode>();

int lastbasesubareaID = -1;

Expand Down
15 changes: 6 additions & 9 deletions src/main/java/com/mapcode/Mapcode.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,11 @@ public Territory getTerritory() {
* provided as statics to only compile these patterns once.
*/
@Nonnull
static final String REGEX_TERRITORY = "[\\p{Alpha}\\p{Digit}]{2,3}+([-_][\\p{Alpha}\\p{Digit}]{2,3}+)?";
static final String REGEX_TERRITORY = "[\\p{L}\\p{N}]{2,3}+([-_][\\p{L}\\p{N}]{2,3}+)?";
@Nonnull
static final String REGEX_CODE_PART = "[\\p{Alpha}\\p{Digit}]{2,5}+";
static final String REGEX_CODE_PART = "[\\p{L}\\p{N}]{2,5}+";
@Nonnull
static final String REGEX_CODE_PRECISION = "[-][\\p{Alpha}\\p{Digit}&&[^zZ]]{1,2}+";
static final String REGEX_CODE_PRECISION = "[-][\\p{L}\\p{N}&&[^zZ]]{1,2}+";

/**
* This patterns/regular expressions is used for checking mapcode format strings.
Expand All @@ -261,14 +261,11 @@ public Territory getTerritory() {
REGEX_CODE_PART + "[.]" + REGEX_CODE_PART + '(' + REGEX_CODE_PRECISION + ")?";

@Nonnull
static final Pattern PATTERN_MAPCODE =
Pattern.compile('^' + REGEX_MAPCODE + '$', Pattern.UNICODE_CHARACTER_CLASS);
static final Pattern PATTERN_MAPCODE = Pattern.compile('^' + REGEX_MAPCODE + '$');
@Nonnull
static final Pattern PATTERN_TERRITORY =
Pattern.compile('^' + REGEX_TERRITORY + ' ', Pattern.UNICODE_CHARACTER_CLASS);
static final Pattern PATTERN_TERRITORY = Pattern.compile('^' + REGEX_TERRITORY + ' ');
@Nonnull
static final Pattern PATTERN_PRECISION =
Pattern.compile(REGEX_CODE_PRECISION + '$', Pattern.UNICODE_CHARACTER_CLASS);
static final Pattern PATTERN_PRECISION = Pattern.compile(REGEX_CODE_PRECISION + '$');

/**
* This enum describes the types of available mapcodes (as returned by {@link #getPrecisionFormat(String)}.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/mapcode/Range.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ Range<T> constrain(@Nonnull final Range<T> constrainingRange) {
return null;
}

return new Range<>(newMin, newMax);
return new Range<T>(newMin, newMax);
}

@Nullable
ArrayList<Range<T>> constrain(@Nonnull final ArrayList<Range<T>> constrainingRanges) {
final ArrayList<Range<T>> resultRanges = new ArrayList<>();
final ArrayList<Range<T>> resultRanges = new ArrayList<Range<T>>();
for (final Range<T> range : constrainingRanges) {
final Range<T> constrainedRange = constrain(range);
if (constrainedRange != null) {
Expand Down
34 changes: 17 additions & 17 deletions src/main/java/com/mapcode/SubArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ class SubArea {

private static final int SUB_AREAS_INITIAL_CAPACITY = 16250;

private static final List<SubArea> SUB_AREAS = new ArrayList<>(SUB_AREAS_INITIAL_CAPACITY);
private static final TreeMap<Integer, ArrayList<SubArea>> LON_MAP = new TreeMap<>();
private static final TreeMap<Integer, ArrayList<SubArea>> LAT_MAP = new TreeMap<>();
private static final List<SubArea> SUB_AREAS = new ArrayList<SubArea>(SUB_AREAS_INITIAL_CAPACITY);
private static final TreeMap<Integer, ArrayList<SubArea>> LON_MAP = new TreeMap<Integer, ArrayList<SubArea>>();
private static final TreeMap<Integer, ArrayList<SubArea>> LAT_MAP = new TreeMap<Integer, ArrayList<SubArea>>();

private static final Range<Integer> LAT_BOUNDING_RANGE = new Range<>(Point.LAT_MICRODEG_MIN, Point.LAT_MICRODEG_MAX);
private static final Range<Integer> LON_BOUNDING_RANGE = new Range<>(Point.LON_MICRODEG_MIN, Point.LON_MICRODEG_MAX);
private static final Range<Integer> LAT_BOUNDING_RANGE = new Range<Integer>(Point.LAT_MICRODEG_MIN, Point.LAT_MICRODEG_MAX);
private static final Range<Integer> LON_BOUNDING_RANGE = new Range<Integer>(Point.LON_MICRODEG_MIN, Point.LON_MICRODEG_MAX);

static {
LOG.info("SubArea: Initialize sub-areas for {} territories", Territory.values().length);
Expand Down Expand Up @@ -115,7 +115,7 @@ static SubArea getArea(final int i) {
@SuppressWarnings("unchecked")
@Nonnull
static List<SubArea> getAreasForPoint(@Nonnull final Point point) {
final ArrayList<ArrayList<SubArea>> areaLists = new ArrayList<>();
final ArrayList<ArrayList<SubArea>> areaLists = new ArrayList<ArrayList<SubArea>>();
ArrayList<SubArea> list;
list = LAT_MAP.get(point.getLatMicroDeg());

Expand Down Expand Up @@ -158,7 +158,7 @@ static List<SubArea> getAreasForPoint(@Nonnull final Point point) {
areaLists.add(list);
}

final ArrayList<SubArea> result = new ArrayList<>();
final ArrayList<SubArea> result = new ArrayList<SubArea>();
list = areaLists.get(0);

mainLoop:
Expand Down Expand Up @@ -208,8 +208,8 @@ private SubArea(final int i, @Nonnull final Territory territory, @Nullable final
minMaxSetup(i);
parentTerritory = territory;
subAreaID = i;
boundedLonRange = new ArrayList<>();
boundedLatRange = new ArrayList<>();
boundedLonRange = new ArrayList<Range<Integer>>();
boundedLatRange = new ArrayList<Range<Integer>>();

// Mapcode areas are inclusive for the minimum bounds and exclusive for the maximum bounds
// Trim max by 1, to address boundary cases.
Expand Down Expand Up @@ -246,7 +246,7 @@ private SubArea(final int i, @Nonnull final Territory territory, @Nullable final
@Nonnull
private static ArrayList<Range<Integer>> normaliseRange(
@Nonnull final Range<Integer> range, @Nonnull final Range<Integer> boundingRange) {
final ArrayList<Range<Integer>> ranges = new ArrayList<>();
final ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>();

Range<Integer> tempRange = range.constrain(boundingRange);
if (tempRange != null) {
Expand All @@ -255,7 +255,7 @@ private static ArrayList<Range<Integer>> normaliseRange(

Range<Integer> normalisingRange = range;
while (normalisingRange.getMin() < boundingRange.getMin()) {
normalisingRange = new Range<>((normalisingRange.getMin() + boundingRange.getMax())
normalisingRange = new Range<Integer>((normalisingRange.getMin() + boundingRange.getMax())
- boundingRange.getMin(), (normalisingRange.getMax() + boundingRange.getMax())
- boundingRange.getMin());
tempRange = normalisingRange.constrain(boundingRange);
Expand All @@ -266,7 +266,7 @@ private static ArrayList<Range<Integer>> normaliseRange(

normalisingRange = range;
while (normalisingRange.getMax() > boundingRange.getMax()) {
normalisingRange = new Range<>((normalisingRange.getMin() - boundingRange.getMax())
normalisingRange = new Range<Integer>((normalisingRange.getMin() - boundingRange.getMax())
+ boundingRange.getMin(), (normalisingRange.getMax() - boundingRange.getMax())
+ boundingRange.getMin());
tempRange = normalisingRange.constrain(boundingRange);
Expand All @@ -293,8 +293,8 @@ boolean containsPoint(@Nonnull final Point point) {
@Nonnull
SubArea extendBounds(final int xExtension, final int yExtension) {
final SubArea result = new SubArea();
result.latRange = new Range<>(this.getMinY() - yExtension, getMaxY() + yExtension);
result.lonRange = new Range<>(this.getMinX() - xExtension, getMaxX() + xExtension);
result.latRange = new Range<Integer>(this.getMinY() - yExtension, getMaxY() + yExtension);
result.lonRange = new Range<Integer>(this.getMinX() - xExtension, getMaxX() + xExtension);
return result;
}

Expand Down Expand Up @@ -327,11 +327,11 @@ private void minMaxSetup(final int arg) {
i += 4;
final int maxY = DataAccess.asLong(i);

latRange = new Range<>(minY, maxY);
lonRange = new Range<>(minX, maxX);
latRange = new Range<Integer>(minY, maxY);
lonRange = new Range<Integer>(minX, maxX);
}

private static Range<Integer> trimRange(final Range<Integer> range) {
return new Range<>(range.getMin(), range.getMax() - 1);
return new Range<Integer>(range.getMin(), range.getMax() - 1);
}
}
39 changes: 29 additions & 10 deletions src/main/java/com/mapcode/Territory.java
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ static Territory fromNumber(final int number) throws UnknownTerritoryException {
}

/**
* Get a territory from a mapcode territory abbreviation. Note that the provided abbreviation is NOT an
* Get a territory from a mapcode territory abbreviation (or a territory name). Note that the provided abbreviation is NOT an
* ISO code: it's a mapcode prefix. As local mapcodes for subdivisions have been optimized to prefer to use 2-character
* subdivisions codes in local codes, subdivisions are preferred over countries in this case.
*
Expand All @@ -658,7 +658,7 @@ static Territory fromNumber(final int number) throws UnknownTerritoryException {
*
* Brazilian mapcodes, on the other hand, would be specified as "BRA BDHP.JK39-1D", using the ISO 3 letter code.
*
* @param alphaCode Territory, alphanumeric code.
* @param alphaCode Territory name or alphanumeric code.
* @return Territory.
* @throws UnknownTerritoryException Thrown if incorrect numeric or alphanumeric code.
*/
Expand Down Expand Up @@ -822,13 +822,13 @@ private Territory(
*/
static {
final String errorPrefix = "Initializing error: ";
codeList = new ArrayList<>();
nameMap = new HashMap<>();
parentList = new ArrayList<>();
codeList = new ArrayList<Territory>();
nameMap = new HashMap<String, List<Territory>>();
parentList = new ArrayList<Territory>();
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
final Set<Integer> territoryCodes = new HashSet<>();
final Set<String> aliasesSet = new HashSet<>();
final Set<Integer> territoryCodes = new HashSet<Integer>();
final Set<String> namesSet = new HashSet<String>();

for (final Territory territory : Territory.values()) {
final int territoryNumber = territory.getNumber();
Expand All @@ -849,14 +849,33 @@ private Territory(
if ((territory.parentTerritory != null) && !parentList.contains(territory.parentTerritory)) {
parentList.add(territory.parentTerritory);
}

// Add territory codes and alias codes.
if (namesSet.contains(territory.toString())) {
throw new ExceptionInInitializerError(errorPrefix + "non-unique territory: " + territory.toString());
}
namesSet.add(territory.toString());
addNameWithParentVariants(territory.toString(), territory);
for (final String alias : territory.aliases) {
if (aliasesSet.contains(alias)) {
if (namesSet.contains(alias)) {
throw new ExceptionInInitializerError(errorPrefix + "non-unique alias: " + alias);
}
aliasesSet.add(alias);
namesSet.add(alias);
addNameWithParentVariants(alias, territory);
}

// Add territory fullnames and aliases as well. Skip special case: territory name == territory code (e.g. USA).
if (namesSet.contains(territory.fullName.toUpperCase()) && !territory.toString().equals(territory.fullName.toUpperCase())) {
throw new ExceptionInInitializerError(errorPrefix + "non-unique fullName: " + territory.fullName.toUpperCase());
}
addNameWithParentVariants(territory.fullName.toUpperCase(), territory);
for (final String fullNameAlias : territory.fullNameAliases) {
if (namesSet.contains(fullNameAlias.toUpperCase())) {
throw new ExceptionInInitializerError(errorPrefix + "non-unique fullName alias: " + fullNameAlias);
}
namesSet.add(fullNameAlias.toUpperCase());
addNameWithParentVariants(fullNameAlias.toUpperCase(), territory);
}
min = Math.min(min, territory.number);
max = Math.max(max, territory.number);
}
Expand Down Expand Up @@ -986,7 +1005,7 @@ private static void addName(@Nonnull final String name, @Nonnull final Territory
}
territories.add(territory);
} else {
final ArrayList<Territory> arrayList = new ArrayList<>();
final ArrayList<Territory> arrayList = new ArrayList<Territory>();
arrayList.add(territory);
nameMap.put(name, arrayList);
}
Expand Down
5 changes: 5 additions & 0 deletions src/site/apt/ReleaseNotes.apt.vm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ Release Notes (Version ${project.version})

* 2.0.1

* Reverted Java JDK level to 1.6 (Java 6) from 1.8 (Java 8), so the library can be used on
Android platforms operating at Java 6 as well.

* Use multi-threading for long running test to speed them up (uses all CPU cores now).

* Added the ability to use a country name for <<<Territory.fromString()>>>.

* 2.0.0

* Fixes to the data rectangles (primarily intended for ISO proposal).
Expand Down
Loading