Skip to content

Commit

Permalink
Mapsforge: multilingual vector map files v4, closes #34
Browse files Browse the repository at this point in the history
  • Loading branch information
devemux86 committed Jun 25, 2016
1 parent bbdc431 commit d5954d3
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {

Expand All @@ -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();
}
}
Expand Down
1 change: 1 addition & 0 deletions vtm-playground/src/org/oscim/test/MapsforgeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
36 changes: 34 additions & 2 deletions vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -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);

Expand All @@ -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"))
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -141,4 +167,10 @@ public MapInfo getMapInfo() {
return fileInfo;
}

public interface Callback {
/**
* Extracts substring of preferred language from multilingual string.
*/
String extractLocalized(String s);
}
}
60 changes: 60 additions & 0 deletions vtm/src/org/oscim/tiling/source/mapfile/MapFileUtils.java
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.tiling.source.mapfile;

import java.util.Locale;

public final class MapFileUtils {

/**
* Extracts substring of preferred language from multilingual string.<br/>
* Example multilingual string: "Base\ren\bEnglish\rjp\bJapan\rzh_py\bPin-yin".
* <p/>
* 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() {
}
}
7 changes: 4 additions & 3 deletions vtm/src/org/oscim/tiling/source/mapfile/MapInfo.java
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -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);
Expand Down
28 changes: 10 additions & 18 deletions vtm/src/org/oscim/tiling/source/mapfile/header/OptionalFields.java
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -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.
Expand All @@ -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.
*/
Expand All @@ -77,30 +73,26 @@ 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;

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;
}
Expand Down Expand Up @@ -150,7 +142,7 @@ private OpenResult readOptionalFields(ReadBuffer readBuffer) {
return openResult;
}

openResult = readLanguagePreference(readBuffer);
openResult = readLanguagesPreference(readBuffer);
if (!openResult.isSuccess()) {
return openResult;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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).
*
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit d5954d3

Please sign in to comment.