Mapsforge: catch unexpected errors (#942)

This commit is contained in:
Emux 2022-07-29 15:32:58 +03:00 committed by GitHub
parent f570105920
commit d89a402375
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 38 deletions

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);
} }