Fix bug with multipolygons

This commit is contained in:
Victor Shcherb 2012-05-27 12:18:46 +02:00
parent ef7affc671
commit 868786eefd
10 changed files with 105 additions and 95 deletions

View file

@ -285,9 +285,14 @@ public class MapAlgorithms {
} }
} }
private static long combine2Points(int x, int y) {
return (((long) x ) <<32) | ((long)y );
}
/** /**
* outx,outy are the coordinates out of the box * outx,outy are the coordinates out of the box
* inx,iny are the coordinates from the box * inx,iny are the coordinates from the box (NOT IMPORTANT in/out, just one should be in second out)
* @return -1 if there is no instersection or x<<32 | y * @return -1 if there is no instersection or x<<32 | y
*/ */
public static long calculateIntersection(int inx, int iny, int outx, int outy, int leftX, int rightX, int bottomY, int topY) { public static long calculateIntersection(int inx, int iny, int outx, int outy, int leftX, int rightX, int bottomY, int topY) {
@ -299,7 +304,7 @@ public class MapAlgorithms {
if (leftX <= tx && tx <= rightX) { if (leftX <= tx && tx <= rightX) {
bx = tx; bx = tx;
by = topY; by = topY;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
if (outy > bottomY && iny <= bottomY) { if (outy > bottomY && iny <= bottomY) {
@ -307,7 +312,7 @@ public class MapAlgorithms {
if (leftX <= tx && tx <= rightX) { if (leftX <= tx && tx <= rightX) {
bx = tx; bx = tx;
by = bottomY; by = bottomY;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
if (outx < leftX && inx >= leftX) { if (outx < leftX && inx >= leftX) {
@ -315,7 +320,7 @@ public class MapAlgorithms {
if (ty >= topY && ty <= bottomY) { if (ty >= topY && ty <= bottomY) {
by = ty; by = ty;
bx = leftX; bx = leftX;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
@ -324,7 +329,7 @@ public class MapAlgorithms {
if (ty >= topY && ty <= bottomY) { if (ty >= topY && ty <= bottomY) {
by = ty; by = ty;
bx = rightX; bx = rightX;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
@ -335,7 +340,7 @@ public class MapAlgorithms {
if (leftX <= tx && tx <= rightX) { if (leftX <= tx && tx <= rightX) {
bx = tx; bx = tx;
by = topY; by = topY;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
if (outy < bottomY && iny >= bottomY) { if (outy < bottomY && iny >= bottomY) {
@ -343,7 +348,7 @@ public class MapAlgorithms {
if (leftX <= tx && tx <= rightX) { if (leftX <= tx && tx <= rightX) {
bx = tx; bx = tx;
by = bottomY; by = bottomY;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
if (outx > leftX && inx <= leftX) { if (outx > leftX && inx <= leftX) {
@ -351,7 +356,7 @@ public class MapAlgorithms {
if (ty >= topY && ty <= bottomY) { if (ty >= topY && ty <= bottomY) {
by = ty; by = ty;
bx = leftX; bx = leftX;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }
@ -360,7 +365,7 @@ public class MapAlgorithms {
if (ty >= topY && ty <= bottomY) { if (ty >= topY && ty <= bottomY) {
by = ty; by = ty;
bx = rightX; bx = rightX;
return (((long) bx) << 32) | ((long) by); return combine2Points(bx, by);
} }
} }

View file

@ -359,19 +359,19 @@ public class BinaryMapIndexWriter {
MapData.Builder data = MapData.newBuilder(); MapData.Builder data = MapData.newBuilder();
// calculate size // calculate size
mapDataBuf.clear(); mapDataBuf.clear();
int pcalcx = pleft; int pcalcx = (pleft >> SHIFT_COORDINATES);
int pcalcy = ptop; int pcalcy = (ptop >> SHIFT_COORDINATES);
for (int i = 0; i < coordinates.length / 8; i++) { for (int i = 0; i < coordinates.length / 8; i++) {
int x = Algoritms.parseIntFromBytes(coordinates, i * 8); int x = Algoritms.parseIntFromBytes(coordinates, i * 8);
int y = Algoritms.parseIntFromBytes(coordinates, i * 8 + 4); int y = Algoritms.parseIntFromBytes(coordinates, i * 8 + 4);
int tx = (x - pcalcx) >> SHIFT_COORDINATES; int tx = (x >> SHIFT_COORDINATES) - pcalcx;
int ty = (y - pcalcy) >> SHIFT_COORDINATES; int ty = (y >> SHIFT_COORDINATES) - pcalcy;
writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(tx)); writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(tx));
writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(ty)); writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(ty));
pcalcx = pcalcx + (tx << SHIFT_COORDINATES); pcalcx = pcalcx + tx ;
pcalcy = pcalcy + (ty << SHIFT_COORDINATES); pcalcy = pcalcy + ty ;
} }
COORDINATES_SIZE += CodedOutputStream.computeRawVarint32Size(mapDataBuf.size()) COORDINATES_SIZE += CodedOutputStream.computeRawVarint32Size(mapDataBuf.size())
+ CodedOutputStream.computeTagSize(MapData.COORDINATES_FIELD_NUMBER) + mapDataBuf.size(); + CodedOutputStream.computeTagSize(MapData.COORDINATES_FIELD_NUMBER) + mapDataBuf.size();
@ -383,8 +383,8 @@ public class BinaryMapIndexWriter {
if (innerPolygonTypes != null && innerPolygonTypes.length > 0) { if (innerPolygonTypes != null && innerPolygonTypes.length > 0) {
mapDataBuf.clear(); mapDataBuf.clear();
pcalcx = pleft; pcalcx = (pleft >> SHIFT_COORDINATES);
pcalcy = ptop; pcalcy = (ptop >> SHIFT_COORDINATES);
for (int i = 0; i < innerPolygonTypes.length / 8; i++) { for (int i = 0; i < innerPolygonTypes.length / 8; i++) {
int x = Algoritms.parseIntFromBytes(innerPolygonTypes, i * 8); int x = Algoritms.parseIntFromBytes(innerPolygonTypes, i * 8);
int y = Algoritms.parseIntFromBytes(innerPolygonTypes, i * 8 + 4); int y = Algoritms.parseIntFromBytes(innerPolygonTypes, i * 8 + 4);
@ -393,17 +393,17 @@ public class BinaryMapIndexWriter {
data.addPolygonInnerCoordinates(ByteString.copyFrom(mapDataBuf.toArray())); data.addPolygonInnerCoordinates(ByteString.copyFrom(mapDataBuf.toArray()));
mapDataBuf.clear(); mapDataBuf.clear();
} }
pcalcx = pleft; pcalcx = (pleft >> SHIFT_COORDINATES);
pcalcy = ptop; pcalcy = (ptop >> SHIFT_COORDINATES);
} else { } else {
int tx = (x - pcalcx) >> SHIFT_COORDINATES; int tx = (x >> SHIFT_COORDINATES) - pcalcx;
int ty = (y - pcalcy) >> SHIFT_COORDINATES; int ty = (y >> SHIFT_COORDINATES) - pcalcy;
writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(tx)); writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(tx));
writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(ty)); writeRawVarint32(mapDataBuf, CodedOutputStream.encodeZigZag32(ty));
pcalcx = pcalcx + (tx << SHIFT_COORDINATES); pcalcx = pcalcx + tx ;
pcalcy = pcalcy + (ty << SHIFT_COORDINATES); pcalcy = pcalcy + ty ;
} }
} }
} }

View file

@ -743,7 +743,6 @@ public class IndexCreator {
public static void main(String[] args) throws IOException, SAXException, SQLException, InterruptedException { public static void main(String[] args) throws IOException, SAXException, SQLException, InterruptedException {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$ IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$
creator.setIndexMap(true); creator.setIndexMap(true);

View file

@ -96,9 +96,11 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
boolean inner = "inner".equals(entities.get(es)); //$NON-NLS-1$ boolean inner = "inner".equals(entities.get(es)); //$NON-NLS-1$
if (!inner) { if (!inner) {
outerFound = true; outerFound = true;
for (String t : es.getTagKeySet()) { // This is incorrect (it should be intersection of all boundaries)
e.putTag(t, es.getTag(t)); // Currently it causes an issue with coastline (if one line is coastline)
} // for (String t : es.getTagKeySet()) {
// e.putTag(t, es.getTag(t));
// }
break; break;
} }
} }
@ -518,7 +520,6 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
if (hasMulti) { if (hasMulti) {
TIntArrayList set = multiPolygonsWays.get(e.getId()); TIntArrayList set = multiPolygonsWays.get(e.getId());
typeUse.removeAll(set); typeUse.removeAll(set);
continue;
} }
if (typeUse.isEmpty()) { if (typeUse.isEmpty()) {
continue; continue;

View file

@ -195,8 +195,7 @@
<filter appMode="pedestrian" tag="highway" value="bridleway" order="59"/> <filter appMode="pedestrian" tag="highway" value="bridleway" order="59"/>
<filter tag="highway" value="bridleway" order="36"/> <filter tag="highway" value="bridleway" order="36"/>
<filter tag="natural" value="coastline_broken" order="25"/> <filter tag="natural" value="coastline_broken" order="35"/>
<filter tag="contour" value="" order="15"/> <filter tag="contour" value="" order="15"/>
</group> </group>

View file

@ -4,7 +4,7 @@
Disclaimer : Disclaimer :
If you are going to translate strings, please make sure : If you are going to translate strings, please make sure :
1. There is no duplicate strings by name 1. There is no duplicate strings by name
2. Every apostrophe is started with quote (look others). 2. Every apostrophe (quote) is preceded by a backslash (see others).
If you are making/correcting english translations make sure : If you are making/correcting english translations make sure :
1. All your modified/created strings are in the top of the file (to make easier find what's translated). 1. All your modified/created strings are in the top of the file (to make easier find what's translated).
--> -->

View file

@ -206,10 +206,10 @@ public class LocalIndexHelper {
Map<String, String> loadedMaps = app.getResourceManager().getIndexFileNames(); Map<String, String> loadedMaps = app.getResourceManager().getIndexFileNames();
List<LocalIndexInfo> result = new ArrayList<LocalIndexInfo>(); List<LocalIndexInfo> result = new ArrayList<LocalIndexInfo>();
loadTilesData(settings.extendOsmandPath(ResourceManager.TILES_PATH), result, false, loadTask);
loadTilesData(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), result, false, loadTask);
loadObfData(settings.extendOsmandPath(ResourceManager.MAPS_PATH), result, false, loadTask, loadedMaps); loadObfData(settings.extendOsmandPath(ResourceManager.MAPS_PATH), result, false, loadTask, loadedMaps);
loadObfData(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), result, true, loadTask, loadedMaps); loadObfData(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), result, true, loadTask, loadedMaps);
loadTilesData(settings.extendOsmandPath(ResourceManager.TILES_PATH), result, false, loadTask);
loadTilesData(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), result, false, loadTask);
loadPoiData(settings.extendOsmandPath(ResourceManager.POI_PATH), result, false, loadTask); loadPoiData(settings.extendOsmandPath(ResourceManager.POI_PATH), result, false, loadTask);
loadPoiData(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), result, true, loadTask); loadPoiData(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), result, true, loadTask);
loadVoiceData(settings.extendOsmandPath(ResourceManager.VOICE_PATH), result, false, loadTask); loadVoiceData(settings.extendOsmandPath(ResourceManager.VOICE_PATH), result, false, loadTask);

View file

@ -401,18 +401,16 @@ public class MapRenderRepositories {
if(!coastLines.isEmpty()) { if(!coastLines.isEmpty()) {
long ms = System.currentTimeMillis(); long ms = System.currentTimeMillis();
List<BinaryMapDataObject> pcoastlines = processCoastlines(coastLines, leftX, rightX, bottomY, topY, zoom, boolean coastlinesWereAdded = processCoastlines(coastLines, leftX, rightX, bottomY, topY, zoom,
basemapCoastLines.isEmpty()); basemapCoastLines.isEmpty(), true, tempResult);
addBasemapCoastlines = pcoastlines.isEmpty() || zoom <= BASEMAP_ZOOM; addBasemapCoastlines = !coastlinesWereAdded || zoom <= BASEMAP_ZOOM;
tempResult.addAll(pcoastlines);
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )"; coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
} }
if(addBasemapCoastlines){ if(addBasemapCoastlines){
addBasemapCoastlines = false;
long ms = System.currentTimeMillis(); long ms = System.currentTimeMillis();
List<BinaryMapDataObject> pcoastlines = processCoastlines(basemapCoastLines, leftX, rightX, bottomY, topY, zoom, true); boolean coastlinesWereAdded = processCoastlines(basemapCoastLines, leftX, rightX, bottomY, topY, zoom,
addBasemapCoastlines = pcoastlines.isEmpty(); true, true, tempResult);
tempResult.addAll(pcoastlines); addBasemapCoastlines = !coastlinesWereAdded;
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )"; coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
} }
if(addBasemapCoastlines && mi != null){ if(addBasemapCoastlines && mi != null){
@ -673,11 +671,11 @@ public class MapRenderRepositories {
} }
/// MULTI POLYGONS (coastline) /// MULTI POLYGONS (coastline)
private List<BinaryMapDataObject> processCoastlines(List<BinaryMapDataObject> coastLines, int leftX, int rightX, // returns true if coastlines were added!
int bottomY, int topY, int zoom, boolean showIncompleted) { private boolean processCoastlines(List<BinaryMapDataObject> coastLines, int leftX, int rightX,
int bottomY, int topY, int zoom, boolean doNotAddIfIncompleted, boolean addDebugIncompleted, List<BinaryMapDataObject> result) {
List<TLongList> completedRings = new ArrayList<TLongList>(); List<TLongList> completedRings = new ArrayList<TLongList>();
List<TLongList> uncompletedRings = new ArrayList<TLongList>(); List<TLongList> uncompletedRings = new ArrayList<TLongList>();
List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>(coastLines.size());
MapIndex mapIndex = null; MapIndex mapIndex = null;
long dbId = 0; long dbId = 0;
for (BinaryMapDataObject o : coastLines) { for (BinaryMapDataObject o : coastLines) {
@ -694,7 +692,7 @@ public class MapRenderRepositories {
int y = py; int y = py;
boolean pinside = leftX <= x && x <= rightX && y >= topY && y <= bottomY; boolean pinside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
if (pinside) { if (pinside) {
coordinates.add((((long) x) << 32) | ((long) y)); coordinates.add(combine2Points(x, y));
} }
for (int i = 1; i < len; i++) { for (int i = 1; i < len; i++) {
x = o.getPoint31XTile(i); x = o.getPoint31XTile(i);
@ -713,18 +711,29 @@ public class MapRenderRepositories {
combineMultipolygonLine(completedRings, uncompletedRings, coordinates); combineMultipolygonLine(completedRings, uncompletedRings, coordinates);
} }
if (completedRings.size() == 0 && uncompletedRings.size() == 0) { if (completedRings.size() == 0 && uncompletedRings.size() == 0) {
return result; return false;
} }
if (uncompletedRings.size() > 0) { if (uncompletedRings.size() > 0) {
unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom); unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
} }
if(!showIncompleted && uncompletedRings.size() > 0){ long mask = 0xffffffffl;
result.clear(); // draw uncompleted for debug purpose
return result; for (int i = 0; i < uncompletedRings.size(); i++) {
TLongList ring = uncompletedRings.get(i);
int[] coordinates = new int[ring.size() * 2];
for (int j = 0; j < ring.size(); j++) {
coordinates[j * 2] = (int) (ring.get(j) >> 32);
coordinates[j * 2 + 1] = (int) (ring.get(j) & mask);
}
BinaryMapDataObject o = new BinaryMapDataObject(coordinates, new int[] { mapIndex.coastlineBrokenEncodingType }, null, dbId);
o.setMapIndex(mapIndex);
result.add(o);
}
if(!doNotAddIfIncompleted && uncompletedRings.size() > 0){
return false;
} }
boolean clockwiseFound = false; boolean clockwiseFound = false;
long mask = 0xffffffffl;
for (int i = 0; i < completedRings.size(); i++) { for (int i = 0; i < completedRings.size(); i++) {
TLongList ring = completedRings.get(i); TLongList ring = completedRings.get(i);
int[] coordinates = new int[ring.size() * 2]; int[] coordinates = new int[ring.size() * 2];
@ -741,18 +750,6 @@ public class MapRenderRepositories {
result.add(o); result.add(o);
} }
// draw uncompleted for debug purpose
for (int i = 0; i < uncompletedRings.size(); i++) {
TLongList ring = uncompletedRings.get(i);
int[] coordinates = new int[ring.size() * 2];
for (int j = 0; j < ring.size(); j++) {
coordinates[j * 2] = (int) (ring.get(j) >> 32);
coordinates[j * 2 + 1] = (int) (ring.get(j) & mask);
}
BinaryMapDataObject o = new BinaryMapDataObject(coordinates, new int[] { mapIndex.coastlineBrokenEncodingType}, null, dbId);
o.setMapIndex(mapIndex);
result.add(o);
}
if (!clockwiseFound && uncompletedRings.size() == 0) { if (!clockwiseFound && uncompletedRings.size() == 0) {
// add complete water tile // add complete water tile
BinaryMapDataObject o = new BinaryMapDataObject(new int[] { leftX, topY, rightX, topY, rightX, bottomY, leftX, bottomY, leftX, BinaryMapDataObject o = new BinaryMapDataObject(new int[] { leftX, topY, rightX, topY, rightX, bottomY, leftX, bottomY, leftX,
@ -762,23 +759,27 @@ public class MapRenderRepositories {
result.add(o); result.add(o);
} }
return result; return true;
}
private boolean eq(long i1, long i2){
return i1 == i2;
} }
private void combineMultipolygonLine(List<TLongList> completedRings, List<TLongList> incompletedRings, TLongList coordinates) { private void combineMultipolygonLine(List<TLongList> completedRings, List<TLongList> incompletedRings, TLongList coordinates) {
if (coordinates.size() > 0) { if (coordinates.size() > 0) {
if (coordinates.get(0) == coordinates.get(coordinates.size() - 1)) { if (eq(coordinates.get(0), coordinates.get(coordinates.size() - 1))) {
completedRings.add(coordinates); completedRings.add(coordinates);
} else { } else {
boolean add = true; boolean add = true;
for (int k = 0; k < incompletedRings.size();) { for (int k = 0; k < incompletedRings.size();) {
boolean remove = false; boolean remove = false;
TLongList i = incompletedRings.get(k); TLongList i = incompletedRings.get(k);
if (coordinates.get(0) == i.get(i.size() - 1)) { if (eq(coordinates.get(0), i.get(i.size() - 1))) {
i.addAll(coordinates.subList(1, coordinates.size())); i.addAll(coordinates.subList(1, coordinates.size()));
remove = true; remove = true;
coordinates = i; coordinates = i;
} else if (coordinates.get(coordinates.size() - 1) == i.get(0)) { } else if (eq(coordinates.get(coordinates.size() - 1), i.get(0))) {
coordinates.addAll(i.subList(1, i.size())); coordinates.addAll(i.subList(1, i.size()));
remove = true; remove = true;
} }
@ -787,7 +788,7 @@ public class MapRenderRepositories {
} else { } else {
k++; k++;
} }
if (coordinates.get(0) == coordinates.get(coordinates.size() - 1)) { if (eq(coordinates.get(0), coordinates.get(coordinates.size() - 1))) {
completedRings.add(coordinates); completedRings.add(coordinates);
add = false; add = false;
break; break;
@ -958,6 +959,10 @@ public class MapRenderRepositories {
return res; return res;
} }
private static long combine2Points(int x, int y) {
return (((long) x ) <<32) | ((long)y );
}
private boolean calculateLineCoordinates(boolean inside, int x, int y, boolean pinside, int px, int py, int leftX, int rightX, private boolean calculateLineCoordinates(boolean inside, int x, int y, boolean pinside, int px, int py, int leftX, int rightX,
int bottomY, int topY, TLongList coordinates) { int bottomY, int topY, TLongList coordinates) {
boolean lineEnded = false; boolean lineEnded = false;
@ -966,19 +971,19 @@ public class MapRenderRepositories {
long is = MapAlgorithms.calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY); long is = MapAlgorithms.calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
if (is == -1) { if (is == -1) {
// it is an error (!) // it is an error (!)
is = (((long) px) << 32) | ((long) py); is = combine2Points(px, py);
} }
coordinates.add(is); coordinates.add(is);
lineEnded = true; lineEnded = true;
} else { } else {
coordinates.add((((long) x) << 32) | ((long) y)); coordinates.add(combine2Points(x, y));
} }
} else { } else {
long is = MapAlgorithms.calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY); long is = MapAlgorithms.calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY);
if (inside) { if (inside) {
// assert is != -1; // assert is != -1;
coordinates.add(is); coordinates.add(is);
coordinates.add((((long) x) << 32) | ((long) y)); coordinates.add(combine2Points(x, y));
} else if (is != -1) { } else if (is != -1) {
int bx = (int) (is >> 32); int bx = (int) (is >> 32);
int by = (int) (is & 0xffffffff); int by = (int) (is & 0xffffffff);

View file

@ -784,17 +784,15 @@ ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates,
bool addBasemapCoastlines = true; bool addBasemapCoastlines = true;
bool emptyData = q->zoom > BASEMAP_ZOOM && tempResult.empty() && coastLines.empty(); bool emptyData = q->zoom > BASEMAP_ZOOM && tempResult.empty() && coastLines.empty();
if (!coastLines.empty()) { if (!coastLines.empty()) {
std::vector<MapDataObject*> pcoastlines; bool coastlinesWereAdded = processCoastlines(coastLines, q->left, q->right, q->bottom, q->top, q->zoom,
processCoastlines(coastLines, q->left, q->right, q->bottom, q->top, q->zoom, basemapCoastLines.empty(), pcoastlines); basemapCoastLines.empty(), true, tempResult);
addBasemapCoastlines = pcoastlines.empty() || q->zoom <= BASEMAP_ZOOM; addBasemapCoastlines = !coastlinesWereAdded || q->zoom <= BASEMAP_ZOOM;
tempResult.insert(tempResult.end(), pcoastlines.begin(), pcoastlines.end());
} }
if (addBasemapCoastlines) { if (addBasemapCoastlines) {
addBasemapCoastlines = false; addBasemapCoastlines = false;
std::vector<MapDataObject*> pcoastlines; bool coastlinesWereAdded = processCoastlines(basemapCoastLines, q->left, q->right, q->bottom, q->top, q->zoom,
processCoastlines(basemapCoastLines, q->left, q->right, q->bottom, q->top, q->zoom, true, pcoastlines); true, true, tempResult);
addBasemapCoastlines = pcoastlines.empty(); addBasemapCoastlines = !coastlinesWereAdded;
tempResult.insert(tempResult.end(), pcoastlines.begin(), pcoastlines.end());
} }
// processCoastlines always create new objects // processCoastlines always create new objects
deleteObjects(basemapCoastLines); deleteObjects(basemapCoastLines);

View file

@ -4,12 +4,12 @@
#include "multipolygons.h" #include "multipolygons.h"
#include "osmand_log.h" #include "osmand_log.h"
void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int rightX, int bottomY, int topY, int zoom, // returns true if coastlines were added!
bool showIncompleted, std::vector<MapDataObject*>& res) { bool processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int rightX, int bottomY, int topY, int zoom,
bool showIfThereIncompleted, bool addDebugIncompleted, std::vector<MapDataObject*>& res) {
std::vector<coordinates> completedRings; std::vector<coordinates> completedRings;
std::vector<coordinates > uncompletedRings; std::vector<coordinates > uncompletedRings;
std::vector<MapDataObject*>::iterator val = coastLines.begin(); std::vector<MapDataObject*>::iterator val = coastLines.begin();
res.reserve(coastLines.size());
long long dbId = 0; long long dbId = 0;
for (; val != coastLines.end(); val++) { for (; val != coastLines.end(); val++) {
MapDataObject* o = *val; MapDataObject* o = *val;
@ -44,14 +44,23 @@ void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int
combineMultipolygonLine(completedRings, uncompletedRings, *cs); combineMultipolygonLine(completedRings, uncompletedRings, *cs);
} }
if (completedRings.size() == 0 && uncompletedRings.size() == 0) { if (completedRings.size() == 0 && uncompletedRings.size() == 0) {
return; return false;
} }
if (uncompletedRings.size() > 0) { if (uncompletedRings.size() > 0) {
unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom); unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
} }
if (!showIncompleted && uncompletedRings.size() > 0) { if (addDebugIncompleted) {
res.clear(); // draw uncompleted for debug purpose
return; for (int i = 0; i < uncompletedRings.size(); i++) {
MapDataObject* o = new MapDataObject();
o->points = uncompletedRings[i];
o->types.push_back(tag_value("natural", "coastline_broken"));
res.push_back(o);
}
}
if (!showIfThereIncompleted && uncompletedRings.size() > 0) {
return false;
} }
bool clockwiseFound = false; bool clockwiseFound = false;
for (int i = 0; i < completedRings.size(); i++) { for (int i = 0; i < completedRings.size(); i++) {
@ -69,13 +78,6 @@ void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int
res.push_back(o); res.push_back(o);
} }
// draw uncompleted for debug purpose
for (int i = 0; i < uncompletedRings.size(); i++) {
MapDataObject* o = new MapDataObject();
o->points = uncompletedRings[i];
o->types.push_back(tag_value("natural", "coastline_broken"));
//res.push_back(o);
}
if (!clockwiseFound && uncompletedRings.size() == 0) { if (!clockwiseFound && uncompletedRings.size() == 0) {
// add complete water tile // add complete water tile
MapDataObject* o = new MapDataObject(); MapDataObject* o = new MapDataObject();
@ -90,6 +92,7 @@ void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int
res.push_back(o); res.push_back(o);
} }
return true;
} }
// Copied from MapAlgorithms // Copied from MapAlgorithms