From a6b3d7b0c29d41d38fb98ba7ff1af490d6f7b6fb Mon Sep 17 00:00:00 2001 From: Emux Date: Mon, 31 Oct 2016 14:45:16 +0200 Subject: [PATCH] Mapsforge: multiple map files, closes #208 --- docs/Changelog.md | 3 +- .../org/oscim/test/MapsforgeMultiTest.java | 85 +++++++++++++++ .../source/mapfile/IMapFileTileSource.java | 22 ++++ .../source/mapfile/MapFileTileSource.java | 4 +- .../source/mapfile/MultiMapDataSink.java | 49 +++++++++ .../source/mapfile/MultiMapDatabase.java | 57 ++++++++++ .../mapfile/MultiMapFileTileSource.java | 100 ++++++++++++++++++ 7 files changed, 318 insertions(+), 2 deletions(-) create mode 100644 vtm-playground/src/org/oscim/test/MapsforgeMultiTest.java create mode 100644 vtm/src/org/oscim/tiling/source/mapfile/IMapFileTileSource.java create mode 100644 vtm/src/org/oscim/tiling/source/mapfile/MultiMapDataSink.java create mode 100644 vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java create mode 100644 vtm/src/org/oscim/tiling/source/mapfile/MultiMapFileTileSource.java 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); + } + } +}