diff --git a/DataExtractionOSM/src/net/osmand/ToDoConstants.java b/DataExtractionOSM/src/net/osmand/ToDoConstants.java
index f5068abc59..a3e01aec22 100644
--- a/DataExtractionOSM/src/net/osmand/ToDoConstants.java
+++ b/DataExtractionOSM/src/net/osmand/ToDoConstants.java
@@ -12,8 +12,8 @@ public class ToDoConstants {
// Map QuadTree (skip small areas!!!)
// Routing index !!
-
- // Identify coastline areas and pure ocean areas !!!
+
+ // Identify coastline areas and pure ocean areas !!! Show high zoom level for coatline if coastline is broken
// TODO Delete/Extract the code with multipolygons ! (coastline))
// Render : different texts support render.xml
diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java b/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java
index 3cbe5c1ec8..0fd92bd223 100644
--- a/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java
+++ b/DataExtractionOSM/src/net/osmand/binary/BinaryInspector.java
@@ -46,13 +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/temp/Belarus_europe.obf"});
-// inspector(new String[]{"-v","C:\\Users\\tpd\\osmand\\Housenumbers.obf"});
- //inspector(new String[]{"/home/victor/projects/OsmAnd/data/osm-gen/saved/Belarus-newzooms-new-rt.obf"});
-// inspector(new String[]{"/home/victor/projects/OsmAnd/download/spain/Spain_europe_1_small.obf"});
- inspector(new String[]{"-vpoi", "/home/victor/projects/OsmAnd/data/osm-gen/10m_coastline_out.obf"
- /*"/home/victor/projects/OsmAnd/data/osm-gen/Luxembourg.obf"*/});
-
+ inspector(new String[]{"/home/victor/projects/OsmAnd/data/osm-gen/basemap_coastlines"});
// test case extract parts
@@ -519,7 +513,7 @@ public class BinaryInspector {
continue;
// throw new NullPointerException("Type " + obj.getAdditionalTypes()[j] + "was not found");
}
- b.append(pair.toSimpleString()+"("+types[j]+")");
+ b.append(pair.toSimpleString()+" ("+types[j]+")");
}
b.append("]");
if(obj.getAdditionalTypes() != null && obj.getAdditionalTypes().length > 0){
diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java
index 09b9b2c9bb..32ac81af6c 100644
--- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java
+++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java
@@ -57,6 +57,13 @@ public class BinaryMapDataObject {
return objectNames;
}
+ public void putObjectName(int type, String name){
+ if(objectNames == null){
+ objectNames = new TIntObjectHashMap();
+ }
+ objectNames.put(type, name);
+ }
+
public int[][] getPolygonInnerCoordinates() {
return polygonInnerCoordinates;
}
diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java
index 4618695448..48afc2cc95 100644
--- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java
+++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java
@@ -60,6 +60,7 @@ public class BinaryMapIndexReader {
private int version;
private long dateCreated;
// keep them immutable inside
+ private boolean basemap = false;
private List mapIndexes = new ArrayList();
private List poiIndexes = new ArrayList();
private List addressIndexes = new ArrayList();
@@ -72,6 +73,8 @@ public class BinaryMapIndexReader {
private final BinaryMapPoiReaderAdapter poiAdapter;
private final BinaryMapAddressReaderAdapter addressAdapter;
+ private static String BASEMAP_NAME = "basemap";
+
public BinaryMapIndexReader(final RandomAccessFile raf) throws IOException {
this(raf, false);
@@ -90,6 +93,7 @@ public class BinaryMapIndexReader {
addressIndexes = new ArrayList(referenceToSameFile.addressIndexes);
transportIndexes = new ArrayList(referenceToSameFile.transportIndexes);
indexes = new ArrayList(referenceToSameFile.indexes);
+ basemap = referenceToSameFile.basemap;
}
public BinaryMapIndexReader(final RandomAccessFile raf, boolean readOnlyMapData) throws IOException {
@@ -136,6 +140,7 @@ public class BinaryMapIndexReader {
mapIndex.filePointer = codedIS.getTotalBytesRead();
int oldLimit = codedIS.pushLimit(mapIndex.length);
readMapIndex(mapIndex);
+ basemap = basemap || mapIndex.isBaseMap();
codedIS.popLimit(oldLimit);
codedIS.seek(mapIndex.filePointer + mapIndex.length);
mapIndexes.add(mapIndex);
@@ -215,6 +220,14 @@ public class BinaryMapIndexReader {
return indexes;
}
+ public List getMapIndexes() {
+ return mapIndexes;
+ }
+
+ public boolean isBasemap() {
+ return basemap;
+ }
+
public boolean containsMapData(){
return mapIndexes.size() > 0;
}
@@ -668,6 +681,13 @@ public class BinaryMapIndexReader {
case MapDataBox.TOP_FIELD_NUMBER :
tree.top = codedIS.readSInt32() + atop;
break;
+ case MapDataBox.OCEAN_FIELD_NUMBER :
+ if(codedIS.readBool()) {
+ tree.ocean = Boolean.TRUE;
+ } else {
+ tree.ocean = Boolean.FALSE;
+ }
+ break;
case MapDataBox.SHIFTTOMAPDATA_FIELD_NUMBER :
tree.mapDataBlock = readInt() + tree.filePointer;
break;
@@ -852,7 +872,12 @@ public class BinaryMapIndexReader {
foundSubtrees.add(current);
break;
case MapDataBox.OCEAN_FIELD_NUMBER :
- current.ocean = codedIS.readBool();
+ if(codedIS.readBool()) {
+ current.ocean = Boolean.TRUE;
+ } else {
+ current.ocean = Boolean.FALSE;
+ }
+ req.publishOceanTile(current.ocean);
break;
case MapDataBox.BOXES_FIELD_NUMBER :
// left, ... already initialized
@@ -860,8 +885,8 @@ public class BinaryMapIndexReader {
child.length = readInt();
child.filePointer = codedIS.getTotalBytesRead();
int oldLimit = codedIS.pushLimit(child.length);
- if(current.ocean){
- child.ocean = true;
+ if(current.ocean != null ){
+ child.ocean = current.ocean;
}
searchMapTreeBounds(child, current, req, foundSubtrees);
codedIS.popLimit(oldLimit);
@@ -1228,6 +1253,9 @@ public class BinaryMapIndexReader {
public static class SearchRequest {
private List searchResults = new ArrayList();
+ private boolean land = false;
+ private boolean ocean = false;
+
private ResultMatcher resultMatcher;
// 31 zoom tiles
@@ -1276,6 +1304,14 @@ public class BinaryMapIndexReader {
return false;
}
+ protected void publishOceanTile(boolean ocean){
+ if(ocean) {
+ this.ocean = true;
+ } else {
+ this.land = true;
+ }
+ }
+
public List getSearchResults() {
return searchResults;
}
@@ -1294,11 +1330,21 @@ public class BinaryMapIndexReader {
return false;
}
+ public boolean isOcean() {
+ return ocean;
+ }
+
+ public boolean isLand() {
+ return land;
+ }
+
public void clearSearchResults(){
// recreate whole list to allow GC collect old data
searchResults = new ArrayList();
cacheCoordinates.clear();
cacheTypes.clear();
+ land = false;
+ ocean = false;
numberOfVisitedObjects = 0;
numberOfAcceptedObjects = 0;
numberOfReadSubtrees = 0;
@@ -1331,8 +1377,13 @@ public class BinaryMapIndexReader {
}
public void finishInitializingTags() {
- coastlineBrokenEncodingType = decodingRules.size() * 2 + 1;
+ int free = decodingRules.size() * 2 + 1;
+ coastlineBrokenEncodingType = free++;
initMapEncodingRule(0, coastlineBrokenEncodingType, "natural", "coastline_broken");
+ if(landEncodingType == -1){
+ landEncodingType = free++;
+ initMapEncodingRule(0, landEncodingType, "natural", "land");
+ }
}
private void initMapEncodingRule(int type, int id, String tag, String val) {
@@ -1366,7 +1417,10 @@ public class BinaryMapIndexReader {
}
}
}
-
+
+ public boolean isBaseMap(){
+ return name != null && name.toLowerCase().contains(BASEMAP_NAME);
+ }
}
public static class TagValuePair {
@@ -1455,7 +1509,7 @@ public class BinaryMapIndexReader {
int length = 0;
long mapDataBlock = 0;
- boolean ocean = false;
+ Boolean ocean = null;
int left = 0;
int right = 0;
@@ -1482,6 +1536,12 @@ public class BinaryMapIndexReader {
return filePointer;
}
+ @Override
+ public String toString(){
+ return "Top Lat " + ((float) MapUtils.get31LatitudeY(top)) + " lon " + ((float) MapUtils.get31LongitudeX(left))
+ + " Bottom lat " + ((float) MapUtils.get31LatitudeY(bottom)) + " lon " + ((float) MapUtils.get31LongitudeX(right));
+ }
+
}
diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java b/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java
index 68ebc3ed7e..31361a93eb 100644
--- a/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java
+++ b/DataExtractionOSM/src/net/osmand/data/preparation/BinaryMapIndexWriter.java
@@ -196,7 +196,6 @@ public class BinaryMapIndexWriter {
codedOutStream.writeInt32(OsmandOdb.OsmAndMapIndex.MapRootLevel.RIGHT_FIELD_NUMBER, rightX);
codedOutStream.writeInt32(OsmandOdb.OsmAndMapIndex.MapRootLevel.TOP_FIELD_NUMBER, topY);
codedOutStream.writeInt32(OsmandOdb.OsmAndMapIndex.MapRootLevel.BOTTOM_FIELD_NUMBER, bottomY);
-
stackBounds.push(new Bounds(leftX, rightX, topY, bottomY));
}
diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/CoastlineProcessor.java b/DataExtractionOSM/src/net/osmand/data/preparation/CoastlineProcessor.java
index 663aaa1041..8d6ce75926 100644
--- a/DataExtractionOSM/src/net/osmand/data/preparation/CoastlineProcessor.java
+++ b/DataExtractionOSM/src/net/osmand/data/preparation/CoastlineProcessor.java
@@ -9,7 +9,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Iterator;
@@ -17,14 +16,12 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
import javax.xml.stream.XMLStreamException;
import net.osmand.Algoritms;
import net.osmand.binary.OsmandOdb.MapData;
import net.osmand.binary.OsmandOdb.MapDataBlock;
-import net.osmand.binary.OsmandOdb.MapDataBlock.Builder;
import net.osmand.data.MapAlgorithms;
import net.osmand.data.preparation.MapZooms.MapZoomPair;
import net.osmand.osm.Entity;
@@ -54,20 +51,21 @@ public class CoastlineProcessor {
public static final byte TILE_ZOOMLEVEL = 12;
private static final byte BITMASK = 0x3;
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 final int zoomWaySmothness;
private final MapRenderingTypes renderingTypes;
private final MapZooms mapZooms;
private final Log logMapDataWarn;
- private SimplisticQuadTree quadTree;
+ private SimplisticQuadTree[] quadTrees;
private static class SimplisticQuadTree {
- public boolean ocean;
- public boolean land;
int zoom;
int x;
int y;
+ boolean ocean;
+ boolean land;
public SimplisticQuadTree(int x, int y, int zoom) {
this.x = x;
@@ -76,7 +74,8 @@ public class CoastlineProcessor {
}
SimplisticQuadTree[] children = null;
- List coastlines = null;
+ Map> coastlines = null;
+
public SimplisticQuadTree[] getAllChildren(){
initChildren();
@@ -87,11 +86,23 @@ public class CoastlineProcessor {
return children != null;
}
- public void addCoastline(Way w){
+ public void addCoastline(MapZoomPair p, Way w){
+
if(coastlines == null) {
- coastlines = new ArrayList();
+ coastlines = new LinkedHashMap>();
}
- coastlines.add(w);
+ if(!coastlines.containsKey(p)){
+ coastlines.put(p, new ArrayList());
+ }
+ coastlines.get(p).add(w);
+ }
+
+ public boolean coastlinesDefined(MapZoomPair p){
+ return coastlines != null && coastlines.get(p) != null;
+ }
+
+ public List getCoastlines(MapZoomPair p) {
+ return coastlines.get(p);
}
public SimplisticQuadTree getOrCreateSubTree(int x, int y, int zm) {
@@ -127,10 +138,15 @@ public class CoastlineProcessor {
this.mapZooms = mapZooms;
this.renderingTypes = renderingTypes;
this.zoomWaySmothness = zoomWaySmothness;
- quadTree = constructTilesQuadTree();
+ constructBitSetInfo();
+ quadTrees = new SimplisticQuadTree[mapZooms.getLevels().size()];
+ for (int i=0;i< mapZooms.getLevels().size(); i++) {
+ MapZoomPair p = mapZooms.getLevels().get(i);
+ quadTrees[i] = constructTilesQuadTree(Math.min(p.getMaxZoom() - 1, 1));
+ }
}
- private void constructBitSetInfo(BitSet seaTileInfo , BitSet landTileInfo) {
+ private void constructBitSetInfo() {
try {
InputStream stream = CoastlineProcessor.class.getResourceAsStream("oceantiles_12.dat.bz2");
@@ -167,7 +183,7 @@ public class CoastlineProcessor {
}
}
- private boolean isWaterTile(BitSet seaTileInfo, int x, int y, int zoom) {
+ private boolean isWaterTile(int x, int y, int zoom) {
if (zoom >= TILE_ZOOMLEVEL) {
int x1 = x >> (zoom - TILE_ZOOMLEVEL);
int y1 = y >> (zoom - TILE_ZOOMLEVEL);
@@ -190,7 +206,7 @@ public class CoastlineProcessor {
}
}
- private boolean isLandTile(BitSet landTileInfo, int x, int y, int zoom) {
+ private boolean isLandTile(int x, int y, int zoom) {
if (zoom >= TILE_ZOOMLEVEL) {
int x1 = x >> (zoom - TILE_ZOOMLEVEL);
int y1 = y >> (zoom - TILE_ZOOMLEVEL);
@@ -213,83 +229,75 @@ public class CoastlineProcessor {
}
}
- public SimplisticQuadTree constructTilesQuadTree(){
+ public SimplisticQuadTree constructTilesQuadTree(int maxZoom){
SimplisticQuadTree rootTree = new SimplisticQuadTree(0, 0, 0);
- BitSet seaTileInfo = new BitSet(BITS_COUNT);
- BitSet landTileInfo = new BitSet(BITS_COUNT);
- constructBitSetInfo(seaTileInfo, landTileInfo);
+
int baseZoom = 4;
int tiles = 1 << baseZoom;
ArrayList toVisit = new ArrayList();
- int cnt = 0;
for (int x = 0; x < tiles; x++) {
for (int y = 0; y < tiles; y++) {
toVisit.add(rootTree.getOrCreateSubTree(x, y, baseZoom));
}
}
- int ntc = 0;
- for (int zoom = baseZoom; zoom <= TILE_ZOOMLEVEL && !toVisit.isEmpty(); zoom++) {
- cnt = 0;
+ initializeQuadTree(rootTree, baseZoom, maxZoom, toVisit);
+ return rootTree;
+
+ }
+
+ protected ArrayList initializeQuadTree(SimplisticQuadTree rootTree, int baseZoom, int maxZoom,
+ ArrayList toVisit) {
+ for (int zoom = baseZoom; zoom <= maxZoom && !toVisit.isEmpty(); zoom++) {
ArrayList newToVisit = new ArrayList();
for (SimplisticQuadTree subtree : toVisit) {
int x = subtree.x;
int y = subtree.y;
- if (isWaterTile(seaTileInfo, x, y, zoom)) {
- cnt++;
+ if (isWaterTile(x, y, zoom)) {
rootTree.getOrCreateSubTree(x, y, zoom).ocean = true;
- } else if (isLandTile(landTileInfo, x, y, zoom)) {
+ } else if (isLandTile(x, y, zoom)) {
rootTree.getOrCreateSubTree(x, y, zoom).land = true;
- cnt++;
} else if(zoom < TILE_ZOOMLEVEL){
SimplisticQuadTree[] vis = rootTree.getOrCreateSubTree(x, y, zoom).getOrCreateSubTree(x, y, zoom)
.getAllChildren();
for (SimplisticQuadTree t : vis) {
newToVisit.add(t);
}
- } else {
- ntc ++;
}
}
-// System.out.println(" Zoom " + zoom + " count " + cnt);
toVisit = newToVisit;
}
-// System.out.println("Not covered " + ntc + " from " + (float) ntc / ((1 << TILE_ZOOMLEVEL) * (1< refs = new LinkedHashMap();
- writeBinaryMapTree(simplisticQuadTree, writer, refs);
+ int i = 0;
+ for (MapZoomPair p : mapZooms.getLevels()) {
+ // write map levels and map index
+ writer.startWriteMapLevelIndex(p.getMinZoom(), p.getMaxZoom(), 0, (1 << 31) - 1, 0, (1 << 31) - 1);
- // without data blocks
- writeBinaryMapBlock(simplisticQuadTree, writer, refs);
+ Map refs = new LinkedHashMap();
+ writeBinaryMapTree(quadTrees[i], writer, refs, p);
- writer.endWriteMapLevelIndex();
+ // without data blocks
+ writeBinaryMapBlock(quadTrees[i], writer, refs, p);
+ writer.endWriteMapLevelIndex();
+ i++;
+ }
writer.endWriteMapIndex();
writer.flush();
}
private void writeBinaryMapBlock(SimplisticQuadTree simplisticQuadTree, BinaryMapIndexWriter writer,
- Map refs) throws IOException {
+ Map refs, MapZoomPair p) throws IOException {
Iterator> it = refs.entrySet().iterator();
TIntArrayList type = new TIntArrayList();
type.add(renderingTypes.getCoastlineRuleType().getTargetId());
@@ -299,10 +307,12 @@ public class CoastlineProcessor {
MapDataBlock.Builder dataBlock = MapDataBlock.newBuilder();
SimplisticQuadTree quad = e.getKey();
- for (Way w : quad.coastlines) {
+ for (Way w : quad.getCoastlines(p)) {
dataBlock.setBaseId(w.getId());
+ List res = new ArrayList();
+ MapAlgorithms.simplifyDouglasPeucker(w.getNodes(), p.getMaxZoom() - 2 + 8 + zoomWaySmothness, 3, res);
ByteArrayOutputStream bcoordinates = new ByteArrayOutputStream();
- for (Node n : w.getNodes()) {
+ for (Node n : res) {
if (n != null) {
int y = MapUtils.get31TileNumberY(n.getLatitude());
int x = MapUtils.get31TileNumberX(n.getLongitude());
@@ -323,34 +333,40 @@ public class CoastlineProcessor {
}
private void writeBinaryMapTree(SimplisticQuadTree quadTree, BinaryMapIndexWriter writer,
- Map refs) throws IOException {
+ Map refs, MapZoomPair p) throws IOException {
int xL = (quadTree.x) << (31 - quadTree.zoom);
- int xR = (quadTree.x + 1) << (31 - quadTree.zoom) - 1;
+ 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;
- BinaryFileReference ref = writer.startMapTreeElement(xL, xR, yT, yB, false,
- quadTree.ocean, quadTree.land);
+ int yB = ((quadTree.y + 1) << (31 - quadTree.zoom)) - 1;
+ boolean defined = quadTree.coastlinesDefined(p);
+ boolean ocean = false;
+ boolean land = false;
+ if (!defined) {
+ ocean = quadTree.ocean || isWaterTile(quadTree.x, quadTree.y, quadTree.zoom);
+ land = quadTree.land || isLandTile(quadTree.x, quadTree.y, quadTree.zoom);
+ }
+ BinaryFileReference ref = writer.startMapTreeElement(xL, xR, yT, yB, defined, ocean, land);
if (ref != null) {
refs.put(quadTree, ref);
}
-
+
if (quadTree.areChildrenDefined()) {
SimplisticQuadTree[] allChildren = quadTree.getAllChildren();
for (SimplisticQuadTree ch : allChildren) {
- writeBinaryMapTree(ch, writer, refs);
+ writeBinaryMapTree(ch, writer, refs, p);
}
}
writer.endWriteMapTreeElement();
-
+
}
public void processCoastline(Way e) {
-// for(MapZoomPair p : mapZooms.getLevels()) {
renderingTypes.getCoastlineRuleType().updateFreq();
- MapZoomPair p = mapZooms.getLevels().get(mapZooms.getLevels().size() - 1);
- {
- int z = (p.getMinZoom() + p.getMaxZoom()) / 2;
+ int ij = 0;
+ for(MapZoomPair p : mapZooms.getLevels()) {
+ SimplisticQuadTree quadTree = quadTrees[ij++];
+ int z = Math.min((p.getMinZoom() + p.getMaxZoom()) / 2, p.getMinZoom() + 3);
List ns = e.getNodes();
if(ns.size() < 2) {
return;
@@ -380,20 +396,29 @@ public class CoastlineProcessor {
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 leftX = (tilex << (31 - z)) - 1;
int rightX = (tilex + 1) << (31 - z);
- if( rightX < 0 ){
+ if (rightX < 0) {
rightX = Integer.MAX_VALUE;
}
- int topY = (tiley << (31 - z)) - 1;
+ int topY = (tiley << (31 - z)) - 1;
int bottomY = (tiley + 1) << (31 - z);
- if( bottomY < 0 ){
+ 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;
@@ -409,16 +434,16 @@ public class CoastlineProcessor {
System.err.println("Tile " + tilex + " / " + tiley + " at " + z + " can not be found");
}
}
- quad.addCoastline(w);
- }
+ quad.addCoastline(p, w);
+ }
}
}
- ///////////////////////////// OLD CODE ///////////////////////////////
+ ///////////////////////////// NOT USED CODE TO DELETE ///////////////////////////////
public void processCoastlineOld(Way e) {
WayChain chain = null;
diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java
index 3af551d030..16c23e15aa 100644
--- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java
+++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java
@@ -641,7 +641,10 @@ public class IndexCreator {
// 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);
- zooms = MapZooms.parseZooms("1-5;6-14");
+ // ;6-8;9-14
+ zooms = MapZooms.parseZooms("1-3;4-6;7-9;10-14");
+ creator.setRegionName("basemap");
+ creator.setMapFileName("basemap_coastlines.obf");
creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/basemap/10m_coastline_out.osm"),
new ConsoleProgressImplementation(1), null, zooms, rt, log);
diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java
index a08f149fa4..f86521978d 100644
--- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java
+++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java
@@ -98,7 +98,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
}
public void indexMapRelationsAndMultiPolygons(Entity e, OsmDbAccessorContext ctx) throws SQLException {
-// indexHighwayRestrictions(e, ctx);
indexMultiPolygon(e, ctx);
}
@@ -558,7 +557,7 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
closePreparedStatements(mapBinaryStat, mapLowLevelBinaryStat);
mapConnection.commit();
if(COASTLINE_PROCESS) {
- coastlineProcessor.writeCoastlinesFile(writer);
+ coastlineProcessor.writeCoastlinesFile(writer, regionName);
return;
}
try {
diff --git a/DataExtractionOSM/src/net/osmand/render/default.render.xml b/DataExtractionOSM/src/net/osmand/render/default.render.xml
index 3e90749b9a..05c86e3631 100644
--- a/DataExtractionOSM/src/net/osmand/render/default.render.xml
+++ b/DataExtractionOSM/src/net/osmand/render/default.render.xml
@@ -355,6 +355,8 @@
+
+
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index c86c63b51e..8ca177574b 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -180,7 +180,7 @@
\n\t\'To compass\' - Map will continuously be aligned with device compass reading
\n\tHint: To quickly change between rotation by compass and the one you selected in settings, you can simply tap on the compass needle in map view.
- No offline vector map present for this location.\n\t\n\tYou can download one in \'Settings\' -> \'Offline data\', or switch to online maps via \'Settings\' -> \'Map configuration\'.
+ No offline vector map present for this location. You can download one in Settings (Offline data), or switch to online maps.
Download successful.\n\t\n\tTo use activate \'Settings\' -> \'Map configuration\' -> \'Offline vector maps\'.
Day/Night Mode
diff --git a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java
index 81ead92ed2..88fb42c5cf 100644
--- a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java
+++ b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java
@@ -59,12 +59,12 @@ public class MapRenderRepositories {
private final static Log log = LogUtil.getLog(MapRenderRepositories.class);
private final Context context;
+ private final static int BASEMAP_ZOOM = 7;
private Handler handler;
private Map files = new LinkedHashMap();
private Set nativeFiles = new HashSet();
private OsmandRenderer renderer;
- private static String BASEMAP_NAME = "basemap";
// lat/lon box of requested vector data
private RectF cObjectsBox = new RectF();
@@ -229,8 +229,8 @@ public class MapRenderRepositories {
}
public boolean basemapExists() {
- for (String f : files.keySet()) {
- if (f.toLowerCase().contains(BASEMAP_NAME)) {
+ for (BinaryMapIndexReader f : files.values()) {
+ if (f.isBasemap()) {
return true;
}
}
@@ -245,21 +245,9 @@ public class MapRenderRepositories {
int bottomY = MapUtils.get31TileNumberY(dataBox.bottom);
int topY = MapUtils.get31TileNumberY(dataBox.top);
long now = System.currentTimeMillis();
- // search lower level zooms only in basemap for now :) before it was intersection of maps on zooms 5-7
- boolean basemapSearch = false;
- if (zoom <= 7) {
- for (String f : files.keySet()) {
- if (f.toLowerCase().contains(BASEMAP_NAME)) {
- basemapSearch = true;
- break;
- }
- }
- }
+ // TODO coastline/land tiles
NativeSearchResult resultHandler = null;
for (String mapName : files.keySet()) {
- if (basemapSearch && !mapName.toLowerCase().contains(BASEMAP_NAME)) {
- continue;
- }
BinaryMapIndexReader reader = files.get(mapName);
if(!reader.containsMapData(leftX, topY, rightX, bottomY, zoom)) {
continue;
@@ -301,10 +289,12 @@ public class MapRenderRepositories {
}
try {
int count = 0;
- ArrayList tempList = new ArrayList();
+ ArrayList tempResult = new ArrayList();
+ ArrayList basemapResult = new ArrayList();
System.gc(); // to clear previous objects
TLongSet ids = new TLongHashSet();
List coastLines = new ArrayList();
+ List basemapCoastLines = new ArrayList();
int leftX = MapUtils.get31TileNumberX(cLeftLongitude);
int rightX = MapUtils.get31TileNumberX(cRightLongitude);
int bottomY = MapUtils.get31TileNumberY(cBottomLatitude);
@@ -340,56 +330,81 @@ public class MapRenderRepositories {
if (zoom > 16) {
searchFilter = null;
}
- // search lower level zooms only in basemap for now :) before it was intersection of maps on zooms 5-7
- boolean basemapSearch = false;
- if (zoom <= 7) {
- for (String f : files.keySet()) {
- if (f.toLowerCase().contains(BASEMAP_NAME)) {
- basemapSearch = true;
- break;
- }
- }
- }
-
- for (String mapName : files.keySet()) {
- if (basemapSearch && !mapName.toLowerCase().contains(BASEMAP_NAME)) {
- continue;
- }
-
- BinaryMapIndexReader c = files.get(mapName);
- searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom, searchFilter);
+ boolean ocean = false;
+ MapIndex mi = null;
+ searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom, searchFilter);
+ for (BinaryMapIndexReader c : files.values()) {
+ searchRequest.clearSearchResults();
List res = c.searchMapIndex(searchRequest);
- for (BinaryMapDataObject r : res) {
- if (PerformanceFlags.checkForDuplicateObjectIds) {
- if (ids.contains(r.getId()) && r.getId() > 0) {
- // do not add object twice
- continue;
+ for (BinaryMapDataObject r : res) {
+ if (PerformanceFlags.checkForDuplicateObjectIds) {
+ if (ids.contains(r.getId()) && r.getId() > 0) {
+ // do not add object twice
+ continue;
+ }
+ ids.add(r.getId());
}
- ids.add(r.getId());
- }
- count++;
+ count++;
- if(r.containsType(r.getMapIndex().coastlineEncodingType)){
- coastLines.add(r);
- } else {
- // do not mess coastline and other types
- tempList.add(r);
+ if (r.containsType(r.getMapIndex().coastlineEncodingType)) {
+ if(c.isBasemap()){
+ basemapCoastLines.add(r);
+ } else {
+ coastLines.add(r);
+ }
+ } else {
+ // do not mess coastline and other types
+ if(c.isBasemap()){
+ basemapResult.add(r);
+ } else {
+ tempResult.add(r);
+ }
+ }
+ if (checkWhetherInterrupted()) {
+ return false;
+ }
}
- if (checkWhetherInterrupted()) {
- return false;
- }
-
+
+ if(searchRequest.isOcean() ){
+ mi = c.getMapIndexes().get(0);
+ ocean = true;
+ } else if(searchRequest.isLand()) {
+ mi = c.getMapIndexes().get(0);
}
}
String coastlineTime = "";
+ boolean addBasemapCoastlines = zoom <= BASEMAP_ZOOM;
+ 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);
- tempList.addAll(pcoastlines);
+ List pcoastlines = processCoastlines(coastLines, leftX, rightX, bottomY, topY, zoom,
+ basemapCoastLines.isEmpty());
+ addBasemapCoastlines = pcoastlines.isEmpty() || addBasemapCoastlines;
+ tempResult.addAll(pcoastlines);
+ coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
+ } else if(basemapCoastLines.isEmpty() && mi != null){
+ BinaryMapDataObject o = new BinaryMapDataObject(new int[] { leftX, topY, rightX, topY, rightX, bottomY, leftX, bottomY, leftX,
+ topY }, new int[] { ocean ? mi.coastlineEncodingType : (mi.landEncodingType) }, null, -1);
+ o.setMapIndex(mi);
+ tempResult.add(o);
+ }
+ if(addBasemapCoastlines){
+ long ms = System.currentTimeMillis();
+ List pcoastlines = processCoastlines(basemapCoastLines, leftX, rightX, bottomY, topY, zoom, true);
+ tempResult.addAll(pcoastlines);
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
}
+ if(emptyData && tempResult.size() > 0){
+ BinaryMapDataObject o = tempResult.get(0);
+ o.putObjectName(o.getMapIndex().nameEncodingType, context.getString(R.string.switch_to_raster_map_to_see));
+ }
+ if(zoom <= BASEMAP_ZOOM || tempResult.isEmpty()) {
+ tempResult.addAll(basemapResult);
+ }
+
+
if (count > 0) {
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, zoom));
@@ -397,7 +412,7 @@ public class MapRenderRepositories {
}
- cObjects = tempList;
+ cObjects = tempResult;
cObjectsBox = dataBox;
} catch (IOException e) {
log.debug("Search failed", e); //$NON-NLS-1$
@@ -484,6 +499,7 @@ public class MapRenderRepositories {
} else {
cNativeObjects = null;
loaded = loadVectorData(dataBox, requestedBox.getZoom(), renderingReq, nightMode);
+
}
if (!loaded || checkWhetherInterrupted()) {
return;
@@ -629,7 +645,7 @@ public class MapRenderRepositories {
/// MULTI POLYGONS (coastline)
private List processCoastlines(List coastLines, int leftX, int rightX,
- int bottomY, int topY, int zoom) {
+ int bottomY, int topY, int zoom, boolean showIncompleted) {
List completedRings = new ArrayList();
List uncompletedRings = new ArrayList();
List result = new ArrayList(coastLines.size());
@@ -673,6 +689,11 @@ public class MapRenderRepositories {
if (uncompletedRings.size() > 0) {
unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
}
+ if(!showIncompleted && uncompletedRings.size() > 0){
+ result.clear();
+ return result;
+
+ }
boolean clockwiseFound = false;
long mask = 0xffffffffl;
for (int i = 0; i < completedRings.size(); i++) {
diff --git a/OsmAnd/src/net/osmand/plus/render/MapVectorLayer.java b/OsmAnd/src/net/osmand/plus/render/MapVectorLayer.java
index 1cb4d885f7..906c8615bb 100644
--- a/OsmAnd/src/net/osmand/plus/render/MapVectorLayer.java
+++ b/OsmAnd/src/net/osmand/plus/render/MapVectorLayer.java
@@ -2,7 +2,6 @@ package net.osmand.plus.render;
import net.osmand.access.AccessibleToast;
import net.osmand.osm.MapUtils;
-import net.osmand.plus.R;
import net.osmand.plus.ResourceManager;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.views.BaseMapLayer;
@@ -14,7 +13,6 @@ import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.widget.Toast;
public class MapVectorLayer extends BaseMapLayer {
@@ -104,14 +102,6 @@ public class MapVectorLayer extends BaseMapLayer {
pixRect.set(-view.getWidth() / 3, -view.getHeight() / 4, 4 * view.getWidth() / 3, 5 * view.getHeight() / 4);
updateRotatedTileBox();
resourceManager.updateRendererMap(rotatedTileBox);
- // does it slow down Map refreshing ?
- // Arguments : 1. Map request to read data slows whole process // 2. It works in operating memory
- if (warningToSwitchMapShown < 3) {
- if (!resourceManager.getRenderer().containsLatLonMapData(view.getLatitude(), view.getLongitude(), view.getZoom())) {
- AccessibleToast.makeText(view.getContext(), R.string.switch_to_raster_map_to_see, Toast.LENGTH_LONG).show();
- warningToSwitchMapShown++;
- }
- }
}
}