Mapsforge: multilingual vector map files v4, closes #34
This commit is contained in:
parent
bbdc431b9a
commit
d5954d350f
@ -91,6 +91,7 @@ public class MapsforgeMapActivity extends MapActivity {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
MapFileTileSource tileSource = new MapFileTileSource();
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
|
tileSource.setPreferredLanguage("en");
|
||||||
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
|
||||||
if (tileSource.setMapFile(file)) {
|
if (tileSource.setMapFile(file)) {
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ public class MapsforgeMapActivity extends MapActivity {
|
|||||||
MapPosition pos = new MapPosition();
|
MapPosition pos = new MapPosition();
|
||||||
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
|
pos.setByBoundingBox(info.boundingBox, Tile.SIZE * 4, Tile.SIZE * 4);
|
||||||
mMap.setMapPosition(pos);
|
mMap.setMapPosition(pos);
|
||||||
|
|
||||||
mPrefs.clear();
|
mPrefs.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ public class MapsforgeTest extends GdxMap {
|
|||||||
public void createLayers() {
|
public void createLayers() {
|
||||||
MapFileTileSource tileSource = new MapFileTileSource();
|
MapFileTileSource tileSource = new MapFileTileSource();
|
||||||
tileSource.setMapFile(System.getProperty("user.home") + "/Downloads/berlin.map");
|
tileSource.setMapFile(System.getProperty("user.home") + "/Downloads/berlin.map");
|
||||||
|
tileSource.setPreferredLanguage("en");
|
||||||
|
|
||||||
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
mMap.setTheme(VtmThemes.DEFAULT);
|
mMap.setTheme(VtmThemes.DEFAULT);
|
||||||
|
@ -540,7 +540,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
/* bit 1-3 enable optional features
|
/* bit 1-3 enable optional features
|
||||||
* check if the POI has a name */
|
* check if the POI has a name */
|
||||||
if ((featureByte & POI_FEATURE_NAME) != 0) {
|
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));
|
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +769,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
if (mTileSource.experimental) {
|
if (mTileSource.experimental) {
|
||||||
if (hasName) {
|
if (hasName) {
|
||||||
int textPos = mReadBuffer.readUnsignedInt();
|
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));
|
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
||||||
}
|
}
|
||||||
if (hasHouseNr) {
|
if (hasHouseNr) {
|
||||||
@ -784,7 +784,7 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (hasName) {
|
if (hasName) {
|
||||||
String str = mReadBuffer.readUTF8EncodedString();
|
String str = mTileSource.extractLocalized(mReadBuffer.readUTF8EncodedString());
|
||||||
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
e.tags.add(new Tag(Tag.KEY_NAME, str, false));
|
||||||
}
|
}
|
||||||
if (hasHouseNr) {
|
if (hasHouseNr) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
* Copyright 2013 mapsforge.org
|
* Copyright 2013 mapsforge.org
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
* Copyright 2016 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@ -45,10 +46,30 @@ public class MapFileTileSource extends TileSource {
|
|||||||
File mapFile;
|
File mapFile;
|
||||||
RandomAccessFile mInputFile;
|
RandomAccessFile mInputFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The preferred language when extracting labels from this tile source.
|
||||||
|
*/
|
||||||
|
private String preferredLanguage;
|
||||||
|
private Callback callback;
|
||||||
|
|
||||||
public MapFileTileSource() {
|
public MapFileTileSource() {
|
||||||
super(0, 17);
|
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) {
|
public boolean setMapFile(String filename) {
|
||||||
setOption("file", filename);
|
setOption("file", filename);
|
||||||
|
|
||||||
@ -65,6 +86,10 @@ public class MapFileTileSource extends TileSource {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPreferredLanguage(String preferredLanguage) {
|
||||||
|
this.preferredLanguage = preferredLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OpenResult open() {
|
public OpenResult open() {
|
||||||
if (!options.containsKey("file"))
|
if (!options.containsKey("file"))
|
||||||
@ -101,7 +126,8 @@ public class MapFileTileSource extends TileSource {
|
|||||||
mapFile = file;
|
mapFile = file;
|
||||||
databaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
|
databaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);
|
||||||
|
|
||||||
experimental = fileInfo.fileVersion == 4;
|
// Experimental?
|
||||||
|
//experimental = fileInfo.fileVersion == 4;
|
||||||
|
|
||||||
log.debug("File version: " + fileInfo.fileVersion);
|
log.debug("File version: " + fileInfo.fileVersion);
|
||||||
return OpenResult.SUCCESS;
|
return OpenResult.SUCCESS;
|
||||||
@ -141,4 +167,10 @@ public class MapFileTileSource extends TileSource {
|
|||||||
return fileInfo;
|
return fileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface Callback {
|
||||||
|
/**
|
||||||
|
* Extracts substring of preferred language from multilingual string.
|
||||||
|
*/
|
||||||
|
String extractLocalized(String s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
60
vtm/src/org/oscim/tiling/source/mapfile/MapFileUtils.java
Normal file
60
vtm/src/org/oscim/tiling/source/mapfile/MapFileUtils.java
Normal file
@ -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() {
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
* Copyright 2016 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@ -50,9 +51,9 @@ public class MapInfo {
|
|||||||
public final int fileVersion;
|
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.
|
* The center point of the map file.
|
||||||
@ -120,7 +121,7 @@ public class MapInfo {
|
|||||||
this.mapDate = date;
|
this.mapDate = date;
|
||||||
this.boundingBox = bbox;
|
this.boundingBox = bbox;
|
||||||
this.mapCenter = bbox.getCenterPoint();
|
this.mapCenter = bbox.getCenterPoint();
|
||||||
this.languagePreference = language;
|
this.languagesPreference = language;
|
||||||
this.fileSize = size;
|
this.fileSize = size;
|
||||||
this.fileVersion = version;
|
this.fileVersion = version;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
* Copyright 2016 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* 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.mapDate,
|
||||||
mapFileInfoBuilder.fileSize,
|
mapFileInfoBuilder.fileSize,
|
||||||
mapFileInfoBuilder.fileVersion,
|
mapFileInfoBuilder.fileVersion,
|
||||||
mapFileInfoBuilder.optionalFields.languagePreference,
|
mapFileInfoBuilder.optionalFields.languagesPreference,
|
||||||
mapFileInfoBuilder.optionalFields.comment,
|
mapFileInfoBuilder.optionalFields.comment,
|
||||||
mapFileInfoBuilder.optionalFields.createdBy,
|
mapFileInfoBuilder.optionalFields.createdBy,
|
||||||
mapFileInfoBuilder.zoomLevel);
|
mapFileInfoBuilder.zoomLevel);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
* Copyright 2016 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* 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;
|
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.
|
* 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;
|
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.
|
* Maximum valid start zoom level.
|
||||||
*/
|
*/
|
||||||
@ -77,11 +73,11 @@ final class OptionalFields {
|
|||||||
String createdBy;
|
String createdBy;
|
||||||
final boolean hasComment;
|
final boolean hasComment;
|
||||||
final boolean hasCreatedBy;
|
final boolean hasCreatedBy;
|
||||||
final boolean hasLanguagePreference;
|
final boolean hasLanguagesPreference;
|
||||||
final boolean hasStartPosition;
|
final boolean hasStartPosition;
|
||||||
final boolean hasStartZoomLevel;
|
final boolean hasStartZoomLevel;
|
||||||
final boolean isDebugFile;
|
final boolean isDebugFile;
|
||||||
String languagePreference;
|
String languagesPreference;
|
||||||
GeoPoint startPosition;
|
GeoPoint startPosition;
|
||||||
Byte startZoomLevel;
|
Byte startZoomLevel;
|
||||||
|
|
||||||
@ -89,18 +85,14 @@ final class OptionalFields {
|
|||||||
this.isDebugFile = (flags & HEADER_BITMASK_DEBUG) != 0;
|
this.isDebugFile = (flags & HEADER_BITMASK_DEBUG) != 0;
|
||||||
this.hasStartPosition = (flags & HEADER_BITMASK_START_POSITION) != 0;
|
this.hasStartPosition = (flags & HEADER_BITMASK_START_POSITION) != 0;
|
||||||
this.hasStartZoomLevel = (flags & HEADER_BITMASK_START_ZOOM_LEVEL) != 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.hasComment = (flags & HEADER_BITMASK_COMMENT) != 0;
|
||||||
this.hasCreatedBy = (flags & HEADER_BITMASK_CREATED_BY) != 0;
|
this.hasCreatedBy = (flags & HEADER_BITMASK_CREATED_BY) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OpenResult readLanguagePreference(ReadBuffer readBuffer) {
|
private OpenResult readLanguagesPreference(ReadBuffer readBuffer) {
|
||||||
if (this.hasLanguagePreference) {
|
if (this.hasLanguagesPreference) {
|
||||||
String countryCode = readBuffer.readUTF8EncodedString();
|
this.languagesPreference = readBuffer.readUTF8EncodedString();
|
||||||
if (countryCode.length() != LANGUAGE_PREFERENCE_LENGTH) {
|
|
||||||
return new OpenResult("invalid language preference: " + countryCode);
|
|
||||||
}
|
|
||||||
this.languagePreference = countryCode;
|
|
||||||
}
|
}
|
||||||
return OpenResult.SUCCESS;
|
return OpenResult.SUCCESS;
|
||||||
}
|
}
|
||||||
@ -150,7 +142,7 @@ final class OptionalFields {
|
|||||||
return openResult;
|
return openResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
openResult = readLanguagePreference(readBuffer);
|
openResult = readLanguagesPreference(readBuffer);
|
||||||
if (!openResult.isSuccess()) {
|
if (!openResult.isSuccess()) {
|
||||||
return openResult;
|
return openResult;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
* Copyright 2016 devemux86
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
@ -50,10 +51,14 @@ final class RequiredFields {
|
|||||||
private static final char SPACE = ' ';
|
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 SUPPORTED_FILE_VERSION_MIN = 3;
|
||||||
private static final int FILE_VERSION_4 = 4;
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* The maximum latitude values in microdegrees.
|
||||||
@ -126,7 +131,7 @@ final class RequiredFields {
|
|||||||
static OpenResult readFileVersion(ReadBuffer readBuffer, MapFileInfoBuilder mapFileInfoBuilder) {
|
static OpenResult readFileVersion(ReadBuffer readBuffer, MapFileInfoBuilder mapFileInfoBuilder) {
|
||||||
// get and check the file version (4 bytes)
|
// get and check the file version (4 bytes)
|
||||||
int fileVersion = readBuffer.readInt();
|
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);
|
return new OpenResult("unsupported file version: " + fileVersion);
|
||||||
}
|
}
|
||||||
mapFileInfoBuilder.fileVersion = fileVersion;
|
mapFileInfoBuilder.fileVersion = fileVersion;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user