Implement base map layer. Fix some bugs

This commit is contained in:
Victor Shcherb 2011-06-19 19:06:35 +02:00
parent 3ee0d8dcd7
commit 802c52c860
61 changed files with 712 additions and 263 deletions

View file

@ -13,6 +13,9 @@ public class ToDoConstants {
// Map Refactoring
// Remove notification from OsmAndMapTileView (?)
// Yandex Traffic make downloadable
// Index version
// 1. POI inside obf
// 2. Multiple attributes for one point (amenity=circle, type=...)
// === Refactoring issues ===

View file

@ -28,14 +28,14 @@ public class Boundary {
int intersections = 0;
for(Way w : outerWays){
for(int i=0; i<w.getNodes().size() - 1; i++){
if(ray_intersect(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude)){
if(MapAlgorithms.ray_intersect(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude)){
intersections ++;
}
}
}
for(Way w : innerWays){
for(int i=0; i<w.getNodes().size() - 1; i++){
if(ray_intersect(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude)){
if(MapAlgorithms.ray_intersect(w.getNodes().get(i), w.getNodes().get(i+1), latitude, longitude)){
intersections ++;
}
}
@ -44,39 +44,6 @@ public class Boundary {
return intersections % 2 == 1;
}
// Try to intersect with ray from left to right
private boolean ray_intersect(Node node, Node node2, double latitude, double longitude) {
// a node below
Node a = node.getLatitude() < node2.getLatitude() ? node : node2;
// b node above
Node b = a == node2 ? node : node2;
if(latitude == a.getLatitude() || latitude == b.getLatitude()){
latitude += 0.00000001d;
}
if(latitude < a.getLatitude() || latitude > b.getLatitude()){
return false;
} else {
if(longitude > Math.max(a.getLongitude(), b.getLongitude())) {
return true;
} else if(longitude < Math.min(a.getLongitude(), b.getLongitude())){
return false;
} else {
if(a.getLongitude() == b.getLongitude()) {
// the node on the boundary !!!
return true;
}
// that tested on all cases (left/right)
double mR = (b.getLatitude() - a.getLatitude()) / (b.getLongitude() - a.getLongitude());
double mB = (latitude - a.getLatitude()) / (longitude - a.getLongitude());
if(mB <= mR){
return true;
} else {
return false;
}
}
}
}
public LatLon getCenterPoint(){
List<Node> points = new ArrayList<Node>();
for(Way w : outerWays){

View file

@ -1,8 +1,10 @@
package net.osmand.data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.osm.Node;
import net.osmand.osm.Way;
@ -61,6 +63,9 @@ public class MapAlgorithms {
}
private static double orthogonalDistance(int zoom, Node nodeLineStart, Node nodeLineEnd, Node node) {
if(zoom > 31){
zoom = 31;
}
double x1 = MapUtils.getTileNumberX(zoom, nodeLineStart.getLongitude());
double y1 = MapUtils.getTileNumberY(zoom, nodeLineStart.getLatitude());
double x2 = MapUtils.getTileNumberX(zoom, nodeLineEnd.getLongitude());
@ -73,4 +78,138 @@ public class MapAlgorithms {
double D = y2 - y1;
return Math.abs(A * D - C * B) / Math.sqrt(C * C + D * D);
}
public static boolean isClockwiseWay(Way w){
return isClockwiseWay(Collections.singletonList(w));
}
public static boolean isClockwiseWay(List<Way> ways){
if(ways.isEmpty()){
return true;
}
LatLon latLon = ways.get(0).getLatLon();
double lat = latLon.getLatitude();
double lon = 180;
double firstLon = -360;
boolean firstDirectionUp = false;
double previousLon = -360;
double clockwiseSum = 0;
Node prev = null;
boolean firstWay = true;
for(Way w : ways){
List<Node> ns = w.getNodes();
int startInd = 0;
if(firstWay && ns.size() > 0){
prev = ns.get(0);
startInd = 1;
firstWay = false;
}
for(int i = startInd; i < ns.size();i++) {
Node next = ns.get(i);
double rlon = ray_intersect_lon(prev, next, lat, lon);
if(rlon != - 360d){
boolean skipSameSide = (prev.getLatitude() <= lat) == (next.getLatitude() <= lat);
if(skipSameSide){
continue;
}
boolean directionUp = prev.getLatitude() <= lat;
if(firstLon == - 360){
firstDirectionUp = directionUp;
firstLon = rlon;
} else {
boolean clockwise = (!directionUp) == (previousLon < rlon);
if(clockwise){
clockwiseSum += Math.abs(previousLon - rlon);
} else {
clockwiseSum -= Math.abs(previousLon - rlon);
}
}
previousLon = rlon;
}
prev = next;
}
}
if(firstLon != -360){
boolean clockwise = (!firstDirectionUp) == (previousLon < firstLon);
if(clockwise){
clockwiseSum += Math.abs(previousLon - firstLon);
} else {
clockwiseSum -= Math.abs(previousLon - firstLon);
}
}
return clockwiseSum >= 0;
}
public static double ray_intersect_lon(Node node, Node node2, double latitude, double longitude) {
// a node below
Node a = node.getLatitude() < node2.getLatitude() ? node : node2;
// b node above
Node b = a == node2 ? node : node2;
if (latitude == a.getLatitude() || latitude == b.getLatitude()) {
latitude += 0.00000001d;
}
if (latitude < a.getLatitude() || latitude > b.getLatitude()) {
return -360d;
} else {
if (longitude < Math.min(a.getLongitude(), b.getLongitude())) {
return -360d;
} else {
if (a.getLongitude() == b.getLongitude() && longitude == a.getLongitude()) {
// the node on the boundary !!!
return longitude;
}
// that tested on all cases (left/right)
double lon = b.getLongitude()+
(b.getLatitude() - latitude) * (b.getLongitude() - a.getLongitude()) / (b.getLatitude() - a.getLatitude());
if (lon <= longitude) {
return lon;
} else {
return -360d;
}
}
}
}
// Try to intersect with ray from left to right
public static boolean ray_intersect(Node node, Node node2, double latitude, double longitude) {
// a node below
Node a = node.getLatitude() < node2.getLatitude() ? node : node2;
// b node above
Node b = a == node2 ? node : node2;
if(latitude == a.getLatitude() || latitude == b.getLatitude()){
latitude += 0.00000001d;
}
if(latitude < a.getLatitude() || latitude > b.getLatitude()){
return false;
} else {
if(longitude > Math.max(a.getLongitude(), b.getLongitude())) {
return true;
} else if(longitude < Math.min(a.getLongitude(), b.getLongitude())){
return false;
} else {
if(a.getLongitude() == b.getLongitude()) {
// the node on the boundary !!!
return true;
}
// that tested on all cases (left/right)
double mR = (b.getLatitude() - a.getLatitude()) / (b.getLongitude() - a.getLongitude());
double mB = (latitude - a.getLatitude()) / (longitude - a.getLongitude());
if(mB <= mR){
return true;
} else {
return false;
}
}
}
}
}

View file

@ -10,11 +10,13 @@ import java.io.RandomAccessFile;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import net.osmand.Algoritms;
import net.osmand.IProgress;
import net.osmand.binary.BinaryMapIndexWriter;
import net.osmand.data.IndexConstants;
import net.osmand.data.preparation.MapZooms.MapZoomPair;
import net.osmand.data.preparation.OsmDbAccessor.OsmDbVisitor;
import net.osmand.impl.ConsoleProgressImplementation;
import net.osmand.osm.Entity;
@ -63,11 +65,14 @@ public class IndexCreator {
private boolean normalizeStreets = true; // true by default
private boolean saveAddressWays = true; // true by default
private int zoomWaySmothness = 0;
private String regionName;
private String poiFileName = null;
private String mapFileName = null;
private Long lastModifiedDate = null;
private IndexTransportCreator indexTransportCreator;
@ -116,6 +121,10 @@ public class IndexCreator {
public void setNormalizeStreets(boolean normalizeStreets) {
this.normalizeStreets = normalizeStreets;
}
public void setZoomWaySmothness(int zoomWaySmothness) {
this.zoomWaySmothness = zoomWaySmothness;
}
public String getRegionName() {
if (regionName == null) {
@ -351,7 +360,7 @@ public class IndexCreator {
this.accessor = new OsmDbAccessor();
indexMapCreator.initSettings(mapZooms, renderingTypes);
indexMapCreator.initSettings(mapZooms, renderingTypes, zoomWaySmothness);
// init address
String[] normalizeDefaultSuffixes = null;
@ -587,9 +596,9 @@ public class IndexCreator {
long time = System.currentTimeMillis();
IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$
creator.setIndexMap(true);
creator.setIndexAddress(true);
creator.setIndexPOI(true);
creator.setIndexTransport(true);
// creator.setIndexAddress(true);
// creator.setIndexPOI(true);
// creator.setIndexTransport(true);
// for NL
// creator.setCityAdminLevel("10");
@ -597,11 +606,24 @@ public class IndexCreator {
creator.deleteDatabaseIndexes = true;
creator.deleteOsmDB = true;
creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/410/map.osm"),
new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null);
// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/410/map.osm"),
// new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null);
// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/minsk_around.osm"),
// new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null);
MapZooms mapZooms = new MapZooms();
MapZoomPair pair1 = new MapZooms.MapZoomPair(1, 3);
MapZoomPair pair2 = new MapZooms.MapZoomPair(4, 5);
MapZoomPair pair3 = new MapZooms.MapZoomPair(6, 7);
mapZooms.setLevels(Arrays.asList(pair1, pair2, pair3));
creator.setZoomWaySmothness(2);
creator.generateIndexes(new File(
"/home/victor/projects/OsmAnd/download/basemap/10m_coastline_out.osm"
// "/home/victor/projects/OsmAnd/download/basemap/10-admin-0-countries.osm"
// "/home/victor/projects/OsmAnd/download/basemap/10m_populated_places.osm"
),
new ConsoleProgressImplementation(1), null, mapZooms, null);
// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb"));

View file

@ -12,7 +12,6 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -67,6 +66,8 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
private int lowLevelWays = -1;
private RTree[] mapTree = null;
private Connection mapConnection;
private int zoomWaySmothness = 0;
public IndexVectorMapCreator() {
@ -354,10 +355,9 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
boolean point = (type & 3) == MapRenderingTypes.POINT_TYPE;
RTree rtree = null;
int zoom;
long id = (baseId << 3) | ((level & 3) << 1);
rtree = mapTree[level];
zoom = mapZooms.getLevel(level).getMaxZoom() - 1;
boolean skip = false;
String eName = renderingTypes.getEntityName(e);
@ -368,11 +368,13 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
if (e.getTag(OSMTagKey.HIGHWAY) != null) {
highwayAttributes = MapRenderingTypes.getHighwayAttributes(e);
}
if (e instanceof Way) {
id |= 1;
// simplify route
if (level > 0) {
e = simplifyWay((Way) e, id, hasMulti, zoom, eName, type, level);
int zoomToSimplify = mapZooms.getLevel(level).getMaxZoom() - 1;
if (zoomToSimplify < 15) {
e = simplifyWay((Way) e, id, hasMulti, zoomToSimplify, eName, type, level);
skip = e == null;
}
@ -443,12 +445,13 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
boolean cycle = originalE.getNodeIds().get(0).longValue() == originalE.getNodeIds().get(nodes.size() - 1).longValue();
long longType = encodeTypesToOneLong(type);
boolean skip = checkForSmallAreas(nodes, zoom, 3, 3);
if (skip && cycle/* || !hasMulti)*/) {
return null;
if (cycle) {
if(checkForSmallAreas(nodes, zoom + Math.min(zoomWaySmothness / 2, 3), 1, 4)){
return null;
}
}
MapAlgorithms.simplifyDouglasPeucker(nodes, zoom + 8, 3, way);
MapAlgorithms.simplifyDouglasPeucker(nodes, zoom + 8 + zoomWaySmothness, 3, way);
if (way.getNodes().size() < 2) {
return null;
}
@ -575,12 +578,12 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
boolean cycle = startNode == endNode;
boolean hasMulti = multiPolygonsWays[level].containsKey(id >> 3);
if(cycle || !hasMulti){
skip = checkForSmallAreas(wNodes, zoom - 1, 1, 4);
skip = checkForSmallAreas(wNodes, zoom - 1 + Math.min(zoomWaySmothness / 2, 3), 1, 4);
}
if (!skip) {
Way newWs = new Way(id);
MapAlgorithms.simplifyDouglasPeucker(wNodes, zoom - 1 + 8, 3, newWs);
MapAlgorithms.simplifyDouglasPeucker(wNodes, zoom - 1 + 8 + zoomWaySmothness, 3, newWs);
int type = decodeTypesFromOneLong(ltype);
insertBinaryMapRenderObjectIndex(mapTree[level], newWs, name,
@ -617,8 +620,9 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
}
@SuppressWarnings("unchecked")
public void initSettings(MapZooms mapZooms, MapRenderingTypes renderingTypes) {
public void initSettings(MapZooms mapZooms, MapRenderingTypes renderingTypes, int zoomWaySmothness) {
this.mapZooms = mapZooms;
this.zoomWaySmothness = zoomWaySmothness;
this.renderingTypes = renderingTypes;
// init map
multiPolygonsWays = new Map[mapZooms.size()];
@ -633,9 +637,10 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
if (e instanceof Way || e instanceof Node) {
// manipulate what kind of way to load
ctx.loadEntityData(e, false);
boolean inverse = "-1".equals(e.getTag(OSMTagKey.ONEWAY)); //$NON-NLS-1$
boolean oneway = "-1".equals(e.getTag(OSMTagKey.ONEWAY)); //$NON-NLS-1$
for (int i = 0; i < mapZooms.size(); i++) {
writeBinaryEntityToMapDatabase(e, e.getId(), i == 0 ? inverse : false, i);
boolean inverse = i == 0 ? oneway : false;
writeBinaryEntityToMapDatabase(e, e.getId(), inverse, i);
}
}
}
@ -922,4 +927,12 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
closeAllPreparedStatements();
}
public void setZoomWaySmothness(int zoomWaySmothness) {
this.zoomWaySmothness = zoomWaySmothness;
}
public int getZoomWaySmothness() {
return zoomWaySmothness;
}
}

View file

@ -1,11 +1,14 @@
package net.osmand.data.preparation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MapZooms {
public static class MapZoomPair {
public static int MAX_ALLOWED_ZOOM = 22;
private int minZoom;
private int maxZoom;
@ -22,6 +25,10 @@ public class MapZooms {
return maxZoom;
}
@Override
public String toString() {
return "MapZoomPair : " + minZoom + " - "+ maxZoom;
}
}
private List<MapZoomPair> levels = new ArrayList<MapZoomPair>();
@ -33,6 +40,13 @@ public class MapZooms {
public void setLevels(List<MapZoomPair> levels) {
this.levels = levels;
Collections.sort(levels, new Comparator<MapZoomPair>() {
@Override
public int compare(MapZoomPair o1, MapZoomPair o2) {
return -new Integer(o1.getMaxZoom()).compareTo(o2.getMaxZoom());
}
});
}
/**
* @param zooms - could be 5-8;7-10;13-15;15
@ -51,7 +65,7 @@ public class MapZooms {
list.add(0, new MapZoomPair(Integer.parseInt(s.substring(0, i)), Integer.parseInt(s.substring(i + 1))));
}
}
list.add(0, new MapZoomPair(zeroLevel, 22));
list.add(0, new MapZoomPair(zeroLevel, MapZoomPair.MAX_ALLOWED_ZOOM));
if(list.size() < 1 || list.size() > 4){
throw new IllegalArgumentException("Map zooms should have at least 1 level and less than 4 levels");
}

View file

@ -137,17 +137,18 @@ public class MapRenderingTypes {
// val could be null means others for that tag
private Integer nullRule;
private Map<String, Integer> rules = new LinkedHashMap<String, Integer>();
private String nameNullTag;
private Map<String, String> nameNullTag = new LinkedHashMap<String, String>();
public MapRulType(String tag, String nameNullTag){
this.tag = tag;
this.nameNullTag.put(null, nameNullTag);
}
public String getTag() {
return tag;
}
public String getNameNullTag() {
public Map<String, String> getNameNullTag() {
return nameNullTag;
}
@ -563,8 +564,10 @@ public class MapRenderingTypes {
for (String tag : tagKeySet) {
if (types.containsKey(tag)) {
MapRulType rType = types.get(tag);
if (rType.getNameNullTag() != null) {
name = e.getTag(rType.getNameNullTag());
String val = i == 1 ? null : e.getTag(tag);
String nameNullTag = rType.getNameNullTag().get(val);
if (nameNullTag != null) {
name = e.getTag(nameNullTag);
if (name != null) {
break;
}
@ -765,10 +768,13 @@ public class MapRenderingTypes {
if(st == INIT_RULE_TYPES){
MapRulType rtype = types.get(tag);
if(rtype == null){
rtype = new MapRulType(tag, nameNullTag);
rtype = new MapRulType(tag, null);
types.put(tag, rtype);
}
rtype.registerType(minZoom, val, pointRule, polylineRule, polygonRule, type, subtype);
if(nameNullTag != null){
rtype.getNameNullTag().put(val, nameNullTag);
}
} else if(st == INIT_AMENITY_MAP){
if(pointRule == POINT_TYPE || polygonRule == POLYGON_WITH_CENTER_TYPE || polygonRule == POLYGON_TYPE){
registerAmenity(tag, val, type, subtype);

View file

@ -37,7 +37,11 @@ public class Way extends Entity {
if(nodeIds == null){
return null;
}
return nodeIds.remove(i);
Long toReturn = nodeIds.remove(i);
if(nodes != null && nodes.size() > i){
nodes.remove(i);
}
return toReturn;
}
public List<Long> getNodeIds(){

View file

@ -409,7 +409,7 @@
<type id="17" name="natural">
<subtype id="5" polygon="true" tag="natural" value="coastline" minzoom="5" />
<subtype id="5" polygon="true" tag="natural" value="coastline" minzoom="1" />
<subtype id="1" point="true" polygon="true" tag="natural" value="bay" minzoom="15" />
<subtype id="2" point="true" polygon="true" tag="natural" value="beach" minzoom="12" />
<subtype id="3" point="true" polygon_center="true" tag="natural" value="cave_entrance" minzoom="13" />
@ -540,14 +540,16 @@
</type>
<type id="25" name="administrative">
<subtype id="41" point="true" tag="place" value="continent" minzoom="5" />
<subtype id="42" point="true" tag="place" value="country" minzoom="5" />
<subtype id="43" point="true" tag="place" value="state" minzoom="5" />
<subtype id="44" point="true" tag="place" value="region" minzoom="5" />
<subtype id="45" point="true" tag="place" value="county" minzoom="5" />
<subtype id="6" point="true" polygon_center="true" tag="place" value="city" minzoom="6" />
<subtype id="7" point="true" polygon_center="true" tag="place" value="town" minzoom="7" />
<subtype id="6" point="true" polygon_center="true" tag="place" value="city" minzoom="4" />
<subtype id="7" point="true" polygon_center="true" tag="place" value="town" minzoom="6" />
<subtype id="8" point="true" polygon_center="true" tag="place" value="village" minzoom="10" />
<subtype id="9" point="true" polygon_center="true" tag="place" value="hamlet" minzoom="10" />
<subtype id="10" point="true" polygon_center="true" tag="place" value="suburb" minzoom="10" />
@ -570,8 +572,10 @@
<subtype id="19" polyline="true" tag="boundary" value="national_park" minzoom="7" />
<subtype id="20" polyline="true" tag="boundary" value="protected_area" minzoom="7" />
<subtype id="33" point="true" tag="addr:housenumber" minzoom="15" />
</type>
<type id="27" name="sport">
<subtype id="1" point="true" tag="sport" value="9pin" minzoom="15" />
@ -623,4 +627,11 @@
<subtype id="47" point="true" tag="sport" value="volleyball" minzoom="15" />
<subtype id="50" point="true" tag="sport" minzoom="15" />
</type>
<!-- Processing base map at the end to not override tag/values for decoding -->
<type id="25" name="administrative">
<!-- same as town/city -->
<subtype id="6" point="true" tag="MEGACITY" value="1" minzoom="4" nameNullTag="NAME"/>
<subtype id="7" point="true" tag="MEGACITY" value="0" minzoom="6" nameNullTag="NAME"/>
</type>
</osmand_types>

View file

@ -0,0 +1,244 @@
package net.osmand.osm.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLStreamException;
import net.osmand.data.MapAlgorithms;
import net.osmand.impl.ConsoleProgressImplementation;
import net.osmand.osm.Entity;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.osm.Node;
import net.osmand.osm.Way;
import net.osmand.osm.Entity.EntityId;
import net.osmand.osm.Entity.EntityType;
import net.osmand.osm.OSMSettings.OSMTagKey;
import net.osmand.osm.io.OsmBaseStorage;
import net.osmand.osm.io.OsmStorageWriter;
import org.xml.sax.SAXException;
public class FixLinkedCoastline {
public static void main(String[] args) throws IOException, SAXException, XMLStreamException {
String fileToRead = args != null && args.length > 0 ? args[0] : null;
if(fileToRead == null) {
fileToRead = "/home/victor/projects/OsmAnd/download/basemap/10m_coastline.osm";
}
File read = new File(fileToRead);
File write ;
String fileToWrite = args != null && args.length > 1 ? args[1] : null;
if(fileToWrite != null){
write = new File(fileToWrite);
} else {
String fileName = read.getName();
int i = fileName.lastIndexOf('.');
fileName = fileName.substring(0, i) + "_out"+ fileName.substring(i);
write = new File(read.getParentFile(), fileName);
}
write.createNewFile();
process(read, write);
}
private static void process(File read, File write) throws IOException, SAXException, XMLStreamException {
OsmBaseStorage storage = new OsmBaseStorage();
storage.parseOSM(new FileInputStream(read), new ConsoleProgressImplementation());
Map<EntityId, Entity> entities = new HashMap<EntityId, Entity>( storage.getRegisteredEntities());
List<EntityId> toWrite = new ArrayList<EntityId>();
for(EntityId e : entities.keySet()){
if(e.getType() == EntityType.WAY){
Entity oldWay = storage.getRegisteredEntities().remove(e);
List<Way> result = processWay((Way) oldWay);
alignAndAddtoStorage(storage, toWrite, result);
}
}
System.out.println("ERROR Ways : ");
int errors = 0;
for(List<Way> w : endWays.values()){
Way way = w.get(0);
Way lway = w.get(w.size() - 1);
LatLon first = way.getNodes().get(0).getLatLon();
LatLon last = lway.getNodes().get(lway.getNodes().size() - 1).getLatLon();
double dist = MapUtils.getDistance(first, last);
if(dist < 500 && w.size() >= 3){
alignAndAddtoStorage(storage, toWrite, w);
} else {
errors++;
String val = "First " + first+ "Last " + last + " id " + way.getId() + " dist " + MapUtils.getDistance(first, last) + " m";
System.out.println("Ways in chain - " + w.size() + " - " + val);
}
}
System.out.println("Fixed errors : " + ERRORS +", errors not fixed : " + errors );
OsmStorageWriter writer = new OsmStorageWriter();
writer.saveStorage(new FileOutputStream(write), storage, toWrite, true);
}
private static void alignAndAddtoStorage(OsmBaseStorage storage, List<EntityId> toWrite, List<Way> result) {
// align start/end node and add to strage
for (int i = 0; i < result.size(); i++) {
Node nextStart;
if (i < result.size() - 1) {
nextStart = result.get(i + 1).getNodes().get(0);
} else {
nextStart = result.get(0).getNodes().get(0);
}
Way w = result.get(i);
int sz = w.getNodes().size();
w.removeNodeByIndex(sz - 1);
w.addNode(nextStart);
if("land_coastline".equals(w.getTag(OSMTagKey.NATURAL))) {
w.putTag(OSMTagKey.NATURAL.getValue(), "coastline");
}
EntityId eId = EntityId.valueOf(w);
storage.getRegisteredEntities().put(eId, w);
toWrite.add(eId);
}
}
private static long calcCoordinate(net.osmand.osm.Node node){
LatLon l = node.getLatLon();
double lon =l.getLongitude();
if(180 - Math.abs(l.getLongitude()) < 0.0001){
if(l.getLongitude() < 0){
lon = -179.9999;
} else {
lon = 180;
}
}
return ((long)MapUtils.getTileNumberY(21, l.getLatitude()) << 32l) + ((long)MapUtils.getTileNumberX(21, lon));
}
private static Map<Long, List<Way>> startWays = new LinkedHashMap<Long, List<Way>>();
private static Map<Long, List<Way>> endWays = new LinkedHashMap<Long, List<Way>>();
private static Map<Way, LatLon> duplicatedSimpleIslands = new LinkedHashMap<Way, LatLon>();
private static int ERRORS = 0;
private static Way revertWay(Way way){
ArrayList<net.osmand.osm.Node> revNodes = new ArrayList<net.osmand.osm.Node>(way.getNodes());
Collections.reverse(revNodes);
Way ws = new Way(way.getId());
for(String key : way.getTagKeySet()){
ws.putTag(key, way.getTag(key));
}
for(net.osmand.osm.Node n : revNodes){
ws.addNode(n);
}
return ws;
}
private static boolean pointContains(long start, long end){
return startWays.containsKey(start) || endWays.containsKey(end) || startWays.containsKey(end) || endWays.containsKey(start);
}
private static long lastPoint(Way w){
return calcCoordinate(w.getNodes().get(w.getNodes().size() - 1));
}
private static long lastPoint(List<Way> w){
return lastPoint(w.get(w.size() - 1));
}
private static long firstPoint(List<Way> w){
return firstPoint(w.get(0));
}
private static long firstPoint(Way way) {
return calcCoordinate(way.getNodes().get(0));
}
private static List<Way> processWay(Way way) {
// F Lat 8.27039215702537 Lon 73.0661727222713L Lat 8.27039215702537 Lon 73.0661727222713 id -1211228
long start = firstPoint(way);
long end = lastPoint(way);
LatLon first = way.getNodes().get(0).getLatLon();
LatLon last = way.getNodes().get(way.getNodes().size() - 1).getLatLon();
String val = "F " + first + "L " + last + " id " + way.getId();
List<Way> cycle = null;
if (start == end || MapUtils.getDistance(first, last) < 20) {
LatLon c = way.getLatLon();
cycle = Collections.singletonList(way);
for(Way w : duplicatedSimpleIslands.keySet()){
LatLon center = duplicatedSimpleIslands.get(w);
if(MapUtils.getDistance(center, c) < 4000){
//System.out.println("DUPLICATED " + first);
return Collections.emptyList();
}
}
duplicatedSimpleIslands.put(way, c);
} else {
List<Way> list = new ArrayList<Way>();
list.add(way);
// System.out.println(val);
while (pointContains(start, end)) {
if (startWays.containsKey(start) || endWays.containsKey(end)) {
ERRORS++;
Collections.reverse(list);
for (int i = 0; i < list.size(); i++) {
list.set(i, revertWay(list.get(i)));
}
long t = start;
start = end;
end = t;
}
if (endWays.containsKey(start)) {
List<Way> tlist = endWays.remove(start);
startWays.remove(firstPoint(tlist));
tlist.addAll(list);
list = tlist;
} else if (startWays.containsKey(end)) {
List<Way> tlist = startWays.remove(end);
endWays.remove(lastPoint(tlist));
list.addAll(tlist);
}
start = firstPoint(list);
end = lastPoint(list);
if (start == end) {
cycle = list;
break;
}
}
if (cycle == null) {
startWays.put(start, list);
endWays.put(end, list);
}
}
if (cycle != null) {
boolean clockwiseWay = MapAlgorithms.isClockwiseWay(cycle);
if (clockwiseWay) {
List<Way> ways = new ArrayList<Way>();
ERRORS ++;
for (int i = cycle.size() - 1; i >= 0; i--) {
// System.out.println("Cycle error " + way.getId());
ways.add(revertWay(cycle.get(i)));
}
return ways;
}
return cycle;
}
return Collections.emptyList();
}
}

View file

@ -310,12 +310,13 @@
<filter minzoom="4" maxzoom="7" textSize="9" textColor="#9d6c9d" textHaloRadius="1" textWrapWidth="20" tag="place" value="region" />
<filter minzoom="8" textSize="11" textColor="#9d6c9d" textHaloRadius="1" textWrapWidth="20" tag="place" value="region" />
<filter minzoom="6" maxzoom="8" textSize="8" textHaloRadius="1" textWrapWidth="20" tag="place" value="city" />
<filter minzoom="9" maxzoom="10" textSize="11" textHaloRadius="1" textWrapWidth="20" tag="place" value="city" />
<filter minzoom="4" maxzoom="6" textSize="10" textHaloRadius="1" textWrapWidth="20" tag="place" value="city" />
<filter minzoom="7" maxzoom="8" textSize="11" textHaloRadius="1" textWrapWidth="20" tag="place" value="city" />
<filter minzoom="9" maxzoom="10" textSize="12" textHaloRadius="1" textWrapWidth="20" tag="place" value="city" />
<filter minzoom="11" textSize="14" textHaloRadius="1" textWrapWidth="20" tag="place" value="city" />
<filter minzoom="9" maxzoom="10" textSize="8" textHaloRadius="1" textWrapWidth="20" tag="place" value="town" />
<filter minzoom="11" maxzoom="13" textSize="11" textHaloRadius="1" textWrapWidth="20" tag="place" value="town" />
<filter minzoom="14" textSize="13" textColor="#777777" textHaloRadius="1" textWrapWidth="20" tag="place" value="town" />
<filter minzoom="6" maxzoom="10" textSize="10" textHaloRadius="1" textWrapWidth="20" tag="place" value="town" />
<filter minzoom="11" maxzoom="13" textSize="12" textHaloRadius="1" textWrapWidth="20" tag="place" value="town" />
<filter minzoom="14" textSize="14" textColor="#777777" textHaloRadius="1" textWrapWidth="20" tag="place" value="town" />
<filter minzoom="12" maxzoom="14" textSize="9" textHaloRadius="1" tag="place" value="village" />
<filter minzoom="15" textSize="12" textColor="#777777" textHaloRadius="1" tag="place" value="village" />
@ -447,6 +448,9 @@
<filter minzoom="16" icon="viewpoint" tag="tourism" value="viewpoint" />
<filter minzoom="16" icon="geocache_found" tag="geocache" value="found" />
<filter minzoom="16" icon="geocache_not_found" tag="geocache" />
<filter minzoom="4" maxzoom="12" icon="city" value="city" />
<filter minzoom="6" maxzoom="14" icon="city" value="town" />
</point>
<!-- PRIORITY Input to filter : tag, value, zoom [minzoom, maxzoom] -->
@ -498,7 +502,7 @@
<filter minzoom="14" color="#30666600" color_2="#60666600" strokeWidth_2="1" tag="natural" value="field" />
<filter color="#b5d0d0">
<filter minzoom="6" tag="natural" value="coastline" />
<filter minzoom="1" tag="natural" value="coastline" />
<filter minzoom="7" tag="natural" value="water" />
<filter minzoom="7" tag="natural" value="lake" />
</filter>

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

View file

@ -53,7 +53,7 @@
<string name="tip_day_night_mode">Day/Night Mode</string>
<string name="tip_day_night_mode_t">\tThe map appearance can for some vector maps be changed between day (brighter) and night (darker).
\n\tNight colors are safer for night driving.
\n\tYou can set a policy for day/night switching in \'Main Menu\' -> \'Settings\' -> \'Maps\' ->\'Day/night mode\'.
\n\tYou can set a policy for day/night switching in \'Main Menu\' -> \'Settings\' -> \'Map appearance\' ->\'Day/night mode\'.
\n\tChoices are:
\n\t\'Sunrise/Sunset\' - automatic mode, controlled by position of the sun (default)
\n\t\'Day\' - always use day mode

View file

@ -500,7 +500,7 @@ public class OsmandSettings {
public final OsmandPreference<Integer> MAX_LEVEL_TO_DOWNLOAD_TILE = new IntPreference("max_level_download_tile", 18, false, true);
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<Integer> LEVEL_TO_SWITCH_VECTOR_RASTER = new IntPreference("level_to_switch_vector_raster", 5, false, true);
public final OsmandPreference<Integer> LEVEL_TO_SWITCH_VECTOR_RASTER = new IntPreference("level_to_switch_vector_raster", 1, false, true);
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<Boolean> MAP_VIEW_3D = new BooleanPreference("map_view_3d", false, false);

View file

@ -164,9 +164,11 @@ public class MainMenuActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean exit = false;
if(getIntent() != null){
Intent intent = getIntent();
if(intent.getExtras() != null && intent.getExtras().containsKey(APP_EXIT_KEY)){
exit = true;
finish();
}
}
@ -222,10 +224,11 @@ public class MainMenuActivity extends Activity {
activity.startActivity(search);
}
});
if(exit){
return;
}
((OsmandApplication)getApplication()).checkApplicationIsBeingInitialized(this);
((OsmandApplication)getApplication()).checkApplicationIsBeingInitialized(this);
SharedPreferences pref = getPreferences(MODE_WORLD_WRITEABLE);
boolean firstTime = false;
if(!pref.contains(FIRST_TIME_APP_RUN)){

View file

@ -231,7 +231,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
}
registerListPreference(osmandSettings.MAX_LEVEL_TO_DOWNLOAD_TILE, screen, entries, intValues);
startZoom = 3;
startZoom = 1;
endZoom = 18;
entries = new String[endZoom - startZoom + 1];
intValues = new Integer[endZoom - startZoom + 1];

View file

@ -93,24 +93,24 @@ public class MapVectorLayer extends BaseMapLayer {
tileLayer.drawTileMap(canvas, tilesRect);
resourceManager.getRenderer().interruptLoadingMap();
} else {
if (!view.isZooming()){
if (!view.isZooming()) {
pixRect.set(0, 0, view.getWidth(), view.getHeight());
updateRotatedTileBox();
if(resourceManager.updateRenderedMapNeeded(rotatedTileBox)){
if (resourceManager.updateRenderedMapNeeded(rotatedTileBox)) {
// pixRect.set(-view.getWidth(), -view.getHeight() / 2, 2 * view.getWidth(), 3 * view.getHeight() / 2);
pixRect.set(-view.getWidth()/3, -view.getHeight() / 4, 4 * view.getWidth() /3, 5 * view.getHeight() / 4);
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){
if(!resourceManager.getRenderer().containsLatLonMapData(view.getLatitude(), view.getLongitude(), view.getZoom())){
if (!warningToSwitchMapShown) {
if (!resourceManager.getRenderer().containsLatLonMapData(view.getLatitude(), view.getLongitude(), view.getZoom())) {
Toast.makeText(view.getContext(), R.string.switch_to_raster_map_to_see, Toast.LENGTH_LONG).show();
warningToSwitchMapShown = true;
}
}
}
}
MapRenderRepositories renderer = resourceManager.getRenderer();

View file

@ -685,8 +685,8 @@ public class OsmandRenderer {
rc.main.updatePaint(paint);
canvas.drawPath(path, paint);
// for test purpose
// rc.second.strokeWidth = 1.5f;
// rc.second.color = Color.BLACK;
// rc.second.strokeWidth = 1.5f;
// rc.second.color = Color.BLACK;
if (rc.second.strokeWidth != 0) {
rc.second.updatePaint(paint);

View file

@ -1,9 +1,11 @@
package net.osmand.plus.render;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
import net.osmand.plus.R;
import net.osmand.plus.R.drawable;
public class RenderingIcons {
@ -16,183 +18,19 @@ public class RenderingIcons {
return icons;
}
private static void initIcons() {
icons.put("aerodrome", R.drawable.h_aerodrome); //$NON-NLS-1$
icons.put("airport", R.drawable.h_airport); //$NON-NLS-1$
icons.put("alpine_hut", R.drawable.h_alpine_hut); //$NON-NLS-1$
icons.put("amenity_court", R.drawable.h_amenity_court); //$NON-NLS-1$
icons.put("arts_centre", R.drawable.g_amenity_arts_centre); //$NON-NLS-1$
icons.put("atm", R.drawable.h_atm); //$NON-NLS-1$
icons.put("bank", R.drawable.h_bank); //$NON-NLS-1$
icons.put("bar", R.drawable.h_bar); //$NON-NLS-1$
icons.put("beach", R.drawable.h_beach); //$NON-NLS-1$
icons.put("bench", R.drawable.g_amenity_bench); //$NON-NLS-1$
icons.put("biergarten", R.drawable.h_biergarten); //$NON-NLS-1$
icons.put("bicycle_rental", R.drawable.h_bicycle_rental); //$NON-NLS-1$
icons.put("bollard", R.drawable.h_bollard); //$NON-NLS-1$
icons.put("books", R.drawable.g_shop_books); //$NON-NLS-1$
icons.put("bus_station", R.drawable.h_bus_station); //$NON-NLS-1$
icons.put("bus_stop_small", R.drawable.h_bus_stop_small); //$NON-NLS-1$
icons.put("bus_stop", R.drawable.h_bus_stop); //$NON-NLS-1$
icons.put("cable_car", R.drawable.h_cable_car); //$NON-NLS-1$
icons.put("cafe", R.drawable.h_cafe); //$NON-NLS-1$
icons.put("camp_site", R.drawable.h_camp_site); //$NON-NLS-1$
icons.put("car_sharing", R.drawable.h_car_sharing); //$NON-NLS-1$
icons.put("caravan_park", R.drawable.h_caravan_park); //$NON-NLS-1$
icons.put("casino", R.drawable.g_tourist_casino); //$NON-NLS-1$
icons.put("castle", R.drawable.g_historic_castle); //$NON-NLS-1$
icons.put("cave_entrance", R.drawable.h_cave_entrance); //$NON-NLS-1$
icons.put("chair_lift", R.drawable.h_chair_lift); //$NON-NLS-1$
icons.put("chalet", R.drawable.h_chalet); //$NON-NLS-1$
icons.put("cinema", R.drawable.h_cinema); //$NON-NLS-1$
icons.put("cliff", R.drawable.h_cliff); //$NON-NLS-1$
icons.put("cliff2", R.drawable.h_cliff2); //$NON-NLS-1$
icons.put("computer", R.drawable.g_shop_computer); //$NON-NLS-1$
icons.put("confectionery", R.drawable.g_shop_confectionery); //$NON-NLS-1$
icons.put("courthouse", R.drawable.g_amenity_courthouse); //$NON-NLS-1$
icons.put("danger", R.drawable.h_danger); //$NON-NLS-1$
icons.put("department_store", R.drawable.h_department_store); //$NON-NLS-1$
icons.put("do_it_yourself", R.drawable.g_shop_diy); //$NON-NLS-1$
icons.put("drinking_water", R.drawable.h_drinking_water); //$NON-NLS-1$
icons.put("embassy", R.drawable.h_embassy); //$NON-NLS-1$
icons.put("emergency_phone", R.drawable.h_emergency_phone); //$NON-NLS-1$
icons.put("entrance", R.drawable.g_barrier_entrance); //$NON-NLS-1$
icons.put("exchange", R.drawable.g_money_exchange); //$NON-NLS-1$
icons.put("fast_food", R.drawable.h_fast_food); //$NON-NLS-1$
icons.put("fire_station", R.drawable.h_fire_station); //$NON-NLS-1$
icons.put("forest", R.drawable.h_forest); //$NON-NLS-1$
icons.put("fuel", R.drawable.h_fuel); //$NON-NLS-1$
icons.put("gate2", R.drawable.h_gate2); //$NON-NLS-1$
icons.put("geocache_found", R.drawable.h_geocache_found); //$NON-NLS-1$
icons.put("geocache_not_found", R.drawable.h_geocache_not_found); //$NON-NLS-1$
icons.put("guest_house", R.drawable.h_guest_house); //$NON-NLS-1$
icons.put("glacier", R.drawable.h_glacier); //$NON-NLS-1$
icons.put("grave_yard", R.drawable.h_grave_yard); //$NON-NLS-1$
icons.put("guest_house", R.drawable.h_guest_house); //$NON-NLS-1$
icons.put("florist", R.drawable.h_florist); //$NON-NLS-1$
icons.put("fountain", R.drawable.g_amenity_fountain); //$NON-NLS-1$
icons.put("garden_centre", R.drawable.g_shop_garden_centre); //$NON-NLS-1$
icons.put("halt", R.drawable.h_halt); //$NON-NLS-1$
icons.put("helipad", R.drawable.h_helipad); //$NON-NLS-1$
icons.put("hospital", R.drawable.h_hospital); //$NON-NLS-1$
icons.put("hostel", R.drawable.h_hostel); //$NON-NLS-1$
icons.put("hotel", R.drawable.h_hotel); //$NON-NLS-1$
icons.put("ice_cream", R.drawable.g_food_ice_cream); //$NON-NLS-1$
icons.put("information", R.drawable.h_information); //$NON-NLS-1$
icons.put("jewelry", R.drawable.g_shop_jewelry); //$NON-NLS-1$
icons.put("kiosk", R.drawable.g_shop_kiosk); //$NON-NLS-1$
icons.put("level_crossing", R.drawable.h_level_crossing); //$NON-NLS-1$
icons.put("level_crossing2", R.drawable.h_level_crossing2); //$NON-NLS-1$
icons.put("library", R.drawable.h_library); //$NON-NLS-1$
icons.put("liftgate", R.drawable.h_liftgate); //$NON-NLS-1$
icons.put("lighthouse", R.drawable.h_lighthouse); //$NON-NLS-1$
icons.put("lock_gate", R.drawable.h_lock_gate); //$NON-NLS-1$
icons.put("marketplace", R.drawable.g_amenity_marketplace); //$NON-NLS-1$
icons.put("marsh", R.drawable.h_marsh); //$NON-NLS-1$
icons.put("mast", R.drawable.h_mast); //$NON-NLS-1$
icons.put("memorial", R.drawable.h_memorial); //$NON-NLS-1$
icons.put("motel", R.drawable.h_motel); //$NON-NLS-1$
icons.put("mini_roundabout", R.drawable.h_mini_roundabout); //$NON-NLS-1$
icons.put("mud", R.drawable.h_mud); //$NON-NLS-1$
icons.put("museum", R.drawable.h_museum); //$NON-NLS-1$
icons.put("music", R.drawable.g_shop_music); //$NON-NLS-1$
icons.put("nr", R.drawable.h_nr); //$NON-NLS-1$
icons.put("optician", R.drawable.g_health_optician); //$NON-NLS-1$
icons.put("orchard", R.drawable.h_orchard); //$NON-NLS-1$
icons.put("parking", R.drawable.h_parking); //$NON-NLS-1$
icons.put("peak", R.drawable.h_peak); //$NON-NLS-1$
icons.put("shop_pet", R.drawable.g_shop_pet); //$NON-NLS-1$
icons.put("pharmacy", R.drawable.h_pharmacy); //$NON-NLS-1$
icons.put("picnic_site", R.drawable.h_picnic_site); //$NON-NLS-1$
icons.put("place_of_worship", R.drawable.h_place_of_worship); //$NON-NLS-1$
icons.put("playground", R.drawable.h_playground); //$NON-NLS-1$
icons.put("police", R.drawable.h_police); //$NON-NLS-1$
icons.put("postbox", R.drawable.h_postbox); //$NON-NLS-1$
icons.put("postoffice", R.drawable.h_postoffice); //$NON-NLS-1$
icons.put("power_tower", R.drawable.h_power_tower); //$NON-NLS-1$
icons.put("power_wind", R.drawable.h_power_wind); //$NON-NLS-1$
icons.put("prison", R.drawable.h_prison); //$NON-NLS-1$
icons.put("pub", R.drawable.h_pub); //$NON-NLS-1$
icons.put("quarry2", R.drawable.h_quarry2); //$NON-NLS-1$
icons.put("recycling", R.drawable.h_recycling); //$NON-NLS-1$
icons.put("restaurant", R.drawable.h_restaurant); //$NON-NLS-1$
icons.put("school", R.drawable.h_school); //$NON-NLS-1$
icons.put("scrub", R.drawable.h_scrub); //$NON-NLS-1$
icons.put("shelter", R.drawable.h_shelter); //$NON-NLS-1$
icons.put("shop_bakery", R.drawable.h_shop_bakery); //$NON-NLS-1$
icons.put("shop_butcher", R.drawable.h_shop_butcher); //$NON-NLS-1$
icons.put("shop_clothes", R.drawable.h_shop_clothes); //$NON-NLS-1$
icons.put("shop_convenience", R.drawable.h_shop_convenience); //$NON-NLS-1$
icons.put("shop_diy", R.drawable.h_shop_diy); //$NON-NLS-1$
icons.put("shop_bicycle", R.drawable.h_shop_bicycle); //$NON-NLS-1$
icons.put("shop_car", R.drawable.h_shop_car); //$NON-NLS-1$
icons.put("shop_car_repair", R.drawable.h_shop_car_repair); //$NON-NLS-1$
icons.put("shop_hairdresser", R.drawable.h_shop_hairdresser); //$NON-NLS-1$
icons.put("shop_supermarket", R.drawable.h_shop_supermarket); //$NON-NLS-1$
icons.put("slipway", R.drawable.h_slipway); //$NON-NLS-1$
icons.put("sports_centre", R.drawable.g_leisure_sports_centre); //$NON-NLS-1$
icons.put("spring", R.drawable.h_spring); //$NON-NLS-1$
icons.put("station_small", R.drawable.h_station_small); //$NON-NLS-1$
icons.put("station", R.drawable.h_station); //$NON-NLS-1$
icons.put("subway_entrance", R.drawable.h_subway_entrance); //$NON-NLS-1$
icons.put("taxi", R.drawable.g_transport_taxi); //$NON-NLS-1$
icons.put("telephone", R.drawable.h_telephone); //$NON-NLS-1$
icons.put("theatre", R.drawable.h_theatre); //$NON-NLS-1$
icons.put("toilets", R.drawable.h_toilets); //$NON-NLS-1$
icons.put("toys", R.drawable.g_shop_toys); //$NON-NLS-1$
icons.put("traffic_light", R.drawable.h_traffic_light); //$NON-NLS-1$
icons.put("highway_ford", R.drawable.h_highway_ford); //$NON-NLS-1$
icons.put("tree", R.drawable.h_tree); //$NON-NLS-1$
icons.put("tree2", R.drawable.h_tree2); //$NON-NLS-1$
icons.put("university", R.drawable.g_amenity_university); //$NON-NLS-1$
icons.put("vending_machine", R.drawable.g_amenity_vending_machine); //$NON-NLS-1$
icons.put("viewpoint", R.drawable.h_viewpoint); //$NON-NLS-1$
icons.put("vineyard", R.drawable.h_vineyard); //$NON-NLS-1$
icons.put("volcano", R.drawable.h_volcano); //$NON-NLS-1$
icons.put("water_tower", R.drawable.h_water_tower); //$NON-NLS-1$
icons.put("windmill", R.drawable.h_windmill); //$NON-NLS-1$
icons.put("zoo", R.drawable.h_zoo); //$NON-NLS-1$
icons.put("mot_shield1", R.drawable.mot_shield1); //$NON-NLS-1$
icons.put("mot_shield2", R.drawable.mot_shield2); //$NON-NLS-1$
icons.put("mot_shield3", R.drawable.mot_shield3); //$NON-NLS-1$
icons.put("mot_shield4", R.drawable.mot_shield4); //$NON-NLS-1$
icons.put("mot_shield5", R.drawable.mot_shield5); //$NON-NLS-1$
icons.put("mot_shield6", R.drawable.mot_shield6); //$NON-NLS-1$
icons.put("mot_shield7", R.drawable.mot_shield7); //$NON-NLS-1$
icons.put("mot_shield8", R.drawable.mot_shield8); //$NON-NLS-1$
icons.put("pri_shield1", R.drawable.pri_shield1); //$NON-NLS-1$
icons.put("pri_shield2", R.drawable.pri_shield2); //$NON-NLS-1$
icons.put("pri_shield3", R.drawable.pri_shield3); //$NON-NLS-1$
icons.put("pri_shield4", R.drawable.pri_shield4); //$NON-NLS-1$
icons.put("pri_shield5", R.drawable.pri_shield5); //$NON-NLS-1$
icons.put("pri_shield6", R.drawable.pri_shield6); //$NON-NLS-1$
icons.put("pri_shield7", R.drawable.pri_shield7); //$NON-NLS-1$
icons.put("pri_shield8", R.drawable.pri_shield8); //$NON-NLS-1$
icons.put("sec_shield1", R.drawable.sec_shield1); //$NON-NLS-1$
icons.put("sec_shield2", R.drawable.sec_shield2); //$NON-NLS-1$
icons.put("sec_shield3", R.drawable.sec_shield3); //$NON-NLS-1$
icons.put("sec_shield4", R.drawable.sec_shield4); //$NON-NLS-1$
icons.put("sec_shield5", R.drawable.sec_shield5); //$NON-NLS-1$
icons.put("sec_shield6", R.drawable.sec_shield6); //$NON-NLS-1$
icons.put("sec_shield7", R.drawable.sec_shield7); //$NON-NLS-1$
icons.put("sec_shield8", R.drawable.sec_shield8); //$NON-NLS-1$
icons.put("ter_shield1", R.drawable.ter_shield1); //$NON-NLS-1$
icons.put("ter_shield2", R.drawable.ter_shield2); //$NON-NLS-1$
icons.put("ter_shield3", R.drawable.ter_shield3); //$NON-NLS-1$
icons.put("ter_shield4", R.drawable.ter_shield4); //$NON-NLS-1$
icons.put("ter_shield5", R.drawable.ter_shield5); //$NON-NLS-1$
icons.put("ter_shield6", R.drawable.ter_shield6); //$NON-NLS-1$
icons.put("ter_shield7", R.drawable.ter_shield7); //$NON-NLS-1$
icons.put("ter_shield8", R.drawable.ter_shield8); //$NON-NLS-1$
icons.put("tru_shield1", R.drawable.tru_shield1); //$NON-NLS-1$
icons.put("tru_shield2", R.drawable.tru_shield2); //$NON-NLS-1$
icons.put("tru_shield3", R.drawable.tru_shield3); //$NON-NLS-1$
icons.put("tru_shield4", R.drawable.tru_shield4); //$NON-NLS-1$
icons.put("tru_shield5", R.drawable.tru_shield5); //$NON-NLS-1$
icons.put("tru_shield6", R.drawable.tru_shield6); //$NON-NLS-1$
icons.put("tru_shield7", R.drawable.tru_shield7); //$NON-NLS-1$
icons.put("tru_shield8", R.drawable.tru_shield8); //$NON-NLS-1$
}
public static void initIcons() {
Class<? extends drawable> cl = R.drawable.class;
for (Field f : cl.getDeclaredFields()) {
if (f.getName().startsWith("h_") || f.getName().startsWith("g_")) {
try {
icons.put(f.getName().substring(2), f.getInt(null));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}

14
config/basemap/README Normal file
View file

@ -0,0 +1,14 @@
1. Find and install perl Geo-ShapeFile-2.52
cd Geo-ShapeFile-2.52/
sudo perl Makefile.PL
make
make test
2. Locate and run shp2osm.pl.
Example (replacing tags): perl ./shp2osm.pl 10m-coastline/10m_coastline.shp | sed 's/FeatureCla/natural/g;s/Coastline/coastline/g' > 10m_coastline.osm
3. Fix manually all 180 degrees breaks (simply divide islands into 2 islands and add connect line on 180 degree) and make Antarctica cycled.
4. Run net.osmand.osm.util.FixLinkedCoastline from DataExtractionosm.jar with arg0=filename.
5. !Fix manually Caspey Sea !
6. ! Check 2 ShriLanka islands (2 coastlines on one place)
6. ! Check North America for bug!
7. Run Index Creator.

167
config/basemap/shp2osm.pl Executable file
View file

@ -0,0 +1,167 @@
# Copyright (c) 2006 Gabriel Ebner <ge@gabrielebner.at>
# updated in 2008 by Tobias Wendorff <tobias.wendorff@uni-dortmund.de>
# HTML-Entities based on ideas of Hermann Schwärzler
# Gauß-Krüger implementation based on gauss.pl by Andreas Achtzehn
# version 1.3 (17. September 2008)
use Geo::ShapeFile;
use HTML::Entities qw(encode_entities_numeric);
use Math::Trig;
if(@ARGV == 0) {
print "usage:\n";
print "with transformation from GK to WGS84: 'shp2osm.pl shapefile GK'\n";
print "without transformation: 'shp2osm.pl shapefile'";
exit;
}
print <<'END';
<?xml version='1.0'?>
<osm version='0.5' generator='shp2osm.pl'>
END
#BEGIN { our %default_tags = ( natural => 'water', source => 'SWDB' ); }
BEGIN { our %default_tags = ( ); }
my $file = @ARGV[0];
$file =~ s/\.shp$//;
my $shpf = Geo::ShapeFile->new($file);
proc_shpf($shpf);
{
BEGIN { our $i = -1; }
sub tags_out {
my ($tags) = @_;
my %tags = $tags ? %$tags : ();
#$tags{'created_by'} ||= 'shp2osm.pl';
delete $tags{'_deleted'} unless $tags{'_deleted'};
while ( my ( $k, $v ) = each %tags ) {
my $key = encode_entities_numeric($k);
my $val = encode_entities_numeric($v);
print ' <tag k="'. $key .'" v="'. $val ."\"/>\n" if $val;
}
}
sub node_out {
my ( $lon, $lat, $tags ) = @_;
my $id = $i--;
if(@ARGV[1] eq 'GK') {
my ($wgs84lon, $wgs84lat) = gk2geo($lon, $lat);
print " <node id='$id' visible='true' lat='$wgs84lat' lon='$wgs84lon' />\n";
} else {
print " <node id='$id' visible='true' lat='$lat' lon='$lon' />\n";
}
$id;
}
sub seg_out {
my $id = $i+1;
$id;
}
sub way_out {
my ( $segs, $tags ) = @_;
my $id = $i--;
print " <way id='$id' visible='true'>\n";
print " <nd ref='$_' />\n" for @$segs;
tags_out $tags;
print " </way>\n";
$id;
}
}
print <<'END';
</osm>
END
sub polyline_out {
my ( $pts, $tags, $connect_last_seg ) = @_;
my ( $first_node, $last_node, @segs );
for my $pt (@$pts) {
my $node = node_out @$pt;
push @segs, seg_out $last_node, $node;
$last_node = $node;
$first_node ||= $last_node;
}
push @segs, seg_out $last_node, $first_node
if $first_node && $connect_last_seg;
way_out \@segs, $tags;
}
sub proc_obj {
my ( $shp, $dbf, $type ) = @_;
my $tags = { %default_tags, %$dbf };
my $is_polygon = $type % 10 == 5;
for ( 1 .. $shp->num_parts ) {
polyline_out [ map( [ $_->X(), $_->Y() ], $shp->get_part($_) ) ], $tags,
$is_polygon;
}
}
sub proc_shpf {
my ($shpf) = @_;
my $type = $shpf->shape_type;
for ( 1 .. $shpf->shapes() ) {
my $shp = $shpf->get_shp_record($_);
my %dbf = $shpf->get_dbf_record($_);
proc_obj $shp, \%dbf, $type;
}
}
sub gk2geo {
my $sr = $_[0];
my $sx = $_[1];
my $bm = int($sr/1000000);
my $y = $sr-($bm*1000000+500000);
my $si = $sx/111120.6196;
my $px = $si+0.143885358*sin(2*$si*0.017453292)+0.00021079*sin(4*$si*0.017453292)+0.000000423*sin(6*$si*0.017453292);
my $t = (sin($px*0.017453292))/(cos($px*0.017453292));
my $v = sqrt(1+0.006719219*cos($px*0.017453292)*cos($px*0.017453292));
my $ys = ($y*$v)/6398786.85;
my $lat = $px-$ys*$ys*57.29577*$t*$v*$v*(0.5-$ys*$ys*(4.97-3*$t*$t)/24);
my $dl = $ys*57.29577/cos($px*0.017453292) * (1-$ys*$ys/6*($v*$v+2*$t*$t-$ys*$ys*(0.6+1.1*$t*$t)*(0.6+1.1*$t*$t)));
my $lon = $bm*3+$dl;
my $potsd_a = 6377397.155;
my $wgs84_a = 6378137.0;
my $potsd_f = 1/299.152812838;
my $wgs84_f = 1/298.257223563;
my $potsd_es = 2*$potsd_f - $potsd_f*$potsd_f;
my $potsd_dx = 606.0;
my $potsd_dy = 23.0;
my $potsd_dz = 413.0;
my $pi = 3.141592654;
my $latr = $lat/180*$pi;
my $lonr = $lon/180*$pi;
my $sa = sin($latr);
my $ca = cos($latr);
my $so = sin($lonr);
my $co = cos($lonr);
my $bda = 1-$potsd_f;
my $delta_a = $wgs84_a - $potsd_a;
my $delta_f = $wgs84_f - $potsd_f;
my $rn = $potsd_a / sqrt(1-$potsd_es*sin($latr)*sin($latr));
my $rm = $potsd_a * ((1-$potsd_es)/sqrt(1-$potsd_es*sin($latr)*sin($latr)*1-$potsd_es*sin($latr)*sin($latr)*1-$potsd_es*sin($latr)*sin($latr)));
my $ta = (-$potsd_dx*$sa*$co - $potsd_dy*$sa*$so)+$potsd_dz*$ca;
my $tb = $delta_a*(($rn*$potsd_es*$sa*$ca)/$potsd_a);
my $tc = $delta_f*($rm/$bda+$rn*$bda)*$sa*$ca;
my $dlat = ($ta+$tb+$tc)/$rm;
my $dlon = (-$potsd_dx*$so + $potsd_dy*$co)/($rn*$ca);
my $wgs84lat = ($latr + $dlat)*180/$pi;
my $wgs84lon = ($lonr + $dlon)*180/$pi;
return( $wgs84lon, $wgs84lat);
}