diff --git a/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java b/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java
index a74edd64d..a818dbb15 100644
--- a/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java
+++ b/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java
@@ -91,6 +91,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent intent)
return;
MapFileTileSource tileSource = new MapFileTileSource();
+ tileSource.setPreferredLanguage("en");
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
if (tileSource.setMapFile(file)) {
@@ -104,6 +105,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent intent)
MapPosition pos = new MapPosition();
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
mMap.setMapPosition(pos);
+
mPrefs.clear();
}
}
diff --git a/vtm-playground/src/org/oscim/test/MapsforgeTest.java b/vtm-playground/src/org/oscim/test/MapsforgeTest.java
index 98cea34b9..468592e1b 100644
--- a/vtm-playground/src/org/oscim/test/MapsforgeTest.java
+++ b/vtm-playground/src/org/oscim/test/MapsforgeTest.java
@@ -33,6 +33,7 @@ public class MapsforgeTest extends GdxMap {
public void createLayers() {
MapFileTileSource tileSource = new MapFileTileSource();
tileSource.setMapFile(System.getProperty("user.home") + "/Downloads/berlin.map");
+ tileSource.setPreferredLanguage("en");
VectorTileLayer l = mMap.setBaseMap(tileSource);
mMap.setTheme(VtmThemes.DEFAULT);
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java b/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java
index b6130c822..4eeba03bb 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java
@@ -540,7 +540,7 @@ private boolean processPOIs(ITileDataSink mapDataSink, int numberOfPois) {
/* bit 1-3 enable optional features
* check if the POI has a name */
if ((featureByte & POI_FEATURE_NAME) != 0) {
- String str = mReadBuffer.readUTF8EncodedString();
+ String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedString());
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
}
@@ -769,7 +769,7 @@ private boolean processWays(QueryParameters queryParameters,
if (mTileSource.experimental) {
if (hasName) {
int textPos = mReadBuffer.readUnsignedInt();
- String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
+ String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos));
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
}
if (hasHouseNr) {
@@ -784,7 +784,7 @@ private boolean processWays(QueryParameters queryParameters,
}
} else {
if (hasName) {
- String str = mReadBuffer.readUTF8EncodedString();
+ String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedString());
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
}
if (hasHouseNr) {
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java b/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
index 9dc41b07e..4e80c99c4 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
@@ -1,6 +1,7 @@
/*
- * Copyright 2013 Hannes Janetzek
* Copyright 2013 mapsforge.org
+ * Copyright 2013 Hannes Janetzek
+ * Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -45,10 +46,30 @@ public class MapFileTileSource extends TileSource {
File mapFile;
RandomAccessFile mInputFile;
+ /**
+ * The preferred language when extracting labels from this tile source.
+ */
+ private String preferredLanguage;
+ private Callback callback;
+
public MapFileTileSource() {
super(0, 17);
}
+ /**
+ * Extracts substring of preferred language from multilingual string using
+ * the preferredLanguage setting.
+ */
+ String extractLocalized(String s) {
+ if (callback != null)
+ return callback.extractLocalized(s);
+ return MapFileUtils.extract(s, preferredLanguage);
+ }
+
+ public void setCallback(Callback callback) {
+ this.callback = callback;
+ }
+
public boolean setMapFile(String filename) {
setOption("file", filename);
@@ -65,6 +86,10 @@ public boolean setMapFile(String filename) {
return true;
}
+ public void setPreferredLanguage(String preferredLanguage) {
+ this.preferredLanguage = preferredLanguage;
+ }
+
@Override
public OpenResult open() {
if (!options.containsKey("file"))
@@ -101,7 +126,8 @@ public OpenResult open() {
mapFile = file;
databaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
- experimental = fileInfo.fileVersion == 4;
+ // Experimental?
+ //experimental = fileInfo.fileVersion == 4;
log.debug("File version: " + fileInfo.fileVersion);
return OpenResult.SUCCESS;
@@ -141,4 +167,10 @@ public MapInfo getMapInfo() {
return fileInfo;
}
+ public interface Callback {
+ /**
+ * Extracts substring of preferred language from multilingual string.
+ */
+ String extractLocalized(String s);
+ }
}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MapFileUtils.java b/vtm/src/org/oscim/tiling/source/mapfile/MapFileUtils.java
new file mode 100644
index 000000000..d150fadda
--- /dev/null
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MapFileUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see .
+ */
+package org.oscim.tiling.source.mapfile;
+
+import java.util.Locale;
+
+public final class MapFileUtils {
+
+ /**
+ * Extracts substring of preferred language from multilingual string.
+ * Example multilingual string: "Base\ren\bEnglish\rjp\bJapan\rzh_py\bPin-yin".
+ *
+ * Use '\r' delimiter among names and '\b' delimiter between each language and name.
+ */
+ public static String extract(String s, String language) {
+ if (s == null || s.trim().isEmpty()) {
+ return null;
+ }
+
+ String[] langNames = s.split("\r");
+ if (language == null || language.trim().isEmpty()) {
+ return langNames[0];
+ }
+
+ String fallback = null;
+ for (int i = 1; i < langNames.length; i++) {
+ String[] langName = langNames[i].split("\b");
+ if (langName.length != 2) {
+ continue;
+ }
+
+ // Perfect match
+ if (langName[0].equalsIgnoreCase(language)) {
+ return langName[1];
+ }
+
+ // Fall back to base, e.g. zh-min-lan -> zh
+ if (fallback == null && !langName[0].contains("-") && (language.contains("-") || language.contains("_"))
+ && language.toLowerCase(Locale.ENGLISH).startsWith(langName[0].toLowerCase(Locale.ENGLISH))) {
+ fallback = langName[1];
+ }
+ }
+ return (fallback != null) ? fallback : langNames[0];
+ }
+
+ private MapFileUtils() {
+ }
+}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MapInfo.java b/vtm/src/org/oscim/tiling/source/mapfile/MapInfo.java
index be80aacb8..e19cce8d8 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/MapInfo.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MapInfo.java
@@ -1,5 +1,6 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -50,9 +51,9 @@ public class MapInfo {
public final int fileVersion;
/**
- * The preferred language for names as defined in ISO 3166-1 (may be null).
+ * The preferred language(s) separated with ',' for names as defined in ISO 639-1 or ISO 639-2 (may be null).
*/
- public final String languagePreference;
+ public final String languagesPreference;
/**
* The center point of the map file.
@@ -120,7 +121,7 @@ public MapInfo(BoundingBox bbox, Byte zoom, GeoPoint start, String projection,
this.mapDate = date;
this.boundingBox = bbox;
this.mapCenter = bbox.getCenterPoint();
- this.languagePreference = language;
+ this.languagesPreference = language;
this.fileSize = size;
this.fileVersion = version;
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/header/MapFileInfo.java b/vtm/src/org/oscim/tiling/source/mapfile/header/MapFileInfo.java
index ea3ddd686..0ba3649d8 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/header/MapFileInfo.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/header/MapFileInfo.java
@@ -1,5 +1,6 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -57,7 +58,7 @@ public class MapFileInfo extends org.oscim.tiling.source.mapfile.MapInfo {
mapFileInfoBuilder.mapDate,
mapFileInfoBuilder.fileSize,
mapFileInfoBuilder.fileVersion,
- mapFileInfoBuilder.optionalFields.languagePreference,
+ mapFileInfoBuilder.optionalFields.languagesPreference,
mapFileInfoBuilder.optionalFields.comment,
mapFileInfoBuilder.optionalFields.createdBy,
mapFileInfoBuilder.zoomLevel);
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/header/OptionalFields.java b/vtm/src/org/oscim/tiling/source/mapfile/header/OptionalFields.java
index 290a809ba..b71308705 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/header/OptionalFields.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/header/OptionalFields.java
@@ -1,5 +1,6 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -37,9 +38,9 @@ final class OptionalFields {
private static final int HEADER_BITMASK_DEBUG = 0x80;
/**
- * Bitmask for the language preference field in the file header.
+ * Bitmask for the language(s) preference field in the file header.
*/
- private static final int HEADER_BITMASK_LANGUAGE_PREFERENCE = 0x10;
+ private static final int HEADER_BITMASK_LANGUAGES_PREFERENCE = 0x10;
/**
* Bitmask for the start position field in the file header.
@@ -51,11 +52,6 @@ final class OptionalFields {
*/
private static final int HEADER_BITMASK_START_ZOOM_LEVEL = 0x20;
- /**
- * The length of the language preference string.
- */
- private static final int LANGUAGE_PREFERENCE_LENGTH = 2;
-
/**
* Maximum valid start zoom level.
*/
@@ -77,11 +73,11 @@ static OpenResult readOptionalFields(ReadBuffer readBuffer,
String createdBy;
final boolean hasComment;
final boolean hasCreatedBy;
- final boolean hasLanguagePreference;
+ final boolean hasLanguagesPreference;
final boolean hasStartPosition;
final boolean hasStartZoomLevel;
final boolean isDebugFile;
- String languagePreference;
+ String languagesPreference;
GeoPoint startPosition;
Byte startZoomLevel;
@@ -89,18 +85,14 @@ private OptionalFields(byte flags) {
this.isDebugFile = (flags & HEADER_BITMASK_DEBUG) != 0;
this.hasStartPosition = (flags & HEADER_BITMASK_START_POSITION) != 0;
this.hasStartZoomLevel = (flags & HEADER_BITMASK_START_ZOOM_LEVEL) != 0;
- this.hasLanguagePreference = (flags & HEADER_BITMASK_LANGUAGE_PREFERENCE) != 0;
+ this.hasLanguagesPreference = (flags & HEADER_BITMASK_LANGUAGES_PREFERENCE) != 0;
this.hasComment = (flags & HEADER_BITMASK_COMMENT) != 0;
this.hasCreatedBy = (flags & HEADER_BITMASK_CREATED_BY) != 0;
}
- private OpenResult readLanguagePreference(ReadBuffer readBuffer) {
- if (this.hasLanguagePreference) {
- String countryCode = readBuffer.readUTF8EncodedString();
- if (countryCode.length() != LANGUAGE_PREFERENCE_LENGTH) {
- return new OpenResult("invalid language preference: " + countryCode);
- }
- this.languagePreference = countryCode;
+ private OpenResult readLanguagesPreference(ReadBuffer readBuffer) {
+ if (this.hasLanguagesPreference) {
+ this.languagesPreference = readBuffer.readUTF8EncodedString();
}
return OpenResult.SUCCESS;
}
@@ -150,7 +142,7 @@ private OpenResult readOptionalFields(ReadBuffer readBuffer) {
return openResult;
}
- openResult = readLanguagePreference(readBuffer);
+ openResult = readLanguagesPreference(readBuffer);
if (!openResult.isSuccess()) {
return openResult;
}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/header/RequiredFields.java b/vtm/src/org/oscim/tiling/source/mapfile/header/RequiredFields.java
index 619dd4835..e4a80bec3 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/header/RequiredFields.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/header/RequiredFields.java
@@ -1,5 +1,6 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2016 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -50,10 +51,14 @@ final class RequiredFields {
private static final char SPACE = ' ';
/**
- * Version of the map file format which is supported by this implementation.
+ * Lowest version of the map file format supported by this implementation.
*/
- private static final int FILE_VERSION_3 = 3;
- private static final int FILE_VERSION_4 = 4;
+ private static final int SUPPORTED_FILE_VERSION_MIN = 3;
+
+ /**
+ * Highest version of the map file format supported by this implementation.
+ */
+ private static final int SUPPORTED_FILE_VERSION_MAX = 4;
/**
* The maximum latitude values in microdegrees.
@@ -126,7 +131,7 @@ static OpenResult readFileSize(ReadBuffer readBuffer, long fileSize,
static OpenResult readFileVersion(ReadBuffer readBuffer, MapFileInfoBuilder mapFileInfoBuilder) {
// get and check the file version (4 bytes)
int fileVersion = readBuffer.readInt();
- if (fileVersion != FILE_VERSION_3 && fileVersion != FILE_VERSION_4) {
+ if (fileVersion < SUPPORTED_FILE_VERSION_MIN || fileVersion > SUPPORTED_FILE_VERSION_MAX) {
return new OpenResult("unsupported file version: " + fileVersion);
}
mapFileInfoBuilder.fileVersion = fileVersion;