Add coastline processing

This commit is contained in:
Victor Shcherb 2012-04-01 18:38:10 +02:00
parent 12b09c1300
commit a61c9d9071
6 changed files with 33 additions and 27 deletions

View file

@ -534,10 +534,10 @@ public class BinaryMapIndexReader {
switch (tag) { switch (tag) {
case 0: case 0:
// encoding rules are required! // encoding rules are required!
index.finishInitializingTags();
if(index.encodingRules.isEmpty()){ if(index.encodingRules.isEmpty()){
throw new IllegalStateException("Encoding rules are not defined for the map index"); throw new IllegalStateException("Encoding rules are not defined for the map index");
} }
index.finishInitializingTags();
return; return;
case OsmandOdb.OsmAndMapIndex.NAME_FIELD_NUMBER : case OsmandOdb.OsmAndMapIndex.NAME_FIELD_NUMBER :
index.setName(codedIS.readString()); index.setName(codedIS.readString());
@ -1331,7 +1331,7 @@ public class BinaryMapIndexReader {
} }
public void finishInitializingTags() { public void finishInitializingTags() {
coastlineBrokenEncodingType = encodingRules.size() * 2; coastlineBrokenEncodingType = decodingRules.size() * 2 + 1;
initMapEncodingRule(0, coastlineBrokenEncodingType, "natural", "coastline_broken"); initMapEncodingRule(0, coastlineBrokenEncodingType, "natural", "coastline_broken");
} }

View file

@ -626,7 +626,7 @@ public class IndexCreator {
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);
creator.setIndexAddress(true); creator.setIndexAddress(false);
creator.setIndexPOI(false); creator.setIndexPOI(false);
creator.setIndexTransport(false); creator.setIndexTransport(false);
@ -637,7 +637,7 @@ public class IndexCreator {
creator.setZoomWaySmothness(2); creator.setZoomWaySmothness(2);
MapRenderingTypes rt = MapRenderingTypes.getDefault();// new MapRenderingTypes("/home/victor/projects/OsmAnd/data/testdata/roads_rendering_types.xml"); MapRenderingTypes rt = MapRenderingTypes.getDefault();// new MapRenderingTypes("/home/victor/projects/OsmAnd/data/testdata/roads_rendering_types.xml");
MapZooms zooms = MapZooms.getDefault(); // MapZooms.parseZooms("15-"); 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/luxembourg.osm.pbf"),
creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/cuba.osm.bz2"), creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/cuba.osm.bz2"),
new ConsoleProgressImplementation(1), null, zooms, rt, log); new ConsoleProgressImplementation(1), null, zooms, rt, log);

View file

@ -150,7 +150,11 @@ public class OsmDbAccessor implements OsmDbAccessorContext {
int ord = rs.getInt(2); int ord = rs.getInt(2);
if (ord > 0 || first) { if (ord > 0 || first) {
first = false; first = false;
if(rs.getObject(5) != null) {
((Way) e).addNode(new Node(rs.getDouble(5), rs.getDouble(6), rs.getLong(1))); ((Way) e).addNode(new Node(rs.getDouble(5), rs.getDouble(6), rs.getLong(1)));
} else {
((Way) e).addNode(rs.getLong(1));
}
} }
} }
rs.close(); rs.close();
@ -200,9 +204,6 @@ public class OsmDbAccessor implements OsmDbAccessorContext {
way.putTag(rs.getString(3), rs.getString(4)); way.putTag(rs.getString(3), rs.getString(4));
} }
} }
if (way.getNodes() == null) {
System.err.println("Strange, way with id:" + i.getId() + " has no nodes?");
}
rs.close(); rs.close();
} }
} else if (i.getType() == EntityType.RELATION) { } else if (i.getType() == EntityType.RELATION) {

View file

@ -199,7 +199,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="35"/> <filter tag="highway" value="bridleway" order="35"/>
<filter tag="natural" value="coastline_broken" order="4"/> <filter tag="natural" value="coastline_broken" order="25"/>
</group> </group>
<group objectType="3" point="false"> <group objectType="3" point="false">
@ -824,7 +824,7 @@
<!-- Water, night color 330099 --> <!-- Water, night color 330099 -->
<group> <group>
<filter minzoom="1" tag="natural" value="coastline" color_2="#464646" strokeWidth_2="0.5"/> <filter minzoom="1" tag="natural" value="coastline" color_2="#111111" strokeWidth_2="1"/>
<filter minzoom="4" tag="natural" value="water"/> <filter minzoom="4" tag="natural" value="water"/>
<filter minzoom="4" tag="natural" value="lake"/> <filter minzoom="4" tag="natural" value="lake"/>
<filter minzoom="4" tag="natural" value="bay"/> <filter minzoom="4" tag="natural" value="bay"/>
@ -958,7 +958,7 @@
<line> <line>
<filter minzoom="1" tag="natural" value="coastline_broken" color="#000000" strokeWidth_2="1.5"/> <filter minzoom="1" tag="natural" value="coastline_broken" color="#111111" strokeWidth="2.5"/>
<group> <group>
<filter hmRendered="true" tag="highway" value="motorway" maxzoom="13" color="#809bff"/> <filter hmRendered="true" tag="highway" value="motorway" maxzoom="13" color="#809bff"/>
<filter tag="highway" value="motorway" maxzoom="13" color="#a58dff"/> <filter tag="highway" value="motorway" maxzoom="13" color="#a58dff"/>

View file

@ -676,7 +676,7 @@
<string name="route_tsll">Turn slightly left and go</string> <string name="route_tsll">Turn slightly left and go</string>
<string name="route_tu">Make U-turn and go</string> <string name="route_tu">Make U-turn and go</string>
<string name="route_head">Head</string> <string name="route_head">Head</string>
<string name="first_time_continue">No, Thanks</string> <string name="first_time_continue">Later</string>
<string name="first_time_download">Download regions</string> <string name="first_time_download">Download regions</string>
<string name="first_time_msg">Thank you for choosing OsmAnd. \nTo use the major features of this application, you will need some regional offline data, which you can download (use Settings, Offline Data). Afterwards, you will be able to search by address, look up POIs and find public transportation.</string> <string name="first_time_msg">Thank you for choosing OsmAnd. \nTo use the major features of this application, you will need some regional offline data, which you can download (use Settings, Offline Data). Afterwards, you will be able to search by address, look up POIs and find public transportation.</string>
<string name="search_poi_location">Searching for signal&#8230;</string> <string name="search_poi_location">Searching for signal&#8230;</string>

View file

@ -627,7 +627,7 @@ public class MapRenderRepositories {
private List<BinaryMapDataObject> processCoastlines(List<BinaryMapDataObject> coastLines, int leftX, int rightX, int bottomY, int topY, private List<BinaryMapDataObject> processCoastlines(List<BinaryMapDataObject> coastLines, int leftX, int rightX, int bottomY, int topY,
int zoom) { int zoom) {
List<TLongList> completedRings = new ArrayList<TLongList>(); List<TLongList> completedRings = new ArrayList<TLongList>();
List<TLongList> incompletedRings = new ArrayList<TLongList>(); List<TLongList> uncompletedRings = new ArrayList<TLongList>();
List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>(coastLines.size()); List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>(coastLines.size());
MapIndex mapIndex = null; MapIndex mapIndex = null;
long dbId = 0; long dbId = 0;
@ -653,7 +653,7 @@ public class MapRenderRepositories {
boolean inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY; boolean inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
boolean lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, coordinates); boolean lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, coordinates);
if (lineEnded) { if (lineEnded) {
combineMultipolygonLine(completedRings, incompletedRings, coordinates); combineMultipolygonLine(completedRings, uncompletedRings, coordinates);
// create new line if it goes outside // create new line if it goes outside
coordinates = new TLongArrayList(); coordinates = new TLongArrayList();
} }
@ -661,13 +661,13 @@ public class MapRenderRepositories {
py = y; py = y;
pinside = inside; pinside = inside;
} }
combineMultipolygonLine(completedRings, incompletedRings, coordinates); combineMultipolygonLine(completedRings, uncompletedRings, coordinates);
} }
if (completedRings.size() == 0 && incompletedRings.size() == 0) { if (completedRings.size() == 0 && uncompletedRings.size() == 0) {
return result; return result;
} }
if (incompletedRings.size() > 0) { if (uncompletedRings.size() > 0) {
unifyIncompletedRings(incompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom); unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
} }
boolean clockwiseFound = false; boolean clockwiseFound = false;
int mask = 0xffffffff; int mask = 0xffffffff;
@ -687,8 +687,9 @@ public class MapRenderRepositories {
result.add(o); result.add(o);
} }
for (int i = 0; i < incompletedRings.size(); i++) { // draw uncompleted for debug purpose
TLongList ring = incompletedRings.get(i); for (int i = 0; i < uncompletedRings.size(); i++) {
TLongList ring = uncompletedRings.get(i);
int[] coordinates = new int[ring.size() * 2]; int[] coordinates = new int[ring.size() * 2];
for (int j = 0; j < ring.size(); j++) { for (int j = 0; j < ring.size(); j++) {
coordinates[j * 2] = (int) (ring.get(j) >> 32); coordinates[j * 2] = (int) (ring.get(j) >> 32);
@ -702,6 +703,7 @@ public class MapRenderRepositories {
// 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,
topY }, new int[] { mapIndex.coastlineEncodingType }, null, dbId); topY }, new int[] { mapIndex.coastlineEncodingType }, null, dbId);
o.setMapIndex(mapIndex);
log.info("!!! Isolated islands !!!"); //$NON-NLS-1$ log.info("!!! Isolated islands !!!"); //$NON-NLS-1$
result.add(o); result.add(o);
@ -744,11 +746,13 @@ public class MapRenderRepositories {
} }
} }
private void unifyIncompletedRings(List<TLongList> incompletedRings, List<TLongList> completedRings, int leftX, int rightX, int bottomY, int topY, long dbId, int zoom) { private void unifyIncompletedRings(List<TLongList> toProcces, List<TLongList> completedRings, int leftX, int rightX, int bottomY, int topY, long dbId, int zoom) {
int mask = 0xffffffff; int mask = 0xffffffff;
List<TLongList> uncompletedRings = new ArrayList<TLongList>(toProcces);
toProcces.clear();
Set<Integer> nonvisitedRings = new LinkedHashSet<Integer>(); Set<Integer> nonvisitedRings = new LinkedHashSet<Integer>();
for (int j = 0; j < incompletedRings.size(); j++) { for (int j = 0; j < uncompletedRings.size(); j++) {
TLongList i = incompletedRings.get(j); TLongList i = uncompletedRings.get(j);
int x = (int) (i.get(i.size() - 1) >> 32); int x = (int) (i.get(i.size() - 1) >> 32);
int y = (int) (i.get(i.size() - 1) & mask); int y = (int) (i.get(i.size() - 1) & mask);
int sx = (int) (i.get(0) >> 32); int sx = (int) (i.get(0) >> 32);
@ -775,12 +779,13 @@ public class MapRenderRepositories {
System.err System.err
.println(MessageFormat.format(dbId + str, dx, dy, dsx, dsy, leftX + "", topY + "", rightX + "", bottomY + "")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ .println(MessageFormat.format(dbId + str, dx, dy, dsx, dsy, leftX + "", topY + "", rightX + "", bottomY + "")); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
} }
toProcces.add(i);
} else { } else {
nonvisitedRings.add(j); nonvisitedRings.add(j);
} }
} }
for (int j = 0; j < incompletedRings.size(); j++) { for (int j = 0; j < uncompletedRings.size(); j++) {
TLongList i = incompletedRings.get(j); TLongList i = uncompletedRings.get(j);
if (!nonvisitedRings.contains(j)) { if (!nonvisitedRings.contains(j)) {
continue; continue;
} }
@ -808,7 +813,7 @@ public class MapRenderRepositories {
// BEGIN find closest nonvisited start (including current) // BEGIN find closest nonvisited start (including current)
int mindiff = UNDEFINED_MIN_DIFF; int mindiff = UNDEFINED_MIN_DIFF;
for (Integer ni : nonvisitedRings) { for (Integer ni : nonvisitedRings) {
TLongList cni = incompletedRings.get(ni); TLongList cni = uncompletedRings.get(ni);
int csx = (int) (cni.get(0) >> 32); int csx = (int) (cni.get(0) >> 32);
int csy = (int) (cni.get(0) & mask); int csy = (int) (cni.get(0) & mask);
if (h % 4 == 0) { if (h % 4 == 0) {
@ -877,7 +882,7 @@ public class MapRenderRepositories {
nonvisitedRings.remove(j); nonvisitedRings.remove(j);
break; break;
} else { } else {
i.addAll(incompletedRings.get(nextRingIndex)); i.addAll(uncompletedRings.get(nextRingIndex));
nonvisitedRings.remove(nextRingIndex); nonvisitedRings.remove(nextRingIndex);
// get last point and start again going clockwise // get last point and start again going clockwise
x = (int) (i.get(i.size() - 1) >> 32); x = (int) (i.get(i.size() - 1) >> 32);