diff --git a/docs/Changelog.md b/docs/Changelog.md
index 4a76591b..fc24b538 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -2,8 +2,9 @@
## New since 0.6.0
+- Mapsforge multiple map files [#208](https://github.com/mapsforge/vtm/issues/208)
- Polygon label position enhancements [#80](https://github.com/mapsforge/vtm/issues/80)
-- PathLayer (regular) fix disappearing segments [#108](https://github.com/mapsforge/vtm/issues/108)
+- PathLayer (vtm) fix disappearing segments [#108](https://github.com/mapsforge/vtm/issues/108)
- MapFileTileSource zoom level improvements [#219](https://github.com/mapsforge/vtm/issues/219)
- Many other minor improvements and bug fixes
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aissue+is%3Aclosed+milestone%3A0.7.0)
diff --git a/vtm-playground/src/org/oscim/test/MapsforgeMultiTest.java b/vtm-playground/src/org/oscim/test/MapsforgeMultiTest.java
new file mode 100644
index 00000000..7b322de6
--- /dev/null
+++ b/vtm-playground/src/org/oscim/test/MapsforgeMultiTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.test;
+
+import org.oscim.core.MapPosition;
+import org.oscim.core.Tile;
+import org.oscim.gdx.GdxMap;
+import org.oscim.gdx.GdxMapApp;
+import org.oscim.layers.tile.buildings.BuildingLayer;
+import org.oscim.layers.tile.vector.VectorTileLayer;
+import org.oscim.layers.tile.vector.labeling.LabelLayer;
+import org.oscim.theme.VtmThemes;
+import org.oscim.tiling.source.mapfile.MapFileTileSource;
+import org.oscim.tiling.source.mapfile.MultiMapFileTileSource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MapsforgeMultiTest extends GdxMap {
+
+ private final List mapFiles;
+
+ private MapsforgeMultiTest(List mapFiles) {
+ this.mapFiles = mapFiles;
+ }
+
+ @Override
+ public void createLayers() {
+ MultiMapFileTileSource tileSource = new MultiMapFileTileSource();
+ for (File mapFile : mapFiles) {
+ MapFileTileSource mapFileTileSource = new MapFileTileSource();
+ mapFileTileSource.setMapFile(mapFile.getAbsolutePath());
+ tileSource.add(mapFileTileSource);
+ }
+ tileSource.setPreferredLanguage("en");
+
+ VectorTileLayer l = mMap.setBaseMap(tileSource);
+ mMap.setTheme(VtmThemes.DEFAULT);
+
+ mMap.layers().add(new BuildingLayer(mMap, l));
+ mMap.layers().add(new LabelLayer(mMap, l));
+
+ MapPosition pos = new MapPosition();
+ pos.setByBoundingBox(tileSource.getBoundingBox(), Tile.SIZE * 4, Tile.SIZE * 4);
+ mMap.setMapPosition(pos);
+ }
+
+ private static List getMapFiles(String[] args) {
+ if (args.length == 0) {
+ throw new IllegalArgumentException("missing argument: ");
+ }
+
+ List result = new ArrayList<>();
+ for (String arg : args) {
+ File mapFile = new File(arg);
+ if (!mapFile.exists()) {
+ throw new IllegalArgumentException("file does not exist: " + mapFile);
+ } else if (!mapFile.isFile()) {
+ throw new IllegalArgumentException("not a file: " + mapFile);
+ } else if (!mapFile.canRead()) {
+ throw new IllegalArgumentException("cannot read file: " + mapFile);
+ }
+ result.add(mapFile);
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ GdxMapApp.init();
+ GdxMapApp.run(new MapsforgeMultiTest(getMapFiles(args)));
+ }
+}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/IMapFileTileSource.java b/vtm/src/org/oscim/tiling/source/mapfile/IMapFileTileSource.java
new file mode 100644
index 00000000..217af33e
--- /dev/null
+++ b/vtm/src/org/oscim/tiling/source/mapfile/IMapFileTileSource.java
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+public interface IMapFileTileSource {
+
+ void setCallback(MapFileTileSource.Callback callback);
+
+ void setPreferredLanguage(String preferredLanguage);
+}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java b/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
index 4ccb45ee..b3924773 100644
--- a/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MapFileTileSource.java
@@ -30,7 +30,7 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
-public class MapFileTileSource extends TileSource {
+public class MapFileTileSource extends TileSource implements IMapFileTileSource {
private static final Logger log = LoggerFactory.getLogger(MapFileTileSource.class);
/**
@@ -70,6 +70,7 @@ public class MapFileTileSource extends TileSource {
return MapFileUtils.extract(s, preferredLanguage);
}
+ @Override
public void setCallback(Callback callback) {
this.callback = callback;
}
@@ -90,6 +91,7 @@ public class MapFileTileSource extends TileSource {
return true;
}
+ @Override
public void setPreferredLanguage(String preferredLanguage) {
this.preferredLanguage = preferredLanguage;
}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDataSink.java b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDataSink.java
new file mode 100644
index 00000000..5ce67fbe
--- /dev/null
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDataSink.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.oscim.backend.canvas.Bitmap;
+import org.oscim.core.MapElement;
+import org.oscim.tiling.ITileDataSink;
+import org.oscim.tiling.QueryResult;
+
+class MultiMapDataSink implements ITileDataSink {
+
+ private QueryResult result;
+ private final ITileDataSink tileDataSink;
+
+ MultiMapDataSink(ITileDataSink tileDataSink) {
+ this.tileDataSink = tileDataSink;
+ }
+
+ QueryResult getResult() {
+ return result;
+ }
+
+ @Override
+ public void process(MapElement element) {
+ tileDataSink.process(element);
+ }
+
+ @Override
+ public void setTileImage(Bitmap bitmap) {
+ tileDataSink.setTileImage(bitmap);
+ }
+
+ @Override
+ public void completed(QueryResult result) {
+ this.result = result;
+ }
+}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java
new file mode 100644
index 00000000..5cd4b4de
--- /dev/null
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.oscim.layers.tile.MapTile;
+import org.oscim.tiling.ITileDataSink;
+import org.oscim.tiling.ITileDataSource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MultiMapDatabase implements ITileDataSource {
+
+ private final List mapDatabases = new ArrayList<>();
+
+ public boolean add(MapDatabase mapDatabase) {
+ if (mapDatabases.contains(mapDatabase)) {
+ throw new IllegalArgumentException("Duplicate map database");
+ }
+ return mapDatabases.add(mapDatabase);
+ }
+
+ @Override
+ public void query(MapTile tile, ITileDataSink mapDataSink) {
+ MultiMapDataSink multiMapDataSink = new MultiMapDataSink(mapDataSink);
+ for (MapDatabase mapDatabase : mapDatabases) {
+ mapDatabase.query(tile, multiMapDataSink);
+ }
+ mapDataSink.completed(multiMapDataSink.getResult());
+ }
+
+ @Override
+ public void dispose() {
+ for (MapDatabase mapDatabase : mapDatabases) {
+ mapDatabase.dispose();
+ }
+ }
+
+ @Override
+ public void cancel() {
+ for (MapDatabase mapDatabase : mapDatabases) {
+ mapDatabase.cancel();
+ }
+ }
+}
diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MultiMapFileTileSource.java b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapFileTileSource.java
new file mode 100644
index 00000000..4f7eb1ff
--- /dev/null
+++ b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapFileTileSource.java
@@ -0,0 +1,100 @@
+/*
+ * 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 org.oscim.core.BoundingBox;
+import org.oscim.tiling.ITileDataSource;
+import org.oscim.tiling.TileSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MultiMapFileTileSource extends TileSource implements IMapFileTileSource {
+
+ private static final Logger log = LoggerFactory.getLogger(MultiMapFileTileSource.class);
+
+ private final List mapFileTileSources = new ArrayList<>();
+
+ public MultiMapFileTileSource() {
+ this(0, 17);
+ }
+
+ public MultiMapFileTileSource(int zoomMin, int zoomMax) {
+ super(zoomMin, zoomMax);
+ }
+
+ public boolean add(MapFileTileSource mapFileTileSource) {
+ if (mapFileTileSources.contains(mapFileTileSource)) {
+ throw new IllegalArgumentException("Duplicate map file tile source");
+ }
+ return mapFileTileSources.add(mapFileTileSource);
+ }
+
+ public BoundingBox getBoundingBox() {
+ BoundingBox boundingBox = null;
+ for (MapFileTileSource mapFileTileSource : mapFileTileSources) {
+ boundingBox = (boundingBox == null) ? mapFileTileSource.getMapInfo().boundingBox : boundingBox.extendBoundingBox(mapFileTileSource.getMapInfo().boundingBox);
+ }
+ return boundingBox;
+ }
+
+ @Override
+ public ITileDataSource getDataSource() {
+ MultiMapDatabase multiMapDatabase = new MultiMapDatabase();
+ for (MapFileTileSource mapFileTileSource : mapFileTileSources) {
+ try {
+ multiMapDatabase.add(new MapDatabase(mapFileTileSource));
+ } catch (IOException e) {
+ log.debug(e.getMessage());
+ }
+ }
+ return multiMapDatabase;
+ }
+
+ @Override
+ public OpenResult open() {
+ OpenResult openResult = OpenResult.SUCCESS;
+ for (MapFileTileSource mapFileTileSource : mapFileTileSources) {
+ OpenResult result = mapFileTileSource.open();
+ if (result != OpenResult.SUCCESS)
+ openResult = result;
+ }
+ return openResult;
+ }
+
+ @Override
+ public void close() {
+ for (MapFileTileSource mapFileTileSource : mapFileTileSources) {
+ mapFileTileSource.close();
+ }
+ }
+
+ @Override
+ public void setCallback(MapFileTileSource.Callback callback) {
+ for (MapFileTileSource mapFileTileSource : mapFileTileSources) {
+ mapFileTileSource.setCallback(callback);
+ }
+ }
+
+ @Override
+ public void setPreferredLanguage(String preferredLanguage) {
+ for (MapFileTileSource mapFileTileSource : mapFileTileSources) {
+ mapFileTileSource.setPreferredLanguage(preferredLanguage);
+ }
+ }
+}