Merge branch 'mapsforge:master' into master

This commit is contained in:
Youcef HILEM 2022-08-29 11:22:35 +02:00 committed by GitHub
commit 6f39bc05c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 135 additions and 102 deletions

View File

@ -1,5 +1,5 @@
plugins { plugins {
id 'com.android.application' version '7.0.4' apply false id 'com.android.application' version '7.2.2' apply false
} }
allprojects { allprojects {
@ -19,12 +19,12 @@ allprojects {
} }
} }
static def androidCompileSdk() { return 31 } static def androidCompileSdk() { return 33 }
// 14 for Support Library, 16 for sqlite-android // 14 for Support Library, 16 for sqlite-android
static def androidMinSdk() { return 21 } static def androidMinSdk() { return 21 }
static def androidTargetSdk() { return 31 } static def androidTargetSdk() { return 33 }
static def versionCode() { return 1 } static def versionCode() { return 1 }

View File

@ -2,6 +2,8 @@
## New since 0.18.0 ## New since 0.18.0
- MVT simplification [#956](https://github.com/mapsforge/vtm/pull/956)
- `Parameters.SIMPLIFICATION_TOLERANCE`, `Parameters.SIMPLIFICATION_EXCEPTIONS`
- Minor improvements and bug fixes - Minor improvements and bug fixes
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.19.0) - [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.19.0)

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2019 Kostas Tzounopoulos * Copyright 2019 Kostas Tzounopoulos
* Copyright 2022 devemux86
* *
* This program is free software: you can redistribute it and/or modify it under the * 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 * terms of the GNU Lesser General Public License as published by the Free Software
@ -27,7 +28,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -134,7 +134,8 @@ public class MBTilesMvtTileDataSource extends MBTilesTileDataSource {
responseDataSink.completed(success ? QueryResult.SUCCESS : QueryResult.FAILED); responseDataSink.completed(success ? QueryResult.SUCCESS : QueryResult.FAILED);
} else } else
responseDataSink.completed(QueryResult.TILE_NOT_FOUND); responseDataSink.completed(QueryResult.TILE_NOT_FOUND);
} catch (IOException e) { } catch (Throwable t) {
log.error(t.getMessage(), t);
responseDataSink.completed(QueryResult.FAILED); responseDataSink.completed(QueryResult.FAILED);
} finally { } finally {
if (cursor != null) if (cursor != null)

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2019 Andrea Antonello * Copyright 2019 Andrea Antonello
* Copyright 2019 devemux86 * Copyright 2019-2022 devemux86
* Copyright 2019 Kostas Tzounopoulos * Copyright 2019 Kostas Tzounopoulos
* *
* This program is free software: you can redistribute it and/or modify it under the * This program is free software: you can redistribute it and/or modify it under the
@ -124,8 +124,8 @@ public class MBTilesBitmapTileDataSource extends MBTilesTileDataSource {
Bitmap bitmap = CanvasAdapter.decodeBitmap(new ByteArrayInputStream(bytes)); Bitmap bitmap = CanvasAdapter.decodeBitmap(new ByteArrayInputStream(bytes));
sink.setTileImage(bitmap); sink.setTileImage(bitmap);
res = QueryResult.SUCCESS; res = QueryResult.SUCCESS;
} catch (Exception e) { } catch (Throwable t) {
log.debug("{} invalid bitmap", tile); log.error(t.getMessage(), t);
} finally { } finally {
sink.completed(res); sink.completed(res);
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2014 Hannes Janetzek * Copyright 2014 Hannes Janetzek
* Copyright 2017 devemux86 * Copyright 2017-2022 devemux86
* Copyright 2018 boldtrn * Copyright 2018 boldtrn
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@ -23,17 +23,26 @@ import com.wdtinc.mapbox_vector_tile.adapt.jts.TagKeyValueMapConverter;
import com.wdtinc.mapbox_vector_tile.adapt.jts.model.JtsLayer; import com.wdtinc.mapbox_vector_tile.adapt.jts.model.JtsLayer;
import com.wdtinc.mapbox_vector_tile.adapt.jts.model.JtsMvt; import com.wdtinc.mapbox_vector_tile.adapt.jts.model.JtsMvt;
import org.locationtech.jts.geom.*; import org.locationtech.jts.geom.*;
import org.locationtech.jts.simplify.TopologyPreservingSimplifier;
import org.oscim.core.MapElement; import org.oscim.core.MapElement;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.source.ITileDecoder; import org.oscim.tiling.source.ITileDecoder;
import org.oscim.utils.Parameters;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Map; import java.util.Map;
public class TileDecoder implements ITileDecoder { public class TileDecoder implements ITileDecoder {
/**
* Reduce points on-the-fly while reading from vector maps.
*/
public static int SIMPLIFICATION_MIN_ZOOM = 8;
public static int SIMPLIFICATION_MAX_ZOOM = 11;
private final String mLocale; private final String mLocale;
private static final float REF_TILE_SIZE = 4096.0f; private static final float REF_TILE_SIZE = 4096.0f;
@ -71,14 +80,14 @@ public class TileDecoder implements ITileDecoder {
for (JtsLayer layer : jtsMvt.getLayers()) { for (JtsLayer layer : jtsMvt.getLayers()) {
for (Geometry geometry : layer.getGeometries()) { for (Geometry geometry : layer.getGeometries()) {
parseGeometry(layer.getName(), geometry, (Map<String, Object>) geometry.getUserData()); parseGeometry(layer.getName(), geometry, (Map<String, Object>) geometry.getUserData(), tile.zoomLevel);
} }
} }
return true; return true;
} }
private void parseGeometry(String layerName, Geometry geometry, Map<String, Object> tags) { private void parseGeometry(String layerName, Geometry geometry, Map<String, Object> tags, int zoomLevel) {
mMapElement.clear(); mMapElement.clear();
mMapElement.tags.clear(); mMapElement.tags.clear();
@ -105,12 +114,11 @@ public class TileDecoder implements ITileDecoder {
processLineString((LineString) multiLineString.getGeometryN(i)); processLineString((LineString) multiLineString.getGeometryN(i));
} }
} else if (geometry instanceof Polygon) { } else if (geometry instanceof Polygon) {
Polygon polygon = (Polygon) geometry; processPolygon((Polygon) simplify(geometry, zoomLevel));
processPolygon(polygon);
} else if (geometry instanceof MultiPolygon) { } else if (geometry instanceof MultiPolygon) {
MultiPolygon multiPolygon = (MultiPolygon) geometry; MultiPolygon multiPolygon = (MultiPolygon) geometry;
for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { for (int i = 0; i < multiPolygon.getNumGeometries(); i++) {
processPolygon((Polygon) multiPolygon.getGeometryN(i)); processPolygon((Polygon) simplify(multiPolygon.getGeometryN(i), zoomLevel));
} }
} else { } else {
err = true; err = true;
@ -169,5 +177,13 @@ public class TileDecoder implements ITileDecoder {
if (!hasName && fallbackName != null) if (!hasName && fallbackName != null)
mMapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false)); mMapElement.tags.add(new Tag(Tag.KEY_NAME, fallbackName, false));
} }
}
private Geometry simplify(Geometry geometry, int zoomLevel) {
if (Parameters.SIMPLIFICATION_TOLERANCE > 0
&& zoomLevel >= SIMPLIFICATION_MIN_ZOOM && zoomLevel <= SIMPLIFICATION_MAX_ZOOM) {
if (!mMapElement.tags.contains(Parameters.SIMPLIFICATION_EXCEPTIONS))
return TopologyPreservingSimplifier.simplify(geometry, Parameters.SIMPLIFICATION_TOLERANCE * 10);
}
return geometry;
}
}

View File

@ -2,7 +2,7 @@
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2016 Izumi Kawashima * Copyright 2016 Izumi Kawashima
* Copyright 2017 Longri * Copyright 2017 Longri
* Copyright 2017-2020 devemux86 * Copyright 2017-2022 devemux86
* Copyright 2017 nebular * Copyright 2017 nebular
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@ -170,6 +170,8 @@ public class MarkerRenderer extends BucketRenderer {
InternalItem it = new InternalItem(); InternalItem it = new InternalItem();
tmp[i] = it; tmp[i] = it;
it.item = mMarkerLayer.createItem(i); it.item = mMarkerLayer.createItem(i);
if (it.item == null)
continue;
/* pre-project points */ /* pre-project points */
MercatorProjection.project(it.item.getPoint(), mMapPoint); MercatorProjection.project(it.item.getPoint(), mMapPoint);

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2022 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).
* *
@ -64,8 +65,8 @@ public abstract class TileLoader extends PausableThread implements ITileDataSink
try { try {
loadTile(mTile); loadTile(mTile);
} catch (Exception e) { } catch (Throwable t) {
e.printStackTrace(); t.printStackTrace();
completed(FAILED); completed(FAILED);
} }
} }

View File

@ -121,9 +121,9 @@ public class VectorTileLoader extends TileLoader implements RenderStyle.Callback
} catch (NullPointerException e) { } catch (NullPointerException e) {
log.debug("NPE {} {}", tile, e.getMessage()); log.debug("NPE {} {}", tile, e.getMessage());
e.printStackTrace(); e.printStackTrace();
} catch (Exception e) { } catch (Throwable t) {
log.debug("{} {}", tile, e.getMessage()); log.debug("{} {}", tile, t.getMessage());
e.printStackTrace(); t.printStackTrace();
return false; return false;
} }
return true; return true;

View File

@ -1,7 +1,7 @@
/* /*
* Copyright 2012, 2013 Hannes Janetzek * Copyright 2012, 2013 Hannes Janetzek
* Copyright 2017 Wolfgang Schramm * Copyright 2017 Wolfgang Schramm
* Copyright 2017-2018 devemux86 * Copyright 2017-2022 devemux86
* Copyright 2017 Andrey Novikov * Copyright 2017 Andrey Novikov
* Copyright 2018 Gustl22 * Copyright 2018 Gustl22
* *
@ -30,13 +30,11 @@ import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.map.Viewport; import org.oscim.map.Viewport;
import org.oscim.utils.async.SimpleWorker; import org.oscim.utils.async.SimpleWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LabelLayer extends Layer implements Map.UpdateListener, TileManager.Listener, public class LabelLayer extends Layer implements Map.UpdateListener, TileManager.Listener,
ZoomLimiter.IZoomLimiter { ZoomLimiter.IZoomLimiter {
static final Logger log = LoggerFactory.getLogger(LabelLayer.class); //private static final Logger log = LoggerFactory.getLogger(LabelLayer.class);
static final String LABEL_DATA = LabelLayer.class.getName(); static final String LABEL_DATA = LabelLayer.class.getName();
@ -60,8 +58,6 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager
public LabelLayer(Map map, VectorTileLayer l, VectorTileLayer.TileLoaderThemeHook h, public LabelLayer(Map map, VectorTileLayer l, VectorTileLayer.TileLoaderThemeHook h,
int zoomLimit) { int zoomLimit) {
super(map); super(map);
l.getManager().events.bind(this);
l.addHook(h);
mZoomLimiter = new ZoomLimiter(l.getManager(), map.viewport().getMinZoomLevel(), mZoomLimiter = new ZoomLimiter(l.getManager(), map.viewport().getMinZoomLevel(),
map.viewport().getMaxZoomLevel(), zoomLimit); map.viewport().getMaxZoomLevel(), zoomLimit);
@ -69,6 +65,9 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager
mLabelPlacer = new LabelPlacement(map, l.tileRenderer(), mZoomLimiter); mLabelPlacer = new LabelPlacement(map, l.tileRenderer(), mZoomLimiter);
mWorker = new Worker(map); mWorker = new Worker(map);
mRenderer = new TextRenderer(mWorker); mRenderer = new TextRenderer(mWorker);
l.getManager().events.bind(this);
l.addHook(h);
} }
class Worker extends SimpleWorker<LabelTask> { class Worker extends SimpleWorker<LabelTask> {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2018 devemux86 * Copyright 2018-2022 devemux86
* *
* This program is free software: you can redistribute it and/or modify it under the * 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 * terms of the GNU Lesser General Public License as published by the Free Software
@ -15,9 +15,13 @@
package org.oscim.tiling; package org.oscim.tiling;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OverzoomTileDataSource implements ITileDataSource { public class OverzoomTileDataSource implements ITileDataSource {
private static final Logger log = LoggerFactory.getLogger(OverzoomTileDataSource.class);
private final ITileDataSource tileDataSource; private final ITileDataSource tileDataSource;
private final int overZoom; private final int overZoom;
@ -32,14 +36,18 @@ public class OverzoomTileDataSource implements ITileDataSource {
@Override @Override
public void query(MapTile tile, ITileDataSink sink) { public void query(MapTile tile, ITileDataSink sink) {
MapTile mapTile = tile; try {
ITileDataSink dataSink = sink; MapTile mapTile = tile;
int diff = tile.zoomLevel - overZoom; ITileDataSink dataSink = sink;
if (diff > 0) { int diff = tile.zoomLevel - overZoom;
mapTile = new MapTile(tile.node, tile.tileX >> diff, tile.tileY >> diff, overZoom); if (diff > 0) {
dataSink = new OverzoomDataSink(sink, mapTile, tile); mapTile = new MapTile(tile.node, tile.tileX >> diff, tile.tileY >> diff, overZoom);
dataSink = new OverzoomDataSink(sink, mapTile, tile);
}
tileDataSource.query(mapTile, dataSink);
} catch (Throwable t) {
log.error(t.getMessage(), t);
} }
tileDataSource.query(mapTile, dataSink);
} }
@Override @Override

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2012 Hannes Janetzek * Copyright 2012 Hannes Janetzek
* Copyright 2017 devemux86 * Copyright 2017-2022 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).
* *
@ -34,12 +34,9 @@ import java.net.SocketException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import static org.oscim.tiling.QueryResult.DELAYED;
import static org.oscim.tiling.QueryResult.FAILED;
import static org.oscim.tiling.QueryResult.SUCCESS;
public class UrlTileDataSource implements ITileDataSource { public class UrlTileDataSource implements ITileDataSource {
static final Logger log = LoggerFactory.getLogger(UrlTileDataSource.class);
private static final Logger log = LoggerFactory.getLogger(UrlTileDataSource.class);
protected final HttpEngine mConn; protected final HttpEngine mConn;
protected final ITileDecoder mTileDecoder; protected final ITileDecoder mTileDecoder;
@ -57,27 +54,27 @@ public class UrlTileDataSource implements ITileDataSource {
public void query(MapTile tile, ITileDataSink sink) { public void query(MapTile tile, ITileDataSink sink) {
ITileCache cache = mTileSource.tileCache; ITileCache cache = mTileSource.tileCache;
if (mUseCache) { QueryResult res = QueryResult.FAILED;
TileReader c = cache.getTile(tile);
if (c != null) {
InputStream is = c.getInputStream();
try {
if (mTileDecoder.decode(tile, sink, is)) {
sink.completed(SUCCESS);
return;
}
} catch (IOException e) {
log.debug("{} Cache read: {}", tile, e);
} finally {
IOUtils.closeQuietly(is);
}
}
}
QueryResult res = FAILED;
TileWriter cacheWriter = null; TileWriter cacheWriter = null;
try { try {
if (mUseCache) {
TileReader c = cache.getTile(tile);
if (c != null) {
InputStream is = c.getInputStream();
try {
if (mTileDecoder.decode(tile, sink, is)) {
sink.completed(QueryResult.SUCCESS);
return;
}
} catch (IOException e) {
log.debug("{} Cache read: {}", tile, e);
} finally {
IOUtils.closeQuietly(is);
}
}
}
mConn.sendRequest(tile); mConn.sendRequest(tile);
InputStream is = mConn.read(); InputStream is = mConn.read();
if (mUseCache) { if (mUseCache) {
@ -85,23 +82,25 @@ public class UrlTileDataSource implements ITileDataSource {
mConn.setCache(cacheWriter.getOutputStream()); mConn.setCache(cacheWriter.getOutputStream());
} }
if (mTileDecoder.decode(tile, sink, is)) if (mTileDecoder.decode(tile, sink, is))
res = SUCCESS; res = QueryResult.SUCCESS;
} catch (SocketException e) { } catch (SocketException e) {
log.debug("{} Socket Error: {}", tile, e.getMessage()); log.debug("{} Socket Error: {}", tile, e.getMessage());
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
log.debug("{} Socket Timeout", tile); log.debug("{} Socket Timeout", tile);
res = DELAYED; res = QueryResult.DELAYED;
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
log.debug("{} Unknown host: {}", tile, e.getMessage()); log.debug("{} Unknown host: {}", tile, e.getMessage());
} catch (IOException e) { } catch (IOException e) {
log.debug("{} Network Error: {}", tile, e.getMessage()); log.debug("{} Network Error: {}", tile, e.getMessage());
} catch (Exception e) { } catch (Exception e) {
log.debug("{} Error: {}", tile, e.getMessage()); log.debug("{} Error: {}", tile, e.getMessage());
} catch (Throwable t) {
log.error(t.getMessage(), t);
} finally { } finally {
boolean ok = (res == SUCCESS); boolean ok = (res == QueryResult.SUCCESS);
if (!mConn.requestCompleted(ok) && ok) if (!mConn.requestCompleted(ok) && ok)
res = FAILED; res = QueryResult.FAILED;
if (cacheWriter != null) if (cacheWriter != null)
cacheWriter.complete(ok); cacheWriter.complete(ok);

View File

@ -31,6 +31,7 @@ import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.buildings.BuildingLayer; import org.oscim.layers.tile.buildings.BuildingLayer;
import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.QueryResult;
import org.oscim.tiling.TileDataSink; import org.oscim.tiling.TileDataSink;
import org.oscim.tiling.source.mapfile.header.SubFileParameter; import org.oscim.tiling.source.mapfile.header.SubFileParameter;
import org.oscim.utils.Parameters; import org.oscim.utils.Parameters;
@ -46,11 +47,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.oscim.core.GeometryBuffer.GeometryType.LINE;
import static org.oscim.core.GeometryBuffer.GeometryType.POLY;
import static org.oscim.tiling.QueryResult.FAILED;
import static org.oscim.tiling.QueryResult.SUCCESS;
/** /**
* A class for reading binary map files. * A class for reading binary map files.
* *
@ -85,7 +81,7 @@ public class MapDatabase implements ITileDataSource {
*/ */
private static final String INVALID_FIRST_WAY_OFFSET = "invalid first way offset: "; private static final String INVALID_FIRST_WAY_OFFSET = "invalid first way offset: ";
static final Logger log = LoggerFactory.getLogger(MapDatabase.class); private static final Logger log = LoggerFactory.getLogger(MapDatabase.class);
/** /**
* Bitmask for the optional POI feature "elevation". * Bitmask for the optional POI feature "elevation".
@ -257,16 +253,15 @@ public class MapDatabase implements ITileDataSource {
@Override @Override
public void query(MapTile tile, ITileDataSink sink) { public void query(MapTile tile, ITileDataSink sink) {
if (mTileSource.fileHeader == null) {
sink.completed(FAILED);
return;
}
if (mIntBuffer == null)
mIntBuffer = new int[Short.MAX_VALUE * 2];
try { try {
if (mTileSource.fileHeader == null) {
sink.completed(QueryResult.FAILED);
return;
}
if (mIntBuffer == null)
mIntBuffer = new int[Short.MAX_VALUE * 2];
mTileProjection.setTile(tile); mTileProjection.setTile(tile);
//mTile = tile; //mTile = tile;
@ -303,7 +298,7 @@ public class MapDatabase implements ITileDataSource {
log.warn("no sub-file for zoom level: " log.warn("no sub-file for zoom level: "
+ queryParameters.queryZoomLevel); + queryParameters.queryZoomLevel);
sink.completed(FAILED); sink.completed(QueryResult.FAILED);
return; return;
} }
@ -313,13 +308,13 @@ public class MapDatabase implements ITileDataSource {
processBlocks(sink, queryParameters, subFileParameter, tile.getBoundingBox(), Selector.ALL, new MapReadResult()); processBlocks(sink, queryParameters, subFileParameter, tile.getBoundingBox(), Selector.ALL, new MapReadResult());
else else
processBlocks(sink, queryParameters, subFileParameter); processBlocks(sink, queryParameters, subFileParameter);
} catch (IOException e) { } catch (Throwable t) {
log.error(e.getMessage()); log.error(t.getMessage(), t);
sink.completed(FAILED); sink.completed(QueryResult.FAILED);
return; return;
} }
sink.completed(SUCCESS); sink.completed(QueryResult.SUCCESS);
} }
@Override @Override
@ -826,7 +821,7 @@ public class MapDatabase implements ITileDataSource {
} }
if (e.type == GeometryType.NONE) if (e.type == GeometryType.NONE)
e.type = line ? LINE : POLY; e.type = line ? GeometryType.LINE : GeometryType.POLY;
} else if (lat == pLat && lon == pLon) { } else if (lat == pLat && lon == pLon) {
/* drop small distance intermediate nodes */ /* drop small distance intermediate nodes */

View File

@ -20,12 +20,16 @@ import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.QueryResult; import org.oscim.tiling.QueryResult;
import org.oscim.tiling.TileDataSink; import org.oscim.tiling.TileDataSink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MultiMapDatabase implements ITileDataSource { public class MultiMapDatabase implements ITileDataSource {
private static final Logger log = LoggerFactory.getLogger(MultiMapDatabase.class);
private final boolean deduplicate; private final boolean deduplicate;
private final List<MapDatabase> mapDatabases = new ArrayList<>(); private final List<MapDatabase> mapDatabases = new ArrayList<>();
@ -46,28 +50,34 @@ public class MultiMapDatabase implements ITileDataSource {
@Override @Override
public void query(MapTile tile, ITileDataSink sink) { public void query(MapTile tile, ITileDataSink sink) {
boolean deduplicate = this.deduplicate; try {
if (deduplicate) { boolean deduplicate = this.deduplicate;
int n = 0; if (deduplicate) {
for (MapDatabase mapDatabase : mapDatabases) { int n = 0;
if (mapDatabase.supportsTile(tile)) { for (MapDatabase mapDatabase : mapDatabases) {
if (++n > 1) { if (mapDatabase.supportsTile(tile)) {
break; if (++n > 1) {
break;
}
} }
} }
deduplicate = n > 1;
} }
deduplicate = n > 1;
}
TileDataSink dataSink = new TileDataSink(sink); TileDataSink dataSink = new TileDataSink(sink);
for (int i = 0, n = mapDatabases.size(); i < n; i++) { for (int i = 0, n = mapDatabases.size(); i < n; i++) {
MapDatabase mapDatabase = mapDatabases.get(i); MapDatabase mapDatabase = mapDatabases.get(i);
if (mapDatabase.supportsTile(tile)) { if (mapDatabase.supportsTile(tile)) {
mapDatabase.setDeduplicate(deduplicate); mapDatabase.setDeduplicate(deduplicate);
dataSink.level = i + 1; dataSink.level = i + 1;
dataSink.levels = n; dataSink.levels = n;
mapDatabase.query(tile, dataSink); mapDatabase.query(tile, dataSink);
}
} }
} catch (Throwable t) {
log.error(t.getMessage(), t);
sink.completed(QueryResult.FAILED);
return;
} }
sink.completed(QueryResult.SUCCESS); sink.completed(QueryResult.SUCCESS);
} }

View File

@ -85,7 +85,7 @@ public final class Parameters {
public static final Set<Tag> SIMPLIFICATION_EXCEPTIONS = new HashSet<>(); public static final Set<Tag> SIMPLIFICATION_EXCEPTIONS = new HashSet<>();
/** /**
* Reduce points on-the-fly while reading from map files. * Reduce points on-the-fly while reading from vector maps.
* e.g. 0 (no simplification), 2, 4, ... * e.g. 0 (no simplification), 2, 4, ...
*/ */
public static int SIMPLIFICATION_TOLERANCE = 0; public static int SIMPLIFICATION_TOLERANCE = 0;