package net.osmand.osm; import gnu.trove.map.TIntByteMap; import gnu.trove.map.hash.TIntByteHashMap; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import net.osmand.data.AmenityType; import net.osmand.osm.OSMSettings.OSMTagKey; import net.osmand.LogUtil; import org.apache.commons.logging.Log; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * SOURCE : http://wiki.openstreetmap.org/wiki/Map_Features * * Describing types of polygons : * 1. Last 2 bits define type of element : polygon, polyline, point */ public class MapRenderingTypes { private static final Log log = LogUtil.getLog(MapRenderingTypes.class); // TODO Internet access bits for point, polygon /** standard schema : polygon : ll aaaaa ttttt 11 : 14 bits multi : ll aaaaa ttttt 00 : 14 bits t - object type, a - area subtype,l - layer polyline : ll ppppp ttttt 10 : 14 bits t - object type, p - polyline object type, l - layer point : ssss ssss ttttt 10 : 15 bits t - object type, s - subtype */ public final static int MULTY_POLYGON_TYPE = 0; public final static int POLYGON_TYPE = 3; public final static int POLYLINE_TYPE = 2; public final static int POINT_TYPE = 1; public final static int PG_SUBTYPE_MASK_LEN = 5; public final static int PG_SUBTYPE_MASK = (1 << PG_SUBTYPE_MASK_LEN) -1; public final static int PO_SUBTYPE_MASK_LEN = 8; public final static int PO_SUBTYPE_MASK = (1 << PO_SUBTYPE_MASK_LEN) -1; public final static int PL_SUBTYPE_MASK_LEN = 5; public final static int PL_SUBTYPE_MASK = (1 << PL_SUBTYPE_MASK_LEN) -1; // TYPES : public final static int OBJ_TYPE_MASK_LEN = 5; public final static int OBJ_TYPE_MASK = (1 << OBJ_TYPE_MASK_LEN) -1; public final static int MASK_13 = (1 << 13) - 1; public final static int MASK_12 = (1 << 12) - 1; public final static int MASK_4 = (1 << 4) - 1; public final static int MASK_5 = (1 << 5) - 1; public final static int MASK_10 = (1 << 10) - 1; public final static char REF_CHAR = ((char)0x0019); public final static char DELIM_CHAR = ((char)0x0018); public final static byte RESTRICTION_NO_RIGHT_TURN = 1; public final static byte RESTRICTION_NO_LEFT_TURN = 2; public final static byte RESTRICTION_NO_U_TURN = 3; public final static byte RESTRICTION_NO_STRAIGHT_ON = 4; public final static byte RESTRICTION_ONLY_RIGHT_TURN = 5; public final static byte RESTRICTION_ONLY_LEFT_TURN = 6; public final static byte RESTRICTION_ONLY_STRAIGHT_ON = 7; // two bytes pass! public static int getMainObjectType(int type){ return (type >> 2) & OBJ_TYPE_MASK; } // two bytes pass! public static int getObjectSubType(int type){ if((type & 3) == 1){ return (type >> 7) & PO_SUBTYPE_MASK; } else { return (type >> 7) & PG_SUBTYPE_MASK; } } private String resourceName = null; // stored information to convert from osm tags to int type private Map<String, MapRulType> types = null; private TIntByteMap objectsToMinZoom = null; private static Map<String, AmenityType> amenityTagValToType = null; private static Map<String, String> amenityTagValToPrefix = null; private static String TAG_DELIMETER = "&&"; //$NON-NLS-1$ private Map<AmenityType, Map<String, String>> amenityTypeNameToTagVal = null; private Map<String, AmenityType> amenityNameToType = null; public MapRenderingTypes(String fileName){ this.resourceName = fileName; } private static MapRenderingTypes DEFAULT_INSTANCE = null; public static MapRenderingTypes getDefault() { if(DEFAULT_INSTANCE == null){ DEFAULT_INSTANCE = new MapRenderingTypes(null); } return DEFAULT_INSTANCE; } private final static int POLYGON_WITH_CENTER_TYPE = 9; // special type means that ways will transform in area with the same point subtype = as area subtype // instead of zero point subtype (only for ways!) private final static int DEFAULT_POLYGON_BUILDING = 10; public static class MapRulType { private String tag; // val could be null means others for that tag private Integer nullRule; private Map<String, Integer> rules = new LinkedHashMap<String, Integer>(); private String nameNullTag; public MapRulType(String tag, String nameNullTag){ this.tag = tag; } public String getTag() { return tag; } public String getNameNullTag() { return nameNullTag; } public Collection<String> getValuesSet(){ return rules.keySet(); } public void registerType(int minZoom, String val, int pointRule, int polylineRule, int polygonRule, int type, int subtype){ int r = encodeRule(minZoom, pointRule, polylineRule, polygonRule, type, subtype); if(val != null){ rules.put(val, r); } else { nullRule = r; } } public boolean registered(String val){ return rules.containsKey(val); } public boolean registeredAsNull(){ return nullRule != null && nullRule > 0; } private int encodeRule(int minZoom, int pointRule, int polylineRule, int polygonRule, int type, int subtype){ int rule = (((((minZoom << 4) | polygonRule) << 4) | polylineRule) << 4) | pointRule; // 17 bit rule = (((rule << 8) | subtype) << 5) | type; // + 13 bits return rule; } public int getPointRule(String val){ Integer i = val == null ? nullRule : rules.get(val); if(i == null){ return 0; } return (i >> 13) & MASK_4; } public int getPolylineRule(String val){ Integer i = val == null ? nullRule : rules.get(val); if(i == null){ return 0; } return (i >> 17) & MASK_4; } public int getPolygonRule(String val){ Integer i = val == null ? nullRule : rules.get(val); if(i == null){ return 0; } return (i >> 21) & MASK_4; } public int getMinZoom(String val){ Integer i = val == null ? nullRule : rules.get(val); if(i == null){ return 0; } return (i >> 25); } public int getType(String val) { Integer i = val == null ? nullRule : rules.get(val); if (i == null) { return 0; } return i & MASK_5; } public int getSubType(String val) { Integer i = val == null ? nullRule : rules.get(val); if (i == null) { return 0; } return (i & MASK_13) >> 5; } public int getType(String val, int mask){ Integer i = val == null ? nullRule : rules.get(val); if(i == null){ return 0; } return i & mask; } } public Map<String, MapRulType> getEncodingRuleTypes(){ if (types == null) { types = new LinkedHashMap<String, MapRulType>(); init(INIT_RULE_TYPES); } return types; } // if type equals 0 no need to save that point public int encodeEntityWithType(Entity e, int zoom, boolean multipolygon, List<Integer> additionalTypes) { if (types == null) { types = new LinkedHashMap<String, MapRulType>(); init(INIT_RULE_TYPES); } additionalTypes.clear(); if("coastline".equals(e.getTag(OSMTagKey.NATURAL))){ //$NON-NLS-1$ multipolygon = true; } boolean point = e instanceof Node; boolean polygon = multipolygon; if (!point && !polygon) { // determining area or path boolean area = "yes".equals(e.getTag("area")); //$NON-NLS-1$ //$NON-NLS-2$ boolean highway = e.getTag("highway") != null; //$NON-NLS-1$ if(highway && !area){ // skip the check for first and last point } else { List<Long> ids = ((Way) e).getNodeIds(); if (ids.size() > 1) { polygon = ((long) ids.get(0) == (long) ids.get(ids.size() - 1)); } } } Collection<String> tagKeySet = e.getTagKeySet(); // 1. sort tags : important tags (type) will be rendered first if(tagKeySet.size() > 1 && tagKeySet.contains("building")){ //$NON-NLS-1$ // first of all process building tag (in order to distinguish area and buildings) LinkedHashSet<String> set = new LinkedHashSet<String>(); set.add("building"); //$NON-NLS-1$ set.addAll(tagKeySet); tagKeySet = set; } int pointType = 0; int polylineType = 0; int polygonType = 0; // 2. 2 iterations first for exact tag=value match, second for any tag match for (int i = 0; i < 2; i++) { if (i == 1 && !additionalTypes.isEmpty()) { break; } for (String tag : tagKeySet) { if (types.containsKey(tag)) { MapRulType rType = types.get(tag); String val = i == 1 ? null : e.getTag(tag); if(rType.getMinZoom(val) > zoom){ continue; } int pr = point ? rType.getPointRule(val) : (polygon ? rType.getPolygonRule(val) : rType.getPolylineRule(val)); int typeVal = rType.getType(val, MASK_13) << 2; if (pr == POINT_TYPE && pointType == 0) { pointType = POINT_TYPE | typeVal; additionalTypes.add(pointType); } else if (!point && pr == POLYLINE_TYPE) { int attr = getLayerAttributes(e) << 12; boolean prevPoint = (polylineType == 0 && polygonType == 0); polylineType = POLYLINE_TYPE | (typeVal & MASK_12) | attr; if (tag.equals("highway") || prevPoint){ //$NON-NLS-1$ additionalTypes.add(0, polylineType); } else { additionalTypes.add(polylineType); } } else if (polygon && (pr == POLYGON_WITH_CENTER_TYPE || pr == POLYGON_TYPE)) { boolean prevPoint = (polylineType == 0 && polygonType == 0); int attr = getLayerAttributes(e) << 12; polygonType = (multipolygon ? MULTY_POLYGON_TYPE : POLYGON_TYPE) | (typeVal & MASK_12) | attr; if (prevPoint){ additionalTypes.add(0, polygonType); } else { additionalTypes.add(polygonType); } if (pr == POLYGON_WITH_CENTER_TYPE) { pointType = POINT_TYPE | typeVal; additionalTypes.add(pointType); } } else if (polygon && (pr == DEFAULT_POLYGON_BUILDING)) { // TODO get polygon type int MAN_MADE = 8; int SUBTYPE_BUILDING = 1; if(polygonType == 0 && polylineType == 0){ int attr = getLayerAttributes(e) << 12; polygonType = (multipolygon ? MULTY_POLYGON_TYPE : POLYGON_TYPE) | (((SUBTYPE_BUILDING << 5) | MAN_MADE) << 2) | attr; additionalTypes.add(0, polygonType); } pointType = POINT_TYPE | typeVal; additionalTypes.add(pointType); } } } } int type = 0; if(!additionalTypes.isEmpty()){ type = additionalTypes.get(0); additionalTypes.remove(0); } return type; } public static boolean isOneWayWay(int highwayAttributes){ return (highwayAttributes & 1) > 0; } public static boolean isRoundabout(int highwayAttributes){ return ((highwayAttributes >> 2) & 1) > 0; } // 0 - normal, 1 - under, 2 - bridge,over public static int getWayLayer(int type){ return (3 & (type >> 12)); } // 0 - normal, -1 - under, 1 - bridge,over public static int getNegativeWayLayer(int type) { int i = (3 & (type >> 12)); if (i == 1) { return -1; } else if (i == 2) { return 1; } return 0; } // return 0 if not defined public static int getMaxSpeedIfDefined(int highwayAttributes){ switch((highwayAttributes >> 4) & 7) { case 0: return 20; case 1: return 40; case 2: // for old format it should return 0; // TODO it should be uncommented because now it is fixed // return 60; return 0; case 3: return 80; case 4: return 100; case 5: return 120; case 6: return 140; case 7: return 0; } return 0; } // HIGHWAY special attributes : // o/oneway 1 bit // f/free toll 1 bit // r/roundabout 2 bit (+ 1 bit direction) // s/max speed 3 bit [0 - 30km/h, 1 - 50km/h, 2 - 70km/h, 3 - 90km/h, 4 - 110km/h, 5 - 130 km/h, 6 >, 7 - 0/not specified] // a/vehicle access 4 bit (height, weight?) - one bit bicycle // p/parking 1 bit // c/cycle oneway 1 bit // TODO // ci/inside city 1 bit // ENCODING : ci|c|p|aaaa|sss|rr|f|o - 14 bit public static int getHighwayAttributes(Entity e){ int attr = 0; // cycle oneway attr <<= 1; String c = e.getTag("cycleway"); //$NON-NLS-1$ if(c != null && ("opposite_lane".equals(c) || "opposite_track".equals(c) || "opposite".equals(c))){ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ attr |= 1; } // parking attr <<= 1; String park = e.getTag("service"); //$NON-NLS-1$ if("parking_aisle".equals(park)){ //$NON-NLS-1$ attr |= 1; } // ACCESS not complete (should be redesigned) // vehicle access (not implement yet) attr <<= 3; boolean hgv = "yes".equals(e.getTag("hgv")); //$NON-NLS-1$ //$NON-NLS-2$ if(hgv){ attr |= 3; } else { boolean goods = "yes".equals(e.getTag("goods")); //$NON-NLS-1$ //$NON-NLS-2$ if(goods){ attr |= 2; } else { attr |= 1; } } // bicycle access attr <<= 1; // speed // very simple algorithm doesn't consider city rules (country rules) and miles per hour attr <<= 3; String maxspeed = e.getTag("maxspeed"); //$NON-NLS-1$ if(maxspeed != null){ int kmh = 0; try { kmh = Integer.parseInt(maxspeed); } catch (NumberFormatException es) { } if(kmh <= 0){ attr |= 7; } else if(kmh <= 30){ attr |= 0; } else if(kmh <= 50){ attr |= 1; } else if(kmh <= 70){ attr |= 2; } else if(kmh <= 90){ attr |= 3; } else if(kmh <= 110){ attr |= 4; } else if(kmh <= 130){ attr |= 5; } else { attr |= 6; } } else { attr |= 7; } // roundabout attr <<= 2; String jun = e.getTag(OSMTagKey.JUNCTION); if(jun != null){ if("roundabout".equals(jun)){ //$NON-NLS-1$ attr |= 1; if("clockwise".equals(e.getTag("direction"))){ //$NON-NLS-1$ //$NON-NLS-2$ attr |= 2; } } } // toll String toll = e.getTag(OSMTagKey.TOLL); attr <<= 1; if(toll != null){ if("yes".equals(toll)){ //$NON-NLS-1$ attr |= 1; } } // oneway String one = e.getTag(OSMTagKey.ONEWAY); attr <<= 1; if(one != null && (one.equals("yes") || one.equals("1") || one.equals("-1"))){ //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ attr |= 1; } return attr; } private static int getLayerAttributes(Entity e){ // layer String l = e.getTag(OSMTagKey.LAYER); if(l != null){ if(l.startsWith("+")){ //$NON-NLS-1$ l = l.substring(1); } int la = 0; try { la = Integer.parseInt(l); } catch (NumberFormatException es) { } if(la < 0){ return 1; } else if(la > 0){ return 2; } } else if(e.getTag(OSMTagKey.BRIDGE) != null){ return 2; } else if(e.getTag(OSMTagKey.TUNNEL) != null){ return 1; } return 0; } public static boolean isLayerUnder(int attr){ return (attr & 3) == 1; } public String getEntityName(Entity e) { if (e.getTag(OSMTagKey.REF) != null && e.getTag(OSMTagKey.HIGHWAY) != null) { String ref = e.getTag(OSMTagKey.REF); if (ref.length() > 5 && ref.indexOf('_') != -1) { ref = ref.substring(0, ref.indexOf('_')); } String name = e.getTag(OSMTagKey.NAME); if(name != null && !name.equals(ref)){ return REF_CHAR + ref + REF_CHAR + name; } else { return REF_CHAR + ref; } } String name = e.getTag(OSMTagKey.NAME); if (name == null) { name = e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER); } if (name == null) { Collection<String> tagKeySet = e.getTagKeySet(); Map<String, MapRulType> types = getEncodingRuleTypes(); for (int i = 0; i < 2 && name == null; i++) { for (String tag : tagKeySet) { if (types.containsKey(tag)) { MapRulType rType = types.get(tag); if (rType.getNameNullTag() != null) { name = e.getTag(rType.getNameNullTag()); if (name != null) { break; } } } } } } return name; } private void initAmenityMap(){ if (amenityTypeNameToTagVal == null) { amenityTypeNameToTagVal = new LinkedHashMap<AmenityType, Map<String, String>>(); init(INIT_AMENITY_MAP); } } /** * * @return <type, minzoom> map * only when minzoom < 15 */ public TIntByteMap getObjectTypeMinZoom(){ if(objectsToMinZoom == null){ objectsToMinZoom = new TIntByteHashMap(); init(INIT_TYPE_ZOOM); } return objectsToMinZoom; } public Map<AmenityType, Map<String, String>> getAmenityTypeNameToTagVal() { initAmenityMap(); return amenityTypeNameToTagVal; } public Map<String, AmenityType> getAmenityNameToType(){ initAmenityMap(); if(amenityNameToType == null){ amenityNameToType = new LinkedHashMap<String, AmenityType>(); for(AmenityType s : amenityTypeNameToTagVal.keySet()){ Map<String, String> map = amenityTypeNameToTagVal.get(s); for(String t : map.keySet()){ // if(amenityNameToType.containsKey(t)){ // System.err.println("Conflict " + t + " " + amenityNameToType.get(t) + " <> " + s); // } amenityNameToType.put(t, s); } } } return amenityNameToType; } private void registerAmenity(String tag, String val, int type, int subtype){ AmenityType t = getAmenityType(tag, val); if (t != null) { if (val != null) { if (!amenityTypeNameToTagVal.containsKey(t)) { amenityTypeNameToTagVal.put(t, new LinkedHashMap<String, String>()); } String name = val; String prefix = getAmenitySubtypePrefix(tag, val); if (prefix != null) { name = prefix + name; } Map<String, String> map = amenityTypeNameToTagVal.get(t); if (map.containsKey(val)) { if (type == 17 && subtype == 23) { // natural wood } else if (type == 2 && subtype == 21) { // barrier gate } else { // debug purpose // System.err.println("Duplicate entry " + tag + " " + val + " for " + t); } } else { if (prefix != null) { map.put(name, tag + " " + val); //$NON-NLS-1$ } else { map.put(name, tag); } } } }else { // debug purpose // System.out.println("NOT ACCEPTED " + tag + " " + val); } } private final static int INIT_RULE_TYPES = 0; private final static int INIT_AMENITY_MAP = 1; private final static int INIT_TYPE_ZOOM = 2; private void init(final int st){ InputStream is; try { if(resourceName == null){ is = MapRenderingTypes.class.getResourceAsStream("rendering_types.xml"); //$NON-NLS-1$ } else { is = new FileInputStream(resourceName); } long time = System.currentTimeMillis(); final SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(is, new DefaultHandler(){ int currentType = 1; @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { name = parser.isNamespaceAware() ? localName : name; if(name.equals("type")){ //$NON-NLS-1$ currentType = Integer.parseInt(attributes.getValue("id")); //$NON-NLS-1$ } else if (name.equals("subtype")) { //$NON-NLS-1$ String val = attributes.getValue("minzoom"); //$NON-NLS-1$ int maxzoom = 15; if (val != null) { maxzoom = Integer.parseInt(val); } String nameNullTag = attributes.getValue("nameNullTag"); //$NON-NLS-1$ String tag = attributes.getValue("tag"); //$NON-NLS-1$ val = attributes.getValue("value"); //$NON-NLS-1$ if (val != null && (val.equalsIgnoreCase("null") || val.length() == 0)) { //$NON-NLS-1$ val = null; } int subtype = Integer.parseInt(attributes.getValue("id")); //$NON-NLS-1$ boolean building = Boolean.parseBoolean(attributes.getValue("building")); //$NON-NLS-1$ boolean polygon = Boolean.parseBoolean(attributes.getValue("polygon")); //$NON-NLS-1$ boolean polyline = Boolean.parseBoolean(attributes.getValue("polyline")); //$NON-NLS-1$ boolean point = Boolean.parseBoolean(attributes.getValue("point")); //$NON-NLS-1$ boolean polygon_center = Boolean.parseBoolean(attributes.getValue("polygon_center")); //$NON-NLS-1$ int polygonRule = 0; int pointRule = 0; int polylineRule = 0; if(building || point || polygon_center){ pointRule = POINT_TYPE; } if(!polyline && polygon) { pointRule = POINT_TYPE; } if(polyline){ polylineRule = POLYLINE_TYPE; } else if(point){ polylineRule = POINT_TYPE; } if(building){ polygonRule = DEFAULT_POLYGON_BUILDING; } else if(polygon_center){ polygonRule = POLYGON_WITH_CENTER_TYPE; } else if(polygon){ polygonRule = POLYGON_TYPE; }else if(polyline){ polygonRule = POLYLINE_TYPE; } else if(point){ polygonRule = POINT_TYPE; } stepSubtype(st, maxzoom, tag, val, currentType, subtype, polygonRule, polylineRule, pointRule, nameNullTag); } } }); log.info("Time to init " + (System.currentTimeMillis() - time)); //$NON-NLS-1$ is.close(); } catch (IOException e) { log.error("Unexpected error", e); //$NON-NLS-1$ e.printStackTrace(); throw new RuntimeException(e); } catch (RuntimeException e) { log.error("Unexpected error", e); //$NON-NLS-1$ e.printStackTrace(); throw e; } catch (ParserConfigurationException e) { log.error("Unexpected error", e); //$NON-NLS-1$ e.printStackTrace(); throw new RuntimeException(e); } catch (SAXException e) { log.error("Unexpected error", e); //$NON-NLS-1$ e.printStackTrace(); throw new RuntimeException(e); } } private void stepSubtype(int st, int minZoom, String tag, String val, int type, int subtype, int polygonRule, int polylineRule, int pointRule, String nameNullTag) { if(st == INIT_RULE_TYPES){ MapRulType rtype = types.get(tag); if(rtype == null){ rtype = new MapRulType(tag, nameNullTag); types.put(tag, rtype); } rtype.registerType(minZoom, val, pointRule, polylineRule, polygonRule, type, subtype); } else if(st == INIT_AMENITY_MAP){ if(pointRule == POINT_TYPE || polygonRule == POLYGON_WITH_CENTER_TYPE || polygonRule == POLYGON_TYPE){ registerAmenity(tag, val, type, subtype); } } else if(st == INIT_TYPE_ZOOM){ if(minZoom < 15){ int value = (((subtype) << 5) | type) << 2; if(!objectsToMinZoom.containsKey(value)){ // add only first objectsToMinZoom.put(value, (byte) minZoom); } } } } public static String getAmenitySubtype(String tag, String val){ String prefix = getAmenitySubtypePrefix(tag, val); if(prefix != null){ return prefix + val; } return val; } public static String getAmenitySubtypePrefix(String tag, String val){ if(amenityTagValToPrefix == null){ amenityTagValToPrefix = new LinkedHashMap<String, String>(); amenityTagValToPrefix.put("traffic_calming", "traffic_calming_"); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToPrefix.put("power", "power_"); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToPrefix.put("waterway", "water_"); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToPrefix.put("waterway"+TAG_DELIMETER+"riverbank", null); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToPrefix.put("railway", "railway_"); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToPrefix.put("railway"+TAG_DELIMETER+"subway_entrance", null); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToPrefix.put("aeroway", "aeroway_"); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToPrefix.put("aerialway", "aerialway_"); //$NON-NLS-1$ //$NON-NLS-2$ } if(val != null && amenityTagValToPrefix.containsKey(tag+TAG_DELIMETER+val)){ return amenityTagValToPrefix.get(tag+TAG_DELIMETER+val); } return amenityTagValToPrefix.get(tag); } public static AmenityType getAmenityType(String tag, String val){ // register amenity types if(amenityTagValToType == null){ initAmenityTagValToType(); } if(amenityTagValToType.containsKey(tag+TAG_DELIMETER+val)){ return amenityTagValToType.get(tag+TAG_DELIMETER+val); } return amenityTagValToType.get(tag); } private static void initAmenityTagValToType() { amenityTagValToType = new LinkedHashMap<String, AmenityType>(); amenityTagValToType.put("highway"+TAG_DELIMETER+"bus_stop", AmenityType.TRANSPORTATION); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("highway"+TAG_DELIMETER+"platform", AmenityType.TRANSPORTATION); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("highway"+TAG_DELIMETER+"turning_circle", AmenityType.TRANSPORTATION); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("highway"+TAG_DELIMETER+"emergency_access_point", AmenityType.TRANSPORTATION); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("highway"+TAG_DELIMETER+"speed_camera", AmenityType.TRANSPORTATION); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("traffic_calming", AmenityType.BARRIER); //$NON-NLS-1$ amenityTagValToType.put("barrier", AmenityType.BARRIER); //$NON-NLS-1$ amenityTagValToType.put("natural"+TAG_DELIMETER+"hedge", AmenityType.BARRIER); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("historic"+TAG_DELIMETER+"city_walls", AmenityType.BARRIER); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("highway"+TAG_DELIMETER+"gate", AmenityType.BARRIER); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("waterway"+TAG_DELIMETER+"stream", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("waterway"+TAG_DELIMETER+"riverbank", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("waterway"+TAG_DELIMETER+"river", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("waterway"+TAG_DELIMETER+"canal", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("waterway"+TAG_DELIMETER+"ditch", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("waterway"+TAG_DELIMETER+"drain", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("waterway", AmenityType.MAN_MADE); //$NON-NLS-1$ amenityTagValToType.put("railway", AmenityType.TRANSPORTATION); //$NON-NLS-1$ amenityTagValToType.put("aeroway", AmenityType.TRANSPORTATION); //$NON-NLS-1$ amenityTagValToType.put("aerialway", AmenityType.TRANSPORTATION); //$NON-NLS-1$ amenityTagValToType.put("aerialway"+TAG_DELIMETER+"pylon", null); //$NON-NLS-1$//$NON-NLS-2$ // do not add power tower to index amenityTagValToType.put("power"+TAG_DELIMETER+"station", AmenityType.MAN_MADE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("power"+TAG_DELIMETER+"sub_station", AmenityType.MAN_MADE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("power"+TAG_DELIMETER+"generator", AmenityType.MAN_MADE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("power"+TAG_DELIMETER+"cable_distribution_cabinet", AmenityType.MAN_MADE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("building", null); //$NON-NLS-1$ amenityTagValToType.put("man_made"+TAG_DELIMETER+"wastewater_plant", null); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("man_made"+TAG_DELIMETER+"water_works", null); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("man_made"+TAG_DELIMETER+"works", null); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("man_made", AmenityType.MAN_MADE); //$NON-NLS-1$ amenityTagValToType.put("leisure", AmenityType.LEISURE); //$NON-NLS-1$ amenityTagValToType.put("natural"+TAG_DELIMETER+"park", AmenityType.LEISURE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("office", AmenityType.OFFICE); //$NON-NLS-1$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"architect_office", AmenityType.OFFICE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("shop", AmenityType.SHOP); //$NON-NLS-1$ amenityTagValToType.put("emergency", AmenityType.EMERGENCY); //$NON-NLS-1$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"fire_station", AmenityType.EMERGENCY); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("tourism", AmenityType.TOURISM); //$NON-NLS-1$ amenityTagValToType.put("historic", AmenityType.HISTORIC); //$NON-NLS-1$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"basin", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"grave_yard", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"cemetery", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"forest", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"meadow", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"military", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"orchard", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"recreation_ground", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"conservation", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"village_green", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"reservoir", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"water", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"salt_pond", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"quarry", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"vineyard", AmenityType.LANDUSE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("landuse"+TAG_DELIMETER+"wood", AmenityType.NATURAL); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("military", AmenityType.MILITARY); //$NON-NLS-1$ amenityTagValToType.put("natural", AmenityType.NATURAL); //$NON-NLS-1$ amenityTagValToType.put("natural"+TAG_DELIMETER+"field", null); //$NON-NLS-1$ //$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"restaurant", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"cafe", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"food_court", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"fast_food", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"pub", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bar", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"biergarten", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"drinking_water", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bbq", AmenityType.SUSTENANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"kindergarten", AmenityType.EDUCATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"school", AmenityType.EDUCATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"college", AmenityType.EDUCATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"library", AmenityType.EDUCATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"university", AmenityType.EDUCATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"kindergarten", AmenityType.EDUCATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"parking", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bicycle_parking", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"ferry_terminal", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"fuel", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"taxi", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bicycle_rental", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bus_station", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"car_rental", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"car_sharing", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"car_wash", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"grit_bin", AmenityType.TRANSPORTATION); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"atm", AmenityType.FINANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bank", AmenityType.FINANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"bureau_de_change", AmenityType.FINANCE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"pharmacy", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"hospital", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"baby_hatch", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"dentist", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"doctors", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"veterinary", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"first_aid", AmenityType.HEALTHCARE); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"arts_centre", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"cinema", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"community_centre", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"social_centre", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"nightclub", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"stripclub", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"studio", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"theatre", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"sauna", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("amenity"+TAG_DELIMETER+"brothel", AmenityType.ENTERTAINMENT); //$NON-NLS-1$//$NON-NLS-2$ amenityTagValToType.put("geocache", AmenityType.GEOCACHE); //$NON-NLS-1$ amenityTagValToType.put("amenity", AmenityType.OTHER); //$NON-NLS-1$ amenityTagValToType.put("place", AmenityType.ADMINISTRATIVE); //$NON-NLS-1$ amenityTagValToType.put("sport", AmenityType.SPORT); //$NON-NLS-1$ } public static void main(String[] args) { // Map<String, Map<String, AmenityType>> amenityMap = getAmenityTagValToTypeMap(); // for(String s : amenityMap.keySet()){ // System.out.println(s + " - " + amenityMap.get(s)); // } // Map<AmenityType, Map<String, String>> amenityType = getAmenityTypeNameToTagVal(); // for(AmenityType s : amenityType.keySet()){ // Map<String, String> map = amenityType.get(s); // for(String t : map.keySet()){ // System.out.println(s + " - " + t + " " + map.get(t)); // } // } // System.out.println(getAmenityNameToType()); // long ts = System.currentTimeMillis(); System.out.println(MapUtils.getTileNumberX(13, 23.95)+ " " + MapUtils.getTileNumberY(13, 52.136)); MapRenderingTypes def = MapRenderingTypes.getDefault(); def.initAmenityMap(); System.out.println(def.amenityTypeNameToTagVal); System.out.println(def.getAmenityNameToType()); } }