From f5701059206e9f04ec4018bb145ea8b86fcd7cb0 Mon Sep 17 00:00:00 2001 From: Emux Date: Wed, 27 Jul 2022 17:02:34 +0300 Subject: [PATCH 1/7] Update Android Gradle plugin (#941) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 044e358e..43c400c7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.android.application' version '7.0.4' apply false + id 'com.android.application' version '7.2.1' apply false } allprojects { From d89a402375ee30a0dfd64f226fdbae0decb5874b Mon Sep 17 00:00:00 2001 From: Emux Date: Fri, 29 Jul 2022 15:32:58 +0300 Subject: [PATCH 2/7] Mapsforge: catch unexpected errors (#942) --- .../tiling/source/mapfile/MapDatabase.java | 37 +++++++--------- .../source/mapfile/MultiMapDatabase.java | 44 ++++++++++++------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java b/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java index 5b6b56f2..c2b54028 100644 --- a/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java +++ b/vtm/src/org/oscim/tiling/source/mapfile/MapDatabase.java @@ -31,6 +31,7 @@ import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.buildings.BuildingLayer; import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSource; +import org.oscim.tiling.QueryResult; import org.oscim.tiling.TileDataSink; import org.oscim.tiling.source.mapfile.header.SubFileParameter; import org.oscim.utils.Parameters; @@ -46,11 +47,6 @@ import java.util.ArrayList; import java.util.Collections; 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. * @@ -85,7 +81,7 @@ public class MapDatabase implements ITileDataSource { */ 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". @@ -257,16 +253,15 @@ public class MapDatabase implements ITileDataSource { @Override 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 { + if (mTileSource.fileHeader == null) { + sink.completed(QueryResult.FAILED); + return; + } + + if (mIntBuffer == null) + mIntBuffer = new int[Short.MAX_VALUE * 2]; + mTileProjection.setTile(tile); //mTile = tile; @@ -303,7 +298,7 @@ public class MapDatabase implements ITileDataSource { log.warn("no sub-file for zoom level: " + queryParameters.queryZoomLevel); - sink.completed(FAILED); + sink.completed(QueryResult.FAILED); return; } @@ -313,13 +308,13 @@ public class MapDatabase implements ITileDataSource { processBlocks(sink, queryParameters, subFileParameter, tile.getBoundingBox(), Selector.ALL, new MapReadResult()); else processBlocks(sink, queryParameters, subFileParameter); - } catch (IOException e) { - log.error(e.getMessage()); - sink.completed(FAILED); + } catch (Throwable t) { + log.error(t.getMessage(), t); + sink.completed(QueryResult.FAILED); return; } - sink.completed(SUCCESS); + sink.completed(QueryResult.SUCCESS); } @Override @@ -826,7 +821,7 @@ public class MapDatabase implements ITileDataSource { } if (e.type == GeometryType.NONE) - e.type = line ? LINE : POLY; + e.type = line ? GeometryType.LINE : GeometryType.POLY; } else if (lat == pLat && lon == pLon) { /* drop small distance intermediate nodes */ diff --git a/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java index 1bb094fe..2f7569c5 100644 --- a/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java +++ b/vtm/src/org/oscim/tiling/source/mapfile/MultiMapDatabase.java @@ -20,12 +20,16 @@ import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.QueryResult; import org.oscim.tiling.TileDataSink; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; public class MultiMapDatabase implements ITileDataSource { + private static final Logger log = LoggerFactory.getLogger(MultiMapDatabase.class); + private final boolean deduplicate; private final List mapDatabases = new ArrayList<>(); @@ -46,28 +50,34 @@ public class MultiMapDatabase implements ITileDataSource { @Override public void query(MapTile tile, ITileDataSink sink) { - boolean deduplicate = this.deduplicate; - if (deduplicate) { - int n = 0; - for (MapDatabase mapDatabase : mapDatabases) { - if (mapDatabase.supportsTile(tile)) { - if (++n > 1) { - break; + try { + boolean deduplicate = this.deduplicate; + if (deduplicate) { + int n = 0; + for (MapDatabase mapDatabase : mapDatabases) { + if (mapDatabase.supportsTile(tile)) { + if (++n > 1) { + break; + } } } + deduplicate = n > 1; } - deduplicate = n > 1; - } - TileDataSink dataSink = new TileDataSink(sink); - for (int i = 0, n = mapDatabases.size(); i < n; i++) { - MapDatabase mapDatabase = mapDatabases.get(i); - if (mapDatabase.supportsTile(tile)) { - mapDatabase.setDeduplicate(deduplicate); - dataSink.level = i + 1; - dataSink.levels = n; - mapDatabase.query(tile, dataSink); + TileDataSink dataSink = new TileDataSink(sink); + for (int i = 0, n = mapDatabases.size(); i < n; i++) { + MapDatabase mapDatabase = mapDatabases.get(i); + if (mapDatabase.supportsTile(tile)) { + mapDatabase.setDeduplicate(deduplicate); + dataSink.level = i + 1; + dataSink.levels = n; + mapDatabase.query(tile, dataSink); + } } + } catch (Throwable t) { + log.error(t.getMessage(), t); + sink.completed(QueryResult.FAILED); + return; } sink.completed(QueryResult.SUCCESS); } From e86bf54d8a08604400dda318d8ca8b96e0aad1d7 Mon Sep 17 00:00:00 2001 From: Emux Date: Thu, 4 Aug 2022 12:52:44 +0300 Subject: [PATCH 3/7] TileDataSource: catch unexpected errors (#943) --- .../mbtiles/MBTilesMvtTileDataSource.java | 5 +- .../mbtiles/MBTilesBitmapTileDataSource.java | 6 +- vtm/src/org/oscim/layers/tile/TileLoader.java | 5 +- .../layers/tile/vector/VectorTileLoader.java | 6 +- .../oscim/tiling/OverzoomTileDataSource.java | 24 +++++--- .../tiling/source/UrlTileDataSource.java | 55 +++++++++---------- 6 files changed, 55 insertions(+), 46 deletions(-) diff --git a/vtm-android-mvt/src/org/oscim/android/mvt/tiling/source/mbtiles/MBTilesMvtTileDataSource.java b/vtm-android-mvt/src/org/oscim/android/mvt/tiling/source/mbtiles/MBTilesMvtTileDataSource.java index 79cf6a86..418b3e39 100644 --- a/vtm-android-mvt/src/org/oscim/android/mvt/tiling/source/mbtiles/MBTilesMvtTileDataSource.java +++ b/vtm-android-mvt/src/org/oscim/android/mvt/tiling/source/mbtiles/MBTilesMvtTileDataSource.java @@ -1,5 +1,6 @@ /* * Copyright 2019 Kostas Tzounopoulos + * Copyright 2022 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 @@ -27,7 +28,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -134,7 +134,8 @@ public class MBTilesMvtTileDataSource extends MBTilesTileDataSource { responseDataSink.completed(success ? QueryResult.SUCCESS : QueryResult.FAILED); } else responseDataSink.completed(QueryResult.TILE_NOT_FOUND); - } catch (IOException e) { + } catch (Throwable t) { + log.error(t.getMessage(), t); responseDataSink.completed(QueryResult.FAILED); } finally { if (cursor != null) diff --git a/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTilesBitmapTileDataSource.java b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTilesBitmapTileDataSource.java index 7f12f4a3..ad086d7d 100644 --- a/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTilesBitmapTileDataSource.java +++ b/vtm-android/src/org/oscim/android/tiling/source/mbtiles/MBTilesBitmapTileDataSource.java @@ -1,6 +1,6 @@ /* * Copyright 2019 Andrea Antonello - * Copyright 2019 devemux86 + * Copyright 2019-2022 devemux86 * Copyright 2019 Kostas Tzounopoulos * * 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)); sink.setTileImage(bitmap); res = QueryResult.SUCCESS; - } catch (Exception e) { - log.debug("{} invalid bitmap", tile); + } catch (Throwable t) { + log.error(t.getMessage(), t); } finally { sink.completed(res); } diff --git a/vtm/src/org/oscim/layers/tile/TileLoader.java b/vtm/src/org/oscim/layers/tile/TileLoader.java index 70da7e3a..838dec5f 100644 --- a/vtm/src/org/oscim/layers/tile/TileLoader.java +++ b/vtm/src/org/oscim/layers/tile/TileLoader.java @@ -1,5 +1,6 @@ /* * Copyright 2013 Hannes Janetzek + * Copyright 2022 devemux86 * * 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 { loadTile(mTile); - } catch (Exception e) { - e.printStackTrace(); + } catch (Throwable t) { + t.printStackTrace(); completed(FAILED); } } diff --git a/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java b/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java index 748df2b5..0c64844d 100644 --- a/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java +++ b/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java @@ -121,9 +121,9 @@ public class VectorTileLoader extends TileLoader implements RenderStyle.Callback } catch (NullPointerException e) { log.debug("NPE {} {}", tile, e.getMessage()); e.printStackTrace(); - } catch (Exception e) { - log.debug("{} {}", tile, e.getMessage()); - e.printStackTrace(); + } catch (Throwable t) { + log.debug("{} {}", tile, t.getMessage()); + t.printStackTrace(); return false; } return true; diff --git a/vtm/src/org/oscim/tiling/OverzoomTileDataSource.java b/vtm/src/org/oscim/tiling/OverzoomTileDataSource.java index 9eb4cea8..9e3afcaa 100644 --- a/vtm/src/org/oscim/tiling/OverzoomTileDataSource.java +++ b/vtm/src/org/oscim/tiling/OverzoomTileDataSource.java @@ -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 * terms of the GNU Lesser General Public License as published by the Free Software @@ -15,9 +15,13 @@ package org.oscim.tiling; import org.oscim.layers.tile.MapTile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class OverzoomTileDataSource implements ITileDataSource { + private static final Logger log = LoggerFactory.getLogger(OverzoomTileDataSource.class); + private final ITileDataSource tileDataSource; private final int overZoom; @@ -32,14 +36,18 @@ public class OverzoomTileDataSource implements ITileDataSource { @Override public void query(MapTile tile, ITileDataSink sink) { - MapTile mapTile = tile; - ITileDataSink dataSink = sink; - int diff = tile.zoomLevel - overZoom; - if (diff > 0) { - mapTile = new MapTile(tile.node, tile.tileX >> diff, tile.tileY >> diff, overZoom); - dataSink = new OverzoomDataSink(sink, mapTile, tile); + try { + MapTile mapTile = tile; + ITileDataSink dataSink = sink; + int diff = tile.zoomLevel - overZoom; + if (diff > 0) { + 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 diff --git a/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java b/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java index a65ecae6..865e9a6c 100644 --- a/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java +++ b/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java @@ -1,6 +1,6 @@ /* * Copyright 2012 Hannes Janetzek - * Copyright 2017 devemux86 + * Copyright 2017-2022 devemux86 * * 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.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 { - static final Logger log = LoggerFactory.getLogger(UrlTileDataSource.class); + + private static final Logger log = LoggerFactory.getLogger(UrlTileDataSource.class); protected final HttpEngine mConn; protected final ITileDecoder mTileDecoder; @@ -57,27 +54,27 @@ public class UrlTileDataSource implements ITileDataSource { public void query(MapTile tile, ITileDataSink sink) { ITileCache cache = mTileSource.tileCache; - if (mUseCache) { - 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; + QueryResult res = QueryResult.FAILED; TileWriter cacheWriter = null; 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); InputStream is = mConn.read(); if (mUseCache) { @@ -85,23 +82,25 @@ public class UrlTileDataSource implements ITileDataSource { mConn.setCache(cacheWriter.getOutputStream()); } if (mTileDecoder.decode(tile, sink, is)) - res = SUCCESS; + res = QueryResult.SUCCESS; } catch (SocketException e) { log.debug("{} Socket Error: {}", tile, e.getMessage()); } catch (SocketTimeoutException e) { log.debug("{} Socket Timeout", tile); - res = DELAYED; + res = QueryResult.DELAYED; } catch (UnknownHostException e) { log.debug("{} Unknown host: {}", tile, e.getMessage()); } catch (IOException e) { log.debug("{} Network Error: {}", tile, e.getMessage()); } catch (Exception e) { log.debug("{} Error: {}", tile, e.getMessage()); + } catch (Throwable t) { + log.error(t.getMessage(), t); } finally { - boolean ok = (res == SUCCESS); + boolean ok = (res == QueryResult.SUCCESS); if (!mConn.requestCompleted(ok) && ok) - res = FAILED; + res = QueryResult.FAILED; if (cacheWriter != null) cacheWriter.complete(ok); From 4f69560cf3f41c3f409f943d3616bec7e2b62763 Mon Sep 17 00:00:00 2001 From: Emux Date: Thu, 4 Aug 2022 13:00:14 +0300 Subject: [PATCH 4/7] MarkerRenderer: prevent possible NPE (#944) --- vtm/src/org/oscim/layers/marker/MarkerRenderer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vtm/src/org/oscim/layers/marker/MarkerRenderer.java b/vtm/src/org/oscim/layers/marker/MarkerRenderer.java index 996439c6..1185b91c 100644 --- a/vtm/src/org/oscim/layers/marker/MarkerRenderer.java +++ b/vtm/src/org/oscim/layers/marker/MarkerRenderer.java @@ -2,7 +2,7 @@ * Copyright 2013 Hannes Janetzek * Copyright 2016 Izumi Kawashima * Copyright 2017 Longri - * Copyright 2017-2020 devemux86 + * Copyright 2017-2022 devemux86 * Copyright 2017 nebular * * 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(); tmp[i] = it; it.item = mMarkerLayer.createItem(i); + if (it.item == null) + continue; /* pre-project points */ MercatorProjection.project(it.item.getPoint(), mMapPoint); From 002877ff5fc5424730561c445941273197f8b3d8 Mon Sep 17 00:00:00 2001 From: Emux Date: Mon, 8 Aug 2022 13:21:23 +0300 Subject: [PATCH 5/7] LabelLayer: improve constructor (#945) --- .../oscim/layers/tile/vector/labeling/LabelLayer.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/vtm/src/org/oscim/layers/tile/vector/labeling/LabelLayer.java b/vtm/src/org/oscim/layers/tile/vector/labeling/LabelLayer.java index 23eb5d0f..40dc9eb1 100644 --- a/vtm/src/org/oscim/layers/tile/vector/labeling/LabelLayer.java +++ b/vtm/src/org/oscim/layers/tile/vector/labeling/LabelLayer.java @@ -1,7 +1,7 @@ /* * Copyright 2012, 2013 Hannes Janetzek * Copyright 2017 Wolfgang Schramm - * Copyright 2017-2018 devemux86 + * Copyright 2017-2022 devemux86 * Copyright 2017 Andrey Novikov * Copyright 2018 Gustl22 * @@ -30,13 +30,11 @@ import org.oscim.layers.tile.vector.VectorTileLayer; import org.oscim.map.Map; import org.oscim.map.Viewport; import org.oscim.utils.async.SimpleWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class LabelLayer extends Layer implements Map.UpdateListener, TileManager.Listener, 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(); @@ -60,8 +58,6 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager public LabelLayer(Map map, VectorTileLayer l, VectorTileLayer.TileLoaderThemeHook h, int zoomLimit) { super(map); - l.getManager().events.bind(this); - l.addHook(h); mZoomLimiter = new ZoomLimiter(l.getManager(), map.viewport().getMinZoomLevel(), map.viewport().getMaxZoomLevel(), zoomLimit); @@ -69,6 +65,9 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager mLabelPlacer = new LabelPlacement(map, l.tileRenderer(), mZoomLimiter); mWorker = new Worker(map); mRenderer = new TextRenderer(mWorker); + + l.getManager().events.bind(this); + l.addHook(h); } class Worker extends SimpleWorker { From 7b0a5249b7080bf81c277fd332152572374dfcb0 Mon Sep 17 00:00:00 2001 From: Emux Date: Tue, 16 Aug 2022 11:27:35 +0300 Subject: [PATCH 6/7] Android 13 (#950) --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 43c400c7..a3b7ddc6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.android.application' version '7.2.1' apply false + id 'com.android.application' version '7.2.2' apply false } allprojects { @@ -19,12 +19,12 @@ allprojects { } } -static def androidCompileSdk() { return 31 } +static def androidCompileSdk() { return 33 } // 14 for Support Library, 16 for sqlite-android static def androidMinSdk() { return 21 } -static def androidTargetSdk() { return 31 } +static def androidTargetSdk() { return 33 } static def versionCode() { return 1 } From 575c2c2b34e3dbe16886978ad0eb70a14bbfab53 Mon Sep 17 00:00:00 2001 From: Emux Date: Wed, 24 Aug 2022 15:39:01 +0300 Subject: [PATCH 7/7] MVT simplification (#956) --- docs/Changelog.md | 2 ++ .../oscim/tiling/source/mvt/TileDecoder.java | 30 ++++++++++++++----- vtm/src/org/oscim/utils/Parameters.java | 2 +- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 2ebdb3ed..746eafcd 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -2,6 +2,8 @@ ## 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 - [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.19.0) diff --git a/vtm-mvt/src/org/oscim/tiling/source/mvt/TileDecoder.java b/vtm-mvt/src/org/oscim/tiling/source/mvt/TileDecoder.java index a0494d5e..fca5c31a 100644 --- a/vtm-mvt/src/org/oscim/tiling/source/mvt/TileDecoder.java +++ b/vtm-mvt/src/org/oscim/tiling/source/mvt/TileDecoder.java @@ -1,6 +1,6 @@ /* * Copyright 2014 Hannes Janetzek - * Copyright 2017 devemux86 + * Copyright 2017-2022 devemux86 * Copyright 2018 boldtrn * * 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.JtsMvt; import org.locationtech.jts.geom.*; +import org.locationtech.jts.simplify.TopologyPreservingSimplifier; import org.oscim.core.MapElement; import org.oscim.core.Tag; import org.oscim.core.Tile; import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.source.ITileDecoder; +import org.oscim.utils.Parameters; import java.io.IOException; import java.io.InputStream; import java.util.Map; 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 static final float REF_TILE_SIZE = 4096.0f; @@ -71,14 +80,14 @@ public class TileDecoder implements ITileDecoder { for (JtsLayer layer : jtsMvt.getLayers()) { for (Geometry geometry : layer.getGeometries()) { - parseGeometry(layer.getName(), geometry, (Map) geometry.getUserData()); + parseGeometry(layer.getName(), geometry, (Map) geometry.getUserData(), tile.zoomLevel); } } return true; } - private void parseGeometry(String layerName, Geometry geometry, Map tags) { + private void parseGeometry(String layerName, Geometry geometry, Map tags, int zoomLevel) { mMapElement.clear(); mMapElement.tags.clear(); @@ -105,12 +114,11 @@ public class TileDecoder implements ITileDecoder { processLineString((LineString) multiLineString.getGeometryN(i)); } } else if (geometry instanceof Polygon) { - Polygon polygon = (Polygon) geometry; - processPolygon(polygon); + processPolygon((Polygon) simplify(geometry, zoomLevel)); } else if (geometry instanceof MultiPolygon) { MultiPolygon multiPolygon = (MultiPolygon) geometry; for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { - processPolygon((Polygon) multiPolygon.getGeometryN(i)); + processPolygon((Polygon) simplify(multiPolygon.getGeometryN(i), zoomLevel)); } } else { err = true; @@ -169,5 +177,13 @@ public class TileDecoder implements ITileDecoder { if (!hasName && fallbackName != null) 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; + } +} diff --git a/vtm/src/org/oscim/utils/Parameters.java b/vtm/src/org/oscim/utils/Parameters.java index a88aa6a1..1216af53 100644 --- a/vtm/src/org/oscim/utils/Parameters.java +++ b/vtm/src/org/oscim/utils/Parameters.java @@ -85,7 +85,7 @@ public final class Parameters { public static final Set 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, ... */ public static int SIMPLIFICATION_TOLERANCE = 0;