From 4367dda5a4ea506617182316e18260b74ffc08a6 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 10 Apr 2012 00:40:09 +0200 Subject: [PATCH] Fix basemap rendering --- .../net/osmand/binary/BinaryInspector.java | 2 +- .../data/preparation/BasemapProcessor.java | 295 +++++++++++------- .../preparation/BinaryMapIndexWriter.java | 14 +- .../osmand/data/preparation/IndexCreator.java | 38 ++- .../preparation/IndexVectorMapCreator.java | 25 +- .../src/net/osmand/render/default.render.xml | 10 +- .../plus/render/MapRenderRepositories.java | 14 +- 7 files changed, 245 insertions(+), 153 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java b/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java index e62fcf604d..8486e2129c 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java @@ -46,7 +46,7 @@ public class BinaryInspector { public static void main(String[] args) throws IOException { inspector(args); // test cases show info - inspector(new String[]{"/home/victor/projects/OsmAnd/data/osm-gen/basemap_coastlines.obf"}); + inspector(new String[]{"-vmap", "-zoom=3","/home/victor/projects/OsmAnd/data/osm-gen/basemap_all.obf"}); // test case extract parts diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/BasemapProcessor.java b/DataExtractionOSM/src/net/osmand/data/preparation/BasemapProcessor.java index 1d5afd4b2a..28ac945bc7 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/BasemapProcessor.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/BasemapProcessor.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.BitSet; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -15,6 +16,7 @@ import java.util.Map; import java.util.Map.Entry; + import net.osmand.Algoritms; import net.osmand.binary.OsmandOdb.MapData; import net.osmand.binary.OsmandOdb.MapDataBlock; @@ -26,7 +28,7 @@ import net.osmand.osm.MapUtils; import net.osmand.osm.Node; import net.osmand.osm.Way; import net.osmand.osm.WayChain; -import net.osmand.osm.OSMSettings.OSMTagKey; +import net.osmand.osm.MapRenderingTypes.MapRulType; import org.apache.commons.logging.Log; import org.apache.tools.bzip2.CBZip2InputStream; @@ -46,6 +48,10 @@ public class BasemapProcessor { private static final int BITS_COUNT = (1 << TILE_ZOOMLEVEL) * (1 << TILE_ZOOMLEVEL); private BitSet seaTileInfo = new BitSet(BITS_COUNT); private BitSet landTileInfo = new BitSet(BITS_COUNT); + private TIntArrayList typeUse = new TIntArrayList(); + List tempNameUse = new ArrayList(); + TIntArrayList addtypeUse = new TIntArrayList(8); + Map namesUse = new LinkedHashMap(); private final int zoomWaySmothness; private final MapRenderingTypes renderingTypes; @@ -67,7 +73,7 @@ public class BasemapProcessor { } SimplisticQuadTree[] children = null; - Map> coastlines = null; + Map> dataObjects = null; public SimplisticQuadTree[] getAllChildren(){ @@ -79,23 +85,23 @@ public class BasemapProcessor { return children != null; } - public void addCoastline(MapZoomPair p, Way w){ + public void addQuadData(MapZoomPair p, SimplisticBinaryData w){ - if(coastlines == null) { - coastlines = new LinkedHashMap>(); + if(dataObjects == null) { + dataObjects = new LinkedHashMap>(); } - if(!coastlines.containsKey(p)){ - coastlines.put(p, new ArrayList()); + if(!dataObjects.containsKey(p)){ + dataObjects.put(p, new ArrayList()); } - coastlines.get(p).add(w); + dataObjects.get(p).add(w); } - public boolean coastlinesDefined(MapZoomPair p){ - return coastlines != null && coastlines.get(p) != null; + public boolean dataIsDefined(MapZoomPair p){ + return dataObjects != null && dataObjects.get(p) != null; } - public List getCoastlines(MapZoomPair p) { - return coastlines.get(p); + public List getData(MapZoomPair p) { + return dataObjects.get(p); } public SimplisticQuadTree getOrCreateSubTree(int x, int y, int zm) { @@ -122,7 +128,15 @@ public class BasemapProcessor { } } } - + } + + private static class SimplisticBinaryData { + // consequent 31 coordinates + public byte[] coordinates; + public int[] types; + public int[] addTypes; + public long id = -500; + public Map names; } @@ -265,7 +279,7 @@ public class BasemapProcessor { - public void writeCoastlinesFile(BinaryMapIndexWriter writer, String regionName) throws IOException { + public void writeBasemapFile(BinaryMapIndexWriter writer, String regionName) throws IOException { writer.startWriteMapIndex(regionName); // write map encoding rules writer.writeMapEncodingRules(renderingTypes.getEncodingRuleTypes()); @@ -292,36 +306,37 @@ public class BasemapProcessor { private void writeBinaryMapBlock(SimplisticQuadTree simplisticQuadTree, BinaryMapIndexWriter writer, Map refs, MapZoomPair p) throws IOException { Iterator> it = refs.entrySet().iterator(); - TIntArrayList type = new TIntArrayList(); - type.add(renderingTypes.getCoastlineRuleType().getTargetId()); while(it.hasNext()) { Entry e = it.next(); MapDataBlock.Builder dataBlock = MapDataBlock.newBuilder(); SimplisticQuadTree quad = e.getKey(); - - for (Way w : quad.getCoastlines(p)) { - dataBlock.setBaseId(w.getId()); - List res = new ArrayList(); - MapAlgorithms.simplifyDouglasPeucker(w.getNodes(), p.getMaxZoom() - 1 + 8 + zoomWaySmothness, 3, res); - ByteArrayOutputStream bcoordinates = new ByteArrayOutputStream(); - for (Node n : res) { - if (n != null) { - int y = MapUtils.get31TileNumberY(n.getLatitude()); - int x = MapUtils.get31TileNumberX(n.getLongitude()); - Algoritms.writeInt(bcoordinates, x); - Algoritms.writeInt(bcoordinates, y); + Map stringTable = new LinkedHashMap (); + for (SimplisticBinaryData w : quad.getData(p)) { + dataBlock.setBaseId(w.id); + int[] wts = null; + int[] wats = null; + if(w.types != null ){ + wts = new int[w.types.length]; + for (int j = 0; j < w.types.length; j ++) { + wts[j] = renderingTypes.getTypeByInternalId(w.types[j]).getTargetId(); + } + } + if(w.addTypes != null){ + wats = new int[w.addTypes.length]; + for (int j = 0; j < w.addTypes.length; j ++) { + wats[j] = renderingTypes.getTypeByInternalId(w.addTypes[j]).getTargetId(); } } MapData mapData = writer.writeMapData(0, quad.x << (31 - quad.zoom), quad.y << (31 - quad.zoom), false, - bcoordinates.toByteArray(), null, type, null, null, null, dataBlock); + w.coordinates, null, wts, wats, w.names, stringTable, dataBlock); if (mapData != null) { dataBlock.addDataObjects(mapData); } } - writer.writeMapDataBlock(dataBlock, null, e.getValue()); + writer.writeMapDataBlock(dataBlock, stringTable, e.getValue()); } } @@ -331,7 +346,7 @@ public class BasemapProcessor { int xR = ((quadTree.x + 1) << (31 - quadTree.zoom)) - 1; int yT = (quadTree.y) << (31 - quadTree.zoom); int yB = ((quadTree.y + 1) << (31 - quadTree.zoom)) - 1; - boolean defined = quadTree.coastlinesDefined(p); + boolean defined = quadTree.dataIsDefined(p); boolean ocean = false; boolean land = false; if (!defined) { @@ -355,88 +370,158 @@ public class BasemapProcessor { } public void processEntity(Entity e) { - if(e instanceof Way && "coastline".equals(e.getTag(OSMTagKey.NATURAL))) { - processCoastline((Way) e); + if (e instanceof Way || e instanceof Node) { + for (int level = 0; level < mapZooms.getLevels().size(); level++) { + renderingTypes.encodeEntityWithType(e, mapZooms.getLevel(level).getMaxZoom(), typeUse, addtypeUse, namesUse, tempNameUse); + if (typeUse.isEmpty()) { + continue; + } + MapZoomPair zoomPair = mapZooms.getLevel(level); + if (e instanceof Way) { + if(((Way) e).getNodes().size() < 2){ + continue; + } + if ("coastline".equals(e.getTag("natural")) || !Algoritms.isEmpty(e.getTag("admin_level"))) { + splitContinuousWay(((Way) e).getNodes(), typeUse.toArray(), !addtypeUse.isEmpty() ? addtypeUse.toArray() : null, + zoomPair, quadTrees[level]); + } else { + List ns = ((Way) e).getNodes(); + int z = getViewZoom(zoomPair); + int tilex = 0; + int tiley = 0; + boolean sameTile = false; + while (!sameTile) { + tilex = (int) MapUtils.getTileNumberX(z, ns.get(0).getLongitude()); + tiley = (int) MapUtils.getTileNumberY(z, ns.get(0).getLatitude()); + sameTile = true; + for (int i = 1; i < ns.size(); i++) { + int tx = (int) MapUtils.getTileNumberX(z, ns.get(i).getLongitude()); + int ty = (int) MapUtils.getTileNumberY(z, ns.get(i).getLatitude()); + if (tx != tilex || ty != tiley) { + sameTile = false; + break; + } + } + if (!sameTile) { + z--; + } + } + List res = new ArrayList(); + MapAlgorithms.simplifyDouglasPeucker(ns, zoomPair.getMaxZoom() - 1 + 8 + zoomWaySmothness, 3, res); + addSimplisticData(res, typeUse.toArray(), !addtypeUse.isEmpty() ? addtypeUse.toArray() : null, zoomPair, + quadTrees[level], z, tilex, tiley, namesUse.isEmpty() ? null : new LinkedHashMap(namesUse)); + } + } else { + int z = getViewZoom(zoomPair); + int tilex = (int) MapUtils.getTileNumberX(z, ((Node) e).getLongitude()); + int tiley = (int) MapUtils.getTileNumberY(z, ((Node) e).getLatitude()); + addSimplisticData(Collections.singletonList((Node)e), typeUse.toArray(), !addtypeUse.isEmpty() ? addtypeUse.toArray() : null, zoomPair, + quadTrees[level], z, tilex, tiley, namesUse.isEmpty() ? null : new LinkedHashMap(namesUse)); + } + + } } } - public void processCoastline(Way e) { - renderingTypes.getCoastlineRuleType().updateFreq(); - int ij = 0; - for(MapZoomPair zoomPair : mapZooms.getLevels()) { - SimplisticQuadTree quadTree = quadTrees[ij++]; - int z = Math.min((zoomPair.getMinZoom() + zoomPair.getMaxZoom()) / 2 - 1, zoomPair.getMinZoom() + 1); - List ns = e.getNodes(); - if(ns.size() < 2) { - return; - } - int i = 1; - Node prevNode = ns.get(0); - int px31 = MapUtils.get31TileNumberX(prevNode.getLongitude()); - int py31 = MapUtils.get31TileNumberY(prevNode.getLatitude()); - while(i> (31 - z); - int tiley = py31 >> (31 - z); - boolean sameTile = true; - wayConstruct : while(sameTile && i ns, int[] types, int[] addTypes, MapZoomPair zoomPair, SimplisticQuadTree quadTree) { + int z = getViewZoom(zoomPair); + int i = 1; + Node prevNode = ns.get(0); + int px31 = MapUtils.get31TileNumberX(prevNode.getLongitude()); + int py31 = MapUtils.get31TileNumberY(prevNode.getLatitude()); + while (i < ns.size()) { + List w = new ArrayList(); + w.add(prevNode); + int tilex = px31 >> (31 - z); + int tiley = py31 >> (31 - z); + boolean sameTile = true; + wayConstruct: while (sameTile && i < ns.size()) { + Node next = ns.get(i); + int ntilex = (int) MapUtils.getTileNumberX(z, next.getLongitude()); + int ntiley = (int) MapUtils.getTileNumberY(z, next.getLatitude()); + if (ntilex == tilex && tiley == ntiley) { + sameTile = true; + w.add(next); + prevNode = next; + px31 = MapUtils.get31TileNumberX(prevNode.getLongitude()); + py31 = MapUtils.get31TileNumberY(prevNode.getLatitude()); + i++; + } else { + int nx31 = MapUtils.get31TileNumberX(next.getLongitude()); + int ny31 = MapUtils.get31TileNumberY(next.getLatitude()); + // increase boundaries to drop into another tile + int leftX = (tilex << (31 - z)) - 1; + int rightX = (tilex + 1) << (31 - z); + if (rightX < 0) { + rightX = Integer.MAX_VALUE; + } + int topY = (tiley << (31 - z)) - 1; + int bottomY = (tiley + 1) << (31 - z); + if (bottomY < 0) { + bottomY = Integer.MAX_VALUE; + } + + long inter = MapAlgorithms.calculateIntersection(px31, py31, nx31, ny31, leftX, rightX, bottomY, topY); + int cy31 = (int) inter; + int cx31 = (int) (inter >> 32l); + if (inter == -1) { + cx31 = nx31; + cy31 = ny31; i++; - } else { - int nx31 = MapUtils.get31TileNumberX(next.getLongitude()); - int ny31 = MapUtils.get31TileNumberY(next.getLatitude()); - // increase boundaries to drop into another tile - int leftX = (tilex << (31 - z)) - 1; - int rightX = (tilex + 1) << (31 - z); - if (rightX < 0) { - rightX = Integer.MAX_VALUE; - } - int topY = (tiley << (31 - z)) - 1; - int bottomY = (tiley + 1) << (31 - z); - if (bottomY < 0) { - bottomY = Integer.MAX_VALUE; - } - - long inter = MapAlgorithms.calculateIntersection(px31, py31, nx31, ny31, leftX, rightX, bottomY, topY); - int cy31 = (int) inter; - int cx31 = (int) (inter >> 32l); - if (inter == -1) { - cx31 = nx31; - cy31 = ny31; - i++; - logMapDataWarn.warn("Can't find intersection for " + MapUtils.get31LongitudeX(px31) + "," - + MapUtils.get31LatitudeY(py31) + " - " + +MapUtils.get31LongitudeX(nx31) + "," - + MapUtils.get31LatitudeY(ny31)); - } - - prevNode = new Node(MapUtils.get31LatitudeY(cy31), MapUtils.get31LongitudeX(cx31), -1000); - px31 = cx31; - py31 = cy31; - w.addNode(prevNode); - break wayConstruct; + logMapDataWarn.warn("Can't find intersection for " + MapUtils.get31LongitudeX(px31) + "," + + MapUtils.get31LatitudeY(py31) + " - " + MapUtils.get31LongitudeX(nx31) + "," + + MapUtils.get31LatitudeY(ny31)); } + + prevNode = new Node(MapUtils.get31LatitudeY(cy31), MapUtils.get31LongitudeX(cx31), -1000); + px31 = cx31; + py31 = cy31; + w.add(prevNode); + break wayConstruct; } - SimplisticQuadTree quad = quadTree.getOrCreateSubTree(tilex, tiley, z); - if (quad == null) { - if (logMapDataWarn != null) { - logMapDataWarn.error("Tile " + tilex + " / " + tiley + " at " + z + " can not be found"); - } else { - System.err.println("Tile " + tilex + " / " + tiley + " at " + z + " can not be found"); - } - } - quad.addCoastline(zoomPair, w); - + } + List res = new ArrayList(); + MapAlgorithms.simplifyDouglasPeucker(w, zoomPair.getMaxZoom() - 1 + 8 + zoomWaySmothness, 3, res); + addSimplisticData(res, types, addTypes, zoomPair, quadTree, z, tilex, tiley, null); + } + } + + private void addSimplisticData(List res, int[] types, int[] addTypes, MapZoomPair zoomPair, SimplisticQuadTree quadTree, int z, int tilex, + int tiley, Map names) { + SimplisticQuadTree quad = quadTree.getOrCreateSubTree(tilex, tiley, z); + if (quad == null) { + if (logMapDataWarn != null) { + logMapDataWarn.error("Tile " + tilex + " / " + tiley + " at " + z + " can not be found"); + } else { + System.err.println("Tile " + tilex + " / " + tiley + " at " + z + " can not be found"); } } + + ByteArrayOutputStream bcoordinates = new ByteArrayOutputStream(); + for (Node n : res) { + if (n != null) { + int y = MapUtils.get31TileNumberY(n.getLatitude()); + int x = MapUtils.get31TileNumberX(n.getLongitude()); + try { + Algoritms.writeInt(bcoordinates, x); + Algoritms.writeInt(bcoordinates, y); + } catch (IOException e1) { + throw new IllegalStateException(e1); + } + } + } + SimplisticBinaryData data = new SimplisticBinaryData(); + // not needed + // data.id = w.getId(); + data.coordinates = bcoordinates.toByteArray(); + data.types = types; + data.addTypes = addTypes; + data.names = names; + quad.addQuadData(zoomPair, data); + } + + private int getViewZoom(MapZoomPair zoomPair) { + return Math.min((zoomPair.getMinZoom() + zoomPair.getMaxZoom()) / 2 - 1, zoomPair.getMinZoom() + 1); } diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java b/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java index 31361a93eb..24d20a47e5 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java @@ -352,8 +352,8 @@ public class BinaryMapIndexWriter { private TByteArrayList mapDataBuf = new TByteArrayList(); - public MapData writeMapData(long diffId, int pleft, int ptop, boolean area, byte[] coordinates, byte[] innerPolygonTypes, TIntArrayList typeUse, - TIntArrayList addtypeUse, Map names, Map stringTable, MapDataBlock.Builder dataBlock) + public MapData writeMapData(long diffId, int pleft, int ptop, boolean area, byte[] coordinates, byte[] innerPolygonTypes, int[] typeUse, + int[] addtypeUse, Map names, Map stringTable, MapDataBlock.Builder dataBlock) throws IOException { MapData.Builder data = MapData.newBuilder(); @@ -409,16 +409,16 @@ public class BinaryMapIndexWriter { } mapDataBuf.clear(); - for (int i = 0; i < typeUse.size() ; i++) { - writeRawVarint32(mapDataBuf, typeUse.get(i));; + for (int i = 0; i < typeUse.length ; i++) { + writeRawVarint32(mapDataBuf, typeUse[i]); } data.setTypes(ByteString.copyFrom(mapDataBuf.toArray())); TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER) + CodedOutputStream.computeRawVarint32Size(mapDataBuf.size()) + mapDataBuf.size(); - if (addtypeUse != null && addtypeUse.size() > 0) { + if (addtypeUse != null && addtypeUse.length > 0) { mapDataBuf.clear(); - for (int i = 0; i < addtypeUse.size() ; i++) { - writeRawVarint32(mapDataBuf, addtypeUse.get(i));; + for (int i = 0; i < addtypeUse.length ; i++) { + writeRawVarint32(mapDataBuf, addtypeUse[i]); } data.setAdditionalTypes(ByteString.copyFrom(mapDataBuf.toArray())); TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.ADDITIONALTYPES_FIELD_NUMBER); diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java index 87dd46ea14..a827a00771 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java @@ -241,7 +241,9 @@ public class IndexCreator { @Override public boolean acceptEntityToLoad(OsmBaseStorage storage, EntityId entityId, Entity entity) { - indexAddressCreator.registerCityIfNeeded(entity); + if(indexAddressCreator != null) { + indexAddressCreator.registerCityIfNeeded(entity); + } // accept to allow db creator parse it return true; } @@ -275,11 +277,11 @@ public class IndexCreator { } } - private boolean createPlainOsmDb(IProgress progress, File readFile, IOsmStorageFilter addFilter) throws SQLException, FileNotFoundException, IOException, SAXException{ + private boolean createPlainOsmDb(IProgress progress, File readFile, IOsmStorageFilter addFilter, boolean deletePrevious) throws SQLException, FileNotFoundException, IOException, SAXException{ // dbFile = new File(workingDir, TEMP_NODES_DB); // initialize db file - boolean loadFromExistingFile = dbFile != null && dialect.databaseFileExists(dbFile); - if (dbFile == null) { + boolean loadFromExistingFile = dbFile != null && dialect.databaseFileExists(dbFile) && !deletePrevious; + if (dbFile == null || deletePrevious) { dbFile = new File(workingDir, TEMP_NODES_DB); // to save space if (dialect.databaseFileExists(dbFile)) { @@ -362,7 +364,7 @@ public class IndexCreator { for (File readFile : readFiles) { this.accessor = new OsmDbAccessor(); - createPlainOsmDb(progress, readFile, addFilter); + createPlainOsmDb(progress, readFile, addFilter, true); // 2. Create index connections and index structure progress.setGeneralProgress("[50 / 100]"); @@ -398,7 +400,7 @@ public class IndexCreator { progress.setGeneralProgress("[95 of 100]"); progress.startTask("Writing map index to binary file...", -1); - processor.writeCoastlinesFile(writer, regionName); + processor.writeBasemapFile(writer, regionName); progress.finishTask(); writer.close(); mapRAFile.close(); @@ -460,7 +462,7 @@ public class IndexCreator { try { // //////////////////////////////////////////////////////////////////////// // 1. creating nodes db to fast access for all nodes and simply import all relations, ways, nodes to it - boolean loadFromExistingFile = createPlainOsmDb(progress, readFile, addFilter); + boolean loadFromExistingFile = createPlainOsmDb(progress, readFile, addFilter, false); // do not create temp map file and rtree files if (recreateOnlyBinaryFile) { @@ -715,18 +717,24 @@ public class IndexCreator { creator.setZoomWaySmothness(2); MapRenderingTypes rt = MapRenderingTypes.getDefault();// new MapRenderingTypes("/home/victor/projects/OsmAnd/data/testdata/roads_rendering_types.xml"); MapZooms zooms = MapZooms.getDefault(); // MapZooms.parseZooms("15-"); - creator.setNodesDBFile(new File("/home/victor/projects/OsmAnd/data/osm-gen/nodes.tmp.odb")); +// creator.setNodesDBFile(new File("/home/victor/projects/OsmAnd/data/osm-gen/nodes.tmp.odb")); // creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/luxembourg.osm.pbf"), // creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/cuba2.osm.bz2"), // new ConsoleProgressImplementation(1), null, zooms, rt, log); - // ;6-8;9-14 - zooms = MapZooms.parseZooms("1-3;4-6;7-9;10-"); - creator.setMapFileName("basemap_coastlines.obf"); + +// zooms = MapZooms.parseZooms("1-3;4-6;7-9;10-"); +// creator.setMapFileName("basemap_coastlines.obf"); + zooms = MapZooms.parseZooms("1-3;4-5;6-7;8-9;10-"); + creator.setMapFileName("basemap_a.obf"); + + File basemapParent = new File("/home/victor/projects/OsmAnd/data/basemap"); creator.generateBasemapIndex(new ConsoleProgressImplementation(1), null, zooms, rt, log, "basemap", - new File("/home/victor/projects/OsmAnd/data/basemap/10m_coastline_out.osm")); - - - + new File(basemapParent, "10m_coastline_out.osm"), + new File(basemapParent, "10m_admin_level_out.osm"), + new File(basemapParent, "10m_rivers.osm"), + new File(basemapParent, "10m_lakes_out.osm"), + new File(basemapParent, "10m_populated_places_out.osm") + ); // world generation // MapZooms mapZooms = new MapZooms(); // MapZoomPair pair1 = new MapZooms.MapZoomPair(1, 3); diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java index 9e02f7e428..debe6f96b8 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java @@ -2,7 +2,6 @@ package net.osmand.data.preparation; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TLongObjectHashMap; -import gnu.trove.procedure.TObjectProcedure; import gnu.trove.set.hash.TLongHashSet; import java.io.ByteArrayOutputStream; @@ -27,7 +26,6 @@ import net.osmand.binary.OsmandOdb.MapData; import net.osmand.binary.OsmandOdb.MapDataBlock; import net.osmand.data.Boundary; import net.osmand.data.MapAlgorithms; -import net.osmand.data.WayBoundary; import net.osmand.osm.Entity; import net.osmand.osm.Entity.EntityId; import net.osmand.osm.Entity.EntityType; @@ -35,7 +33,6 @@ import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MapRenderingTypes.MapRulType; import net.osmand.osm.MapUtils; import net.osmand.osm.Node; -import net.osmand.osm.WayChain; import net.osmand.osm.OSMSettings.OSMTagKey; import net.osmand.osm.Relation; import net.osmand.osm.Way; @@ -72,9 +69,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { List tempNameUse = new ArrayList(); Map namesUse = new LinkedHashMap(); TIntArrayList addtypeUse = new TIntArrayList(8); - List restrictionsUse = new ArrayList(8); - private BasemapProcessor basemapProcessor; private PreparedStatement mapBinaryStat; private PreparedStatement mapLowLevelBinaryStat; private int lowLevelWays = -1; @@ -91,7 +86,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { this.mapZooms = mapZooms; this.zoomWaySmothness = zoomWaySmothness; this.renderingTypes = renderingTypes; - this.basemapProcessor = new BasemapProcessor(logMapDataWarn, mapZooms, renderingTypes, zoomWaySmothness); lowLevelWays = -1; } @@ -208,13 +202,13 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { List outerWay = outerWaySrc; int zoomToSimplify = mapZooms.getLevel(level).getMaxZoom() - 1; if (zoomToSimplify < 15) { - outerWay = simplifyCycleWay(outerWay, zoomToSimplify); + outerWay = simplifyCycleWay(outerWay, zoomToSimplify, zoomWaySmothness); if (outerWay == null) { continue nextZoom; } List> newinnerWays = new ArrayList>(); for (List ls : innerWays) { - ls = simplifyCycleWay(ls, zoomToSimplify); + ls = simplifyCycleWay(ls, zoomToSimplify, zoomWaySmothness); if (ls != null) { newinnerWays.add(ls); } @@ -299,7 +293,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { } } - protected List simplifyCycleWay(List ns, int zoom) throws SQLException { + public static List simplifyCycleWay(List ns, int zoom, int zoomWaySmothness) throws SQLException { if (checkForSmallAreas(ns, zoom + Math.min(zoomWaySmothness / 2, 3), 2, 4)) { return null; } @@ -339,7 +333,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { } public void processingLowLevelWays(IProgress progress) throws SQLException { - restrictionsUse.clear(); mapLowLevelBinaryStat.executeBatch(); mapLowLevelBinaryStat.close(); pStatements.remove(mapLowLevelBinaryStat); @@ -473,7 +466,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { } - private boolean checkForSmallAreas(List nodes, int zoom, int minz, int maxz) { + private static boolean checkForSmallAreas(List nodes, int zoom, int minz, int maxz) { int minX = Integer.MAX_VALUE; int maxX = Integer.MIN_VALUE; int minY = Integer.MAX_VALUE; @@ -529,7 +522,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { if (zoomToSimplify < 15) { boolean cycle = ((Way) e).getFirstNodeId() == ((Way) e).getLastNodeId(); if (cycle) { - res = simplifyCycleWay(((Way) e).getNodes(), zoomToSimplify); + res = simplifyCycleWay(((Way) e).getNodes(), zoomToSimplify, zoomWaySmothness); } else { String ename = namesUse.get(renderingTypes.getNameRuleType()); insertLowLevelMapBinaryObject(level, zoomToSimplify, typeUse, addtypeUse, id, ((Way) e).getNodes(), ename); @@ -652,17 +645,17 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { tempNames.clear(); decodeNames(rs.getString(6), tempNames); byte[] types = rs.getBytes(4); - typeUse.clear(); + int[] typeUse = new int[types.length / 2]; for (int j = 0; j < types.length; j += 2) { int ids = Algoritms.parseSmallIntFromBytes(types, j); - typeUse.add(renderingTypes.getTypeByInternalId(ids).getTargetId()); + typeUse[j / 2] = renderingTypes.getTypeByInternalId(ids).getTargetId(); } byte[] addTypes = rs.getBytes(5); - addtypeUse.clear(); + int[] addtypeUse = new int[addTypes.length / 2]; if (addTypes != null) { for (int j = 0; j < addTypes.length; j += 2) { int ids = Algoritms.parseSmallIntFromBytes(addTypes, j); - addtypeUse.add(renderingTypes.getTypeByInternalId(ids).getTargetId()); + addtypeUse[j / 2] = renderingTypes.getTypeByInternalId(ids).getTargetId(); } } diff --git a/DataExtractionOSM/src/net/osmand/render/default.render.xml b/DataExtractionOSM/src/net/osmand/render/default.render.xml index 05c86e3631..e115f8252b 100644 --- a/DataExtractionOSM/src/net/osmand/render/default.render.xml +++ b/DataExtractionOSM/src/net/osmand/render/default.render.xml @@ -81,8 +81,8 @@ - - + + @@ -229,13 +229,13 @@ - + - + - + diff --git a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java index 88fb42c5cf..ee217373d3 100644 --- a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java @@ -374,14 +374,14 @@ public class MapRenderRepositories { } String coastlineTime = ""; - boolean addBasemapCoastlines = zoom <= BASEMAP_ZOOM; + boolean addBasemapCoastlines = true; boolean emptyData = zoom > BASEMAP_ZOOM && tempResult.isEmpty() && coastLines.isEmpty() ; if(!coastLines.isEmpty()) { long ms = System.currentTimeMillis(); List pcoastlines = processCoastlines(coastLines, leftX, rightX, bottomY, topY, zoom, basemapCoastLines.isEmpty()); - addBasemapCoastlines = pcoastlines.isEmpty() || addBasemapCoastlines; + addBasemapCoastlines = pcoastlines.isEmpty() || zoom <= BASEMAP_ZOOM; tempResult.addAll(pcoastlines); coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )"; } else if(basemapCoastLines.isEmpty() && mi != null){ @@ -397,10 +397,16 @@ public class MapRenderRepositories { coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )"; } if(emptyData && tempResult.size() > 0){ - BinaryMapDataObject o = tempResult.get(0); + // message + BinaryMapDataObject p = tempResult.get(0); + // avoid overflow int errors + BinaryMapDataObject o = new BinaryMapDataObject(new int[] { leftX + (rightX - leftX) / 2, topY + (bottomY - topY) / 2 }, + new int[] { p.getMapIndex().coastlineEncodingType }, null, -1); + o.setMapIndex(p.getMapIndex()); o.putObjectName(o.getMapIndex().nameEncodingType, context.getString(R.string.switch_to_raster_map_to_see)); + tempResult.add(o); } - if(zoom <= BASEMAP_ZOOM || tempResult.isEmpty()) { + if(zoom <= BASEMAP_ZOOM || emptyData) { tempResult.addAll(basemapResult); }