From ab9f6a46bd8f145b24ef468c70fb5ad2b090d118 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sun, 21 Nov 2010 14:08:30 +0000 Subject: [PATCH] implement basic xml renderer git-svn-id: https://osmand.googlecode.com/svn/trunk@682 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- DataExtractionOSM/src/net/osmand/Version.java | 2 +- .../osmand/binary/BinaryMapDataObject.java | 12 + .../osmand/binary/BinaryMapIndexReader.java | 120 +- .../osmand/data/preparation/IndexCreator.java | 18 +- .../src/net/osmand/osm/MultyPolygon.java | 18 + ...s.java => OsmandRenderingRulesParser.java} | 233 ++-- .../src/net/osmand/render/default.render.xml | 6 +- .../net/osmand/render/BaseOsmandRender.java | 259 ++++ .../osmand/render/MapRenderRepositories.java | 49 +- .../src/net/osmand/render/OsmandRenderer.java | 1097 +++++------------ .../src/net/osmand/render/RenderingIcons.java | 4 +- .../src/net/osmand/render/TextRenderer.java | 764 ++++++++++++ 12 files changed, 1650 insertions(+), 932 deletions(-) rename DataExtractionOSM/src/net/osmand/render/{OsmandRenderingRules.java => OsmandRenderingRulesParser.java} (67%) create mode 100644 OsmAnd/src/net/osmand/render/BaseOsmandRender.java create mode 100644 OsmAnd/src/net/osmand/render/TextRenderer.java diff --git a/DataExtractionOSM/src/net/osmand/Version.java b/DataExtractionOSM/src/net/osmand/Version.java index bb51e8d80e..1d39bf0629 100644 --- a/DataExtractionOSM/src/net/osmand/Version.java +++ b/DataExtractionOSM/src/net/osmand/Version.java @@ -5,7 +5,7 @@ public class Version { public static final String APP_NAME = "OsmAnd"; //$NON-NLS-1$ public static final String APP_MAP_CREATOR_NAME = "OsmAndMapCreator"; //$NON-NLS-1$ public static final String APP_VERSION = "0.5.1"; //$NON-NLS-1$ - public static final String APP_DESCRIPTION = "alpha (b3)"; //$NON-NLS-1$ + public static final String APP_DESCRIPTION = "alpha (b4)"; //$NON-NLS-1$ public static final boolean VELCOM_EDITION = false; public static final String APP_NAME_VERSION = APP_NAME + " " + APP_VERSION; //$NON-NLS-1$ diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java index a97281f293..6ebb228e87 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapDataObject.java @@ -1,5 +1,6 @@ package net.osmand.binary; +import net.osmand.binary.BinaryMapIndexReader.MapIndex; import net.osmand.osm.MapRenderingTypes; public class BinaryMapDataObject { @@ -14,6 +15,8 @@ public class BinaryMapDataObject { protected String name; + protected MapIndex mapIndex = null; + public BinaryMapDataObject(){ } @@ -22,6 +25,7 @@ public class BinaryMapDataObject { this.stringId = stringId; } + protected void setCoordinates(int[] coordinates) { this.coordinates = coordinates; } @@ -59,6 +63,14 @@ public class BinaryMapDataObject { return highwayAttributes; } + public MapIndex getMapIndex() { + return mapIndex; + } + + public void setMapIndex(MapIndex mapIndex) { + this.mapIndex = mapIndex; + } + protected void setHighwayAttributes(int highwayAttributes) { this.highwayAttributes = highwayAttributes; } diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java index a79cb94409..7604dc6501 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java @@ -20,7 +20,9 @@ import net.osmand.data.Street; import net.osmand.data.TransportStop; import net.osmand.data.City.CityType; import net.osmand.osm.LatLon; +import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MapUtils; +import net.osmand.osm.MapRenderingTypes.MapRulType; import net.sf.junidecode.Junidecode; import org.apache.commons.logging.Log; @@ -43,9 +45,6 @@ public class BinaryMapIndexReader { private final static Log log = LogUtil.getLog(BinaryMapIndexReader.class); - - - public BinaryMapIndexReader(final RandomAccessFile raf) throws IOException { this.raf = raf; codedIS = CodedInputStreamRAF.newInstance(raf, 1024); @@ -668,6 +667,19 @@ public class BinaryMapIndexReader { int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: + if(index.encodingRules.isEmpty()){ + // init encoding rules by default + Map map = MapRenderingTypes.getEncodingRuleTypes(); + for(String tags : map.keySet()){ + MapRulType rt = map.get(tags); + if(rt.getType(null) != 0){ + initMapEncodingRule(index, rt.getType(null), rt.getSubType(null), tags, null); + } + for (String value : rt.getValuesSet()) { + initMapEncodingRule(index, rt.getType(value), rt.getSubType(value), tags, value); + } + } + } return; case OsmandOdb.OsmAndMapIndex.NAME_FIELD_NUMBER : index.setName(codedIS.readString()); @@ -696,6 +708,17 @@ public class BinaryMapIndexReader { } } + private void initMapEncodingRule(MapIndex index, int type, int subtype, String tag, String val) { + int ind = ((subtype << 5) | type); + if(!index.encodingRules.containsKey(tag)){ + index.encodingRules.put(tag, new LinkedHashMap()); + } + index.encodingRules.get(tag).put(val, ind); + if(!index.decodingRules.containsKey(ind)){ + index.decodingRules.put(ind, new TagValuePair(tag, val)); + } + } + private void readMapEncodingRule(MapIndex index) throws IOException { int subtype = 0; int type = 0; @@ -706,10 +729,7 @@ public class BinaryMapIndexReader { int tag = WireFormat.getTagFieldNumber(t); switch (tag) { case 0: - if(!index.encodingRules.containsKey(tags)){ - index.encodingRules.put(tags, new LinkedHashMap()); - } - index.encodingRules.get(tags).put(val, ((subtype << 5) | type)); + initMapEncodingRule(index, type, subtype, tags, val); return; case OsmandOdb.MapEncodingRule.VALUE_FIELD_NUMBER : val = codedIS.readString(); @@ -730,6 +750,7 @@ public class BinaryMapIndexReader { } } + private MapRoot readMapLevel() throws IOException { MapRoot root = new MapRoot(); while(true){ @@ -829,7 +850,7 @@ public class BinaryMapIndexReader { } codedIS.seek(tree.filePointer); int oldLimit = codedIS.pushLimit(tree.length); - searchMapTreeBounds(index.left, index.right, index.top, index.bottom, req); + searchMapTreeBounds(index.left, index.right, index.top, index.bottom, req, mapIndex); codedIS.popLimit(oldLimit); } } @@ -1416,7 +1437,7 @@ public class BinaryMapIndexReader { } private void searchMapTreeBounds(int pleft, int pright, int ptop, int pbottom, - SearchRequest req) throws IOException { + SearchRequest req, MapIndex root) throws IOException { int init = 0; int lastIndexResult = -1; int cright = 0; @@ -1464,7 +1485,7 @@ public class BinaryMapIndexReader { if(lastIndexResult == -1){ lastIndexResult = req.searchResults.size(); } - BinaryMapDataObject mapObject = readMapDataObject(cleft, cright, ctop, cbottom, req); + BinaryMapDataObject mapObject = readMapDataObject(cleft, cright, ctop, cbottom, req, root); if(mapObject != null){ req.searchResults.add(mapObject); @@ -1476,7 +1497,7 @@ public class BinaryMapIndexReader { length = readInt(); int filePointer = codedIS.getTotalBytesRead(); oldLimit = codedIS.pushLimit(length); - searchMapTreeBounds(cleft, cright, ctop, cbottom, req); + searchMapTreeBounds(cleft, cright, ctop, cbottom, req, root); codedIS.popLimit(oldLimit); codedIS.seek(filePointer + length); if(lastIndexResult >= 0){ @@ -1523,7 +1544,8 @@ public class BinaryMapIndexReader { } private int MASK_TO_READ = ~((1 << BinaryMapIndexWriter.SHIFT_COORDINATES) - 1); - private BinaryMapDataObject readMapDataObject(int left, int right, int top, int bottom, SearchRequest req) throws IOException { + private BinaryMapDataObject readMapDataObject(int left, int right, int top, int bottom, SearchRequest req, + MapIndex root) throws IOException { int tag = WireFormat.getTagFieldNumber(codedIS.readTag()); if(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER != tag) { throw new IllegalArgumentException(); @@ -1596,6 +1618,7 @@ public class BinaryMapIndexReader { BinaryMapDataObject dataObject = new BinaryMapDataObject(); dataObject.coordinates = req.cacheCoordinates.toArray(); dataObject.types = req.cacheTypes.toArray(); + dataObject.mapIndex = root; while(true){ int t = codedIS.readTag(); @@ -1765,11 +1788,72 @@ public class BinaryMapIndexReader { public static class MapIndex extends BinaryIndexPart { List roots = new ArrayList(); - Map> encodingRules = new LinkedHashMap>(); + Map> encodingRules = new LinkedHashMap>(); + Map decodingRules = new LinkedHashMap(); public List getRoots() { return roots; } + + public TagValuePair decodeType(int type, int subtype){ + return decodingRules.get(((subtype << 5) | type)); + } + + } + + public static class TagValuePair { + public String tag; + public String value; + public int additionalAttribute; + public TagValuePair(String tag, String value) { + super(); + this.tag = tag; + this.value = value; + } + + public TagValuePair(String tag, String value, int additionalAttribute) { + super(); + this.tag = tag; + this.value = value; + this.additionalAttribute = additionalAttribute; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + additionalAttribute; + result = prime * result + ((tag == null) ? 0 : tag.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TagValuePair other = (TagValuePair) obj; + if (additionalAttribute != other.additionalAttribute) + return false; + if (tag == null) { + if (other.tag != null) + return false; + } else if (!tag.equals(other.tag)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + + + } @@ -1856,7 +1940,7 @@ public class BinaryMapIndexReader { int length = 0; // offset from start for each SIZE_OFFSET_ARRAY elements - // (SIZE_OFFSET_ARRAY + 1) offset : offsets[0] + skipOneString() + // (SIZE_OFFSET_ARRAY + 1) offset = offsets[0] + skipOneString() TIntArrayList offsets = new TIntArrayList(); Map cacheOfStrings = new LinkedHashMap(); @@ -1874,10 +1958,10 @@ public class BinaryMapIndexReader { } public static void main(String[] args) throws IOException { - RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.obf"), "r"); + RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.obf"), "r"); //$NON-NLS-1$ //$NON-NLS-2$ // RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Belarus_4.obf"), "r"); BinaryMapIndexReader reader = new BinaryMapIndexReader(raf); - System.out.println("VERSION " + reader.getVersion()); + System.out.println("VERSION " + reader.getVersion()); //$NON-NLS-1$ long time = System.currentTimeMillis(); System.out.println(reader.mapIndexes.get(0).encodingRules); @@ -1951,8 +2035,8 @@ public class BinaryMapIndexReader { // } // } - System.out.println("MEMORY " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); - System.out.println("Time " + (System.currentTimeMillis() - time)); + System.out.println("MEMORY " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())); //$NON-NLS-1$ + System.out.println("Time " + (System.currentTimeMillis() - time)); //$NON-NLS-1$ } } \ No newline at end of file diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java index 310f11901c..e6c006a604 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java @@ -2514,18 +2514,18 @@ public class IndexCreator { long time = System.currentTimeMillis(); IndexCreator creator = new IndexCreator(new File("e:/Information/OSM maps/osmand/")); creator.setIndexMap(true); -// creator.setIndexAddress(true); + creator.setIndexAddress(true); creator.setIndexPOI(true); -// creator.setIndexTransport(true); + creator.setIndexTransport(true); - creator.recreateOnlyBinaryFile = true; - creator.deleteDatabaseIndexes = false; + creator.recreateOnlyBinaryFile = false; + creator.deleteDatabaseIndexes = true; - creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb")); - creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null); +// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb")); +// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null); -// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/belarus_nodes.tmp.odb")); -// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/belarus.osm.bz2"), new ConsoleProgressImplementation(3), null); + creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/belarus_nodes.tmp.odb")); + creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/belarus.osm.bz2"), new ConsoleProgressImplementation(3), null); // creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/ams.tmp.odb")); // creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/ams_part_map.osm"), new ConsoleProgressImplementation(3), null); @@ -2540,6 +2540,8 @@ public class IndexCreator { // creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/luxembourg.tmp.odb")); // creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/luxembourg.osm.pbf"), new ConsoleProgressImplementation(15), null); + +// creator.generateIndexes(new File("e:/Information/OSM maps/osm_map/new_zealand.osm.bz2"), new ConsoleProgressImplementation(3), null); System.out.println("WHOLE GENERATION TIME : " + (System.currentTimeMillis() - time)); System.out.println("COORDINATES_SIZE " + BinaryMapIndexWriter.COORDINATES_SIZE + " count " + BinaryMapIndexWriter.COORDINATES_COUNT); diff --git a/DataExtractionOSM/src/net/osmand/osm/MultyPolygon.java b/DataExtractionOSM/src/net/osmand/osm/MultyPolygon.java index 092b956e2f..65a3d359fe 100644 --- a/DataExtractionOSM/src/net/osmand/osm/MultyPolygon.java +++ b/DataExtractionOSM/src/net/osmand/osm/MultyPolygon.java @@ -9,6 +9,8 @@ public class MultyPolygon extends BinaryMapDataObject { // first 32 bits - x, second 32 bits - y private long[][] lines = null; private String[] names = null; + private String tag = null; + private String value = null; public MultyPolygon(){ super(); id = -1; @@ -62,5 +64,21 @@ public class MultyPolygon extends BinaryMapDataObject { public int getPoint31YTile(int ind, int b) { return (int)(lines[b][ind] & Integer.MAX_VALUE); } + + public void setTag(String tag) { + this.tag = tag; + } + + public void setValue(String value) { + this.value = value; + } + + public String getTag() { + return tag; + } + + public String getValue() { + return value; + } } diff --git a/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRules.java b/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java similarity index 67% rename from DataExtractionOSM/src/net/osmand/render/OsmandRenderingRules.java rename to DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java index 715d185e01..b940f21647 100644 --- a/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRules.java +++ b/DataExtractionOSM/src/net/osmand/render/OsmandRenderingRulesParser.java @@ -18,10 +18,10 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -public class OsmandRenderingRules { +public class OsmandRenderingRulesParser { - private final static Log log = LogUtil.getLog(OsmandRenderingRules.class); + private final static Log log = LogUtil.getLog(OsmandRenderingRulesParser.class); public static class EffectAttributes { public int color = 0; @@ -77,15 +77,27 @@ public class OsmandRenderingRules { } + public interface RenderingRuleVisitor { + + /** + * @param state - one of the point, polygon, line, text state + * @param filter + */ + public void visitRule(int state, FilterState filter); + + public void rendering(String name, String depends); + } - private final static int POINT_STATE = 1; - private final static int POLYGON_STATE = 2; - private final static int LINE_STATE = 3; - private final static int TEXT_STATE = 4; - public void parseRenderingRules(InputStream is) throws IOException, SAXException { + + public final static int POINT_STATE = 1; + public final static int POLYGON_STATE = 2; + public final static int LINE_STATE = 3; + public final static int TEXT_STATE = 4; + + public void parseRenderingRules(InputStream is, RenderingRuleVisitor visitor) throws IOException, SAXException { try { final SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - saxParser.parse(is, new RenderingRulesHandler(saxParser)); + saxParser.parse(is, new RenderingRulesHandler(saxParser, visitor)); } catch (ParserConfigurationException e) { throw new SAXException(e); } @@ -93,12 +105,15 @@ public class OsmandRenderingRules { private class RenderingRulesHandler extends DefaultHandler { private final SAXParser parser; + private final RenderingRuleVisitor visitor; private int state; Stack stack = new Stack(); - public RenderingRulesHandler(SAXParser parser){ + + public RenderingRulesHandler(SAXParser parser, RenderingRuleVisitor visitor){ this.parser = parser; + this.visitor = visitor; } @Override @@ -121,8 +136,10 @@ public class OsmandRenderingRules { } else if("case".equals(name)){ //$NON-NLS-1$ FilterState st = parseFilterAttributes(attributes); ((SwitchState)stack.peek()).filters.add(st); + } else if("renderer".equals(name)){ //$NON-NLS-1$ + visitor.rendering(attributes.getValue("name"), attributes.getValue("depends")); //$NON-NLS-1$ //$NON-NLS-2$ } else { -// System.err.println("Unknown tag " + name); + log.warn("Unknown tag" + name); //$NON-NLS-1$ } } @@ -133,61 +150,15 @@ public class OsmandRenderingRules { List list = popAndAggregateState(); for (FilterState pop : list) { if (pop.tag != null && pop.minzoom != -1) { - String gen = generateAttributes(pop); - if (gen != null) { - String res = ""; - if (pop.maxzoom != -1) { - res += " zoom : " +pop.minzoom + "-" + pop.maxzoom; - } else { - res += " zoom : " +pop.minzoom; - } - res += " tag="+pop.tag; - res += " val="+pop.val; - if(pop.layer != 0){ - res += " layer="+pop.layer; - } - - res += gen; - System.out.println(res); - } + visitor.visitRule(state, pop); } } - } else if("switch".equals(name)){ + } else if("switch".equals(name)){ //$NON-NLS-1$ stack.pop(); } } - private String generateAttributes(FilterState s){ - String res = ""; - if(s.shader != null){ - res+=" shader=" + s.shader; - } - if(s.main.color != 0){ - res +=" color="+colorToString(s.main.color); - } - if(s.icon != null){ - res+= " icon="+s.icon; - } - if(s.main.strokeWidth != 0){ - res+= " strokeWidth="+s.main.strokeWidth; - } - if(s.main.pathEffect != null){ - res+= " pathEffect="+s.main.pathEffect; - } - if(state == POLYGON_STATE){ - return null; -// if(s.shader != null){ -// return " shader=" + s.shader; -// } -// return " color=" + colorToString(s.main.color); -// } else if(state == POINT_STATE){ -// return " icon=" + s.icon; - } else if(state == LINE_STATE){ - return res; - } else { - return null; - } - } + public List popAndAggregateState() { FilterState pop = (FilterState) stack.pop(); @@ -204,8 +175,8 @@ public class OsmandRenderingRules { } } else { List filters = ((SwitchState)o).filters; - if(res == null){ - res =new ArrayList(); + if (res == null) { + res = new ArrayList(); res.add(pop); } int l = res.size(); @@ -217,7 +188,7 @@ public class OsmandRenderingRules { } } for (int j = 0; j < res.size(); j++) { - mergeStateInto(filters.get(j % filters.size()), res.get(j)); + mergeStateInto(filters.get(j / l), res.get(j)); } } @@ -327,76 +298,76 @@ public class OsmandRenderingRules { for(int i=0; i + - + @@ -175,7 +175,7 @@ - + diff --git a/OsmAnd/src/net/osmand/render/BaseOsmandRender.java b/OsmAnd/src/net/osmand/render/BaseOsmandRender.java new file mode 100644 index 0000000000..3122d4a291 --- /dev/null +++ b/OsmAnd/src/net/osmand/render/BaseOsmandRender.java @@ -0,0 +1,259 @@ +package net.osmand.render; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.osmand.LogUtil; +import net.osmand.render.OsmandRenderer.RenderingContext; +import net.osmand.render.OsmandRenderer.RenderingPaintProperties; +import net.osmand.render.OsmandRenderingRulesParser.EffectAttributes; +import net.osmand.render.OsmandRenderingRulesParser.FilterState; +import net.osmand.render.OsmandRenderingRulesParser.RenderingRuleVisitor; + +import org.apache.commons.logging.Log; +import org.xml.sax.SAXException; + +import android.graphics.Color; +import android.graphics.Paint.Cap; + + +public class BaseOsmandRender implements RenderingRuleVisitor { + + public String name = "default"; //$NON-NLS-1$ + public List depends = new ArrayList(); + private static final Log log = LogUtil.getLog(BaseOsmandRender.class); + + @SuppressWarnings("unchecked") + private Map>>[] rules = new LinkedHashMap[5]; + + + private static BaseOsmandRender defaultRender = null; + public static BaseOsmandRender defaultRender() throws IOException, SAXException{ + if(defaultRender == null){ + defaultRender = new BaseOsmandRender(OsmandRenderingRulesParser.class.getResourceAsStream("default.render.xml")); //$NON-NLS-1$ + } + return defaultRender; + } + + public BaseOsmandRender(InputStream is) throws IOException, SAXException { + long time = System.currentTimeMillis(); + OsmandRenderingRulesParser parser = new OsmandRenderingRulesParser(); + parser.parseRenderingRules(is, this); + log.info("Init render " + name + " for " + (System.currentTimeMillis() - time) + " ms"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } + + protected BaseOsmandRender(){ + } + + @Override + public void rendering(String name, String depends) { + this.name = name; + if(depends != null && depends.length() > 0){ + for(String s : depends.split(",")) { //$NON-NLS-1$ + if(s.trim().length() > 0){ + this.depends.add(s.trim()); + } + } + } + } + + @Override + public void visitRule(int state, FilterState filter) { + boolean accept = filter.minzoom != -1; + if(state == OsmandRenderingRulesParser.POINT_STATE){ + accept &= RenderingIcons.getIcons().containsKey(filter.icon); + } + if (accept) { + if (rules[state] == null) { + rules[state] = new LinkedHashMap>>(); + } + if (rules[state].get(filter.tag) == null) { + rules[state].put(filter.tag, new LinkedHashMap>()); + } + if (rules[state].get(filter.tag).get(filter.val) == null) { + rules[state].get(filter.tag).put(filter.val, new ArrayList(3)); + } + rules[state].get(filter.tag).get(filter.val).add(filter); + } + } + + public Integer getPointIcon(String tag, String val, int zoom){ + Integer i = getPointIconImpl(tag,val, zoom); + if(i== null){ + return getPointIconImpl(tag, null, zoom); + } + return i; + } + + private Integer getPointIconImpl(String tag, String val, int zoom) { + Map> map = rules[OsmandRenderingRulesParser.POINT_STATE].get(tag); + if (map != null) { + List list = map.get(val); + if (list != null) { + for (FilterState f : list) { + if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1)) { + return RenderingIcons.getIcons().get(f.icon); + } + } + } + } + return null; + } + + // TODO layer + public boolean renderPolyline(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o){ + boolean r = renderPolylineImpl(tag,val, zoom, rc, o); + if(!r){ + return renderPolylineImpl(tag, null, zoom, rc, o); + } + return r; + } + + private boolean renderPolylineImpl(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o) { + Map> map = rules[OsmandRenderingRulesParser.LINE_STATE].get(tag); + if (map != null) { + List list = map.get(val); + if (list != null) { + for (FilterState f : list) { + // TODO layer!!! + if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1) && f.layer == 0) { + // to not make transparent + rc.main.color = Color.BLACK; + if(f.shader != null){ + Integer i = RenderingIcons.getIcons().get(f.shader); + if(i != null){ + rc.main.shader = o.getShader(i); + } + } + rc.main.fillArea = false; + applyEffectAttributes(f.main, rc.main, o); + if(f.effectAttributes.size() > 0){ + applyEffectAttributes(f.effectAttributes.get(0), rc.second, o); + if(f.effectAttributes.size() > 1){ + applyEffectAttributes(f.effectAttributes.get(1), rc.third, o); + } + } + return true; + } + } + } + } + return false; + } + + public boolean renderPolygon(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o){ + boolean r = renderPolygonImpl(tag,val, zoom, rc, o); + if(!r){ + return renderPolygonImpl(tag, null, zoom, rc, o); + } + return r; + } + + private boolean renderPolygonImpl(String tag, String val, int zoom, RenderingContext rc, OsmandRenderer o) { + Map> map = rules[OsmandRenderingRulesParser.POLYGON_STATE].get(tag); + if (map != null) { + List list = map.get(val); + if (list != null) { + for (FilterState f : list) { + if (f.minzoom <= zoom && (zoom <= f.maxzoom || f.maxzoom == -1)) { + if(f.shader != null){ + Integer i = RenderingIcons.getIcons().get(f.shader); + if(i != null){ + // to not make transparent + rc.main.color = Color.BLACK; + rc.main.shader = o.getShader(i); + } + } + rc.main.fillArea = true; + applyEffectAttributes(f.main, rc.main, o); + if(f.effectAttributes.size() > 0){ + applyEffectAttributes(f.effectAttributes.get(0), rc.second, o); + if(f.effectAttributes.size() > 1){ + applyEffectAttributes(f.effectAttributes.get(1), rc.third, o); + } + } + return true; + } + } + } + } + return false; + } + + private void applyEffectAttributes(EffectAttributes ef, RenderingPaintProperties props, OsmandRenderer o){ + if(ef.cap != null){ + props.cap = Cap.valueOf(ef.cap.toUpperCase()); + } + if(ef.color != 0){ + // do not set transparent color + props.color = ef.color; + } + if(ef.pathEffect != null){ + props.pathEffect = o.getDashEffect(ef.pathEffect); + } + if(ef.strokeWidth > 0){ + props.strokeWidth = ef.strokeWidth; + } + if(ef.shadowColor != 0 && ef.shadowRadius > 0){ + props.shadowColor = ef.shadowColor; + props.shadowLayer = (int) ef.shadowRadius; + } + } + + public String renderObjectText(String name, String tag, String val, RenderingContext rc) { + if(name == null || name.length() == 0){ + return null; + } + String ret = renderObjectTextImpl(name, tag, val, rc); + if(rc.textSize > 0){ + return ret; + } + return renderObjectTextImpl(name, tag, null, rc); + } + + private String renderObjectTextImpl(String name, String tag, String val, RenderingContext rc) { + Map> map = rules[OsmandRenderingRulesParser.TEXT_STATE].get(tag); + if (map != null) { + List list = map.get(val); + if (list != null) { + // first find rule with same text length + for (FilterState f : list) { + if (f.minzoom <= rc.zoom && (rc.zoom <= f.maxzoom || f.maxzoom == -1)) { + if(f.textLength == name.length() && f.text.textSize > 0){ + fillTextProperties(f, rc); + return name; + } + } + } + + for (FilterState f : list) { + if (f.minzoom <= rc.zoom && (rc.zoom <= f.maxzoom || f.maxzoom == -1)) { + if(f.textLength == 0 && f.text.textSize > 0){ + fillTextProperties(f, rc); + return name; + } + } + } + } + } + return null; + } + + private void fillTextProperties(FilterState f, RenderingContext rc) { + rc.textSize = f.text.textSize; + rc.textColor = f.text.textColor; + rc.textSize = f.text.textSize; + rc.textMinDistance = f.text.textMinDistance; + rc.showTextOnPath = f.text.textOnPath; + Integer i = RenderingIcons.getIcons().get(f.text.textShield); + rc.textShield = i== null ? 0 : i.intValue(); + rc.textWrapWidth = f.text.textWrapWidth; + rc.textHaloRadius = f.text.textHaloRadius; + rc.textBold = f.text.textBold; + rc.textDy = f.text.textDy; + } +} diff --git a/OsmAnd/src/net/osmand/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/render/MapRenderRepositories.java index 05039f5b9c..374ff35e81 100644 --- a/OsmAnd/src/net/osmand/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/render/MapRenderRepositories.java @@ -25,6 +25,7 @@ import net.osmand.RotatedTileBox; import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; +import net.osmand.binary.BinaryMapIndexReader.TagValuePair; import net.osmand.data.index.IndexConstants; import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MapUtils; @@ -193,7 +194,7 @@ public class MapRenderRepositories { ArrayList tempList = new ArrayList(); System.gc(); // to clear previous objects TLongSet ids = new TLongHashSet(); - Map> multiPolygons = new LinkedHashMap>(); + Map> multiPolygons = new LinkedHashMap>(); int leftX = MapUtils.get31TileNumberX(cLeftLongitude); int rightX = MapUtils.get31TileNumberX(cRightLongitude); int bottomY = MapUtils.get31TileNumberY(cBottomLatitude); @@ -242,7 +243,19 @@ public class MapRenderRepositories { count++; for(int i=0; i < r.getTypes().length; i++){ - registerMultipolygon(multiPolygons, r.getTypes()[i], r); + if ((r.getTypes()[i] & 0x3) == MapRenderingTypes.MULTY_POLYGON_TYPE) { + // multy polygon + int type = MapRenderingTypes.getMainObjectType(r.getTypes()[i]); + int subtype = MapRenderingTypes.getObjectSubType(r.getTypes()[i]); + TagValuePair pair = r.getMapIndex().decodeType(type, subtype); + if(pair != null){ + pair = new TagValuePair(pair.tag, pair.value, r.getTypes()[i]); + if (!multiPolygons.containsKey(pair)) { + multiPolygons.put(pair, new ArrayList()); + } + multiPolygons.get(pair).add(r); + } + } } @@ -339,30 +352,18 @@ public class MapRenderRepositories { /// Manipulating with multipolygons - private void registerMultipolygon(Map> multyPolygons, int type, BinaryMapDataObject obj) { - if ((type & 0x3) == MapRenderingTypes.MULTY_POLYGON_TYPE) { - // multy polygon - if (type != 0) { - if (!multyPolygons.containsKey(type)) { - multyPolygons.put(type, new ArrayList()); - } - multyPolygons.get(type).add(obj); - } - - } - } - public List proccessMultiPolygons(Map> multyPolygons, int leftX, int rightX, int bottomY, int topY, int zoom){ + public List proccessMultiPolygons(Map> multyPolygons, int leftX, int rightX, int bottomY, int topY, int zoom){ List listPolygons = new ArrayList(multyPolygons.size()); List> completedRings = new ArrayList>(); List> incompletedRings = new ArrayList>(); List completedRingNames = new ArrayList(); List incompletedRingNames = new ArrayList(); - for (Integer type : multyPolygons.keySet()) { + for (TagValuePair type : multyPolygons.keySet()) { List directList; List inverselist; - if(((type >> 15) & 1) == 1){ - int directType = (type & ((1 << 15) - 1)); + if(((type.additionalAttribute >> 15) & 1) == 1){ + TagValuePair directType = new TagValuePair(type.tag, type.value, type.additionalAttribute & ((1 << 15) - 1)); if (!multyPolygons.containsKey(directType)) { inverselist = multyPolygons.get(type); directList = Collections.emptyList(); @@ -371,7 +372,7 @@ public class MapRenderRepositories { continue; } } else { - int inverseType = (type | (1 << 15)); + TagValuePair inverseType = new TagValuePair(type.tag, type.value, type.additionalAttribute | (1 << 15)); directList = multyPolygons.get(type); inverselist = Collections.emptyList(); if (multyPolygons.containsKey(inverseType)) { @@ -394,10 +395,13 @@ public class MapRenderRepositories { private MultyPolygon processMultiPolygon(int leftX, int rightX, int bottomY, int topY, List listPolygons, List> completedRings, List> incompletedRings, List completedRingNames, List incompletedRingNames, - Integer type, List directList, List inverselist, int zoom) { + TagValuePair type, List directList, List inverselist, int zoom) { MultyPolygon pl = new MultyPolygon(); + // TODO delete setType at all!!! // delete direction last bit (to not show point) - pl.setType(type & 0x7fff); + pl.setType(type.additionalAttribute); + pl.setTag(type.tag); + pl.setValue(type.value); long dbId = 0; for (int km = 0; km < 2; km++) { List list = km == 0 ? directList : inverselist; @@ -443,8 +447,7 @@ public class MapRenderRepositories { } else { // due to self intersection small objects (for low zooms check only coastline) if (zoom >= 13 - || (MapRenderingTypes.getMainObjectType(pl.getTypes()[0]) == MapRenderingTypes.NATURAL && MapRenderingTypes - .getObjectSubType(pl.getTypes()[0]) == 5)) { + || ("natural".equals(type.tag) && "coastline".equals(type.value))) { //$NON-NLS-1$//$NON-NLS-2$ boolean clockwiseFound = false; for (List c : completedRings) { if (isClockwiseWay(c)) { diff --git a/OsmAnd/src/net/osmand/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/render/OsmandRenderer.java index 772a4d905f..f7a397cbda 100644 --- a/OsmAnd/src/net/osmand/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/render/OsmandRenderer.java @@ -3,6 +3,7 @@ package net.osmand.render; import gnu.trove.list.array.TIntArrayList; import gnu.trove.map.hash.TFloatObjectHashMap; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -13,13 +14,14 @@ import java.util.List; import java.util.Map; import net.osmand.LogUtil; -import net.osmand.R; import net.osmand.binary.BinaryMapDataObject; +import net.osmand.binary.BinaryMapIndexReader.TagValuePair; import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MultyPolygon; import net.sf.junidecode.Junidecode; import org.apache.commons.logging.Log; +import org.xml.sax.SAXException; import android.content.Context; import android.graphics.Bitmap; @@ -63,6 +65,8 @@ public class OsmandRenderer { private final Context context; + private BaseOsmandRender render; + private static class TextDrawInfo { @@ -210,26 +214,32 @@ public class OsmandRenderer { } } - public OsmandRenderer(Context context){ + public OsmandRenderer(Context context) { this.context = context; - + paintIcon = new Paint(); paintIcon.setStyle(Style.STROKE); - + paintText = new TextPaint(); paintText.setStyle(Style.FILL); paintText.setColor(Color.BLACK); paintText.setTextAlign(Align.CENTER); paintText.setTypeface(Typeface.create("Droid Serif", Typeface.NORMAL)); //$NON-NLS-1$ paintText.setAntiAlias(true); - + paint = new Paint(); paint.setAntiAlias(true); - + paintFillEmpty = new Paint(); paintFillEmpty.setStyle(Style.FILL); paintFillEmpty.setColor(clFillScreen); - + try { + render = BaseOsmandRender.defaultRender(); + } catch (IOException e) { + log.error("Exception initialize renderer", e); //$NON-NLS-1$ + } catch (SAXException e) { + log.error("Exception initialize renderer", e); //$NON-NLS-1$ + } } public PathEffect getDashEffect(String dashes){ @@ -545,17 +555,38 @@ public class OsmandRenderer { return rc.tempPoint; } + + + + + + public void clearCachedResources(){ + Collection values = new ArrayList(cachedIcons.values()); + cachedIcons.clear(); + for(Bitmap b : values){ + if(b != null){ + b.recycle(); + } + } + shaders.clear(); + } + private void drawMultiPolygon(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype) { - Path path = null; + String tag = ((MultyPolygon)obj).getTag(); + String value = ((MultyPolygon)obj).getValue(); + if(render == null || tag == null){ + return; + } rc.main.emptyArea(); rc.second.emptyLine(); rc.main.color = Color.rgb(245, 245, 245); - PolygonRenderer.renderPolygon(rc, rc.zoom, type, subtype, this); - if (!rc.main.fillArea) { + + boolean rendered = render.renderPolygon(tag, value, rc.zoom, rc, this); + if(!rendered){ return; } rc.visible++; - path = new Path(); + Path path = new Path(); for (int i = 0; i < ((MultyPolygon) obj).getBoundsCount(); i++) { int cnt = ((MultyPolygon) obj).getBoundPointsCount(i); float xText = 0; @@ -574,7 +605,7 @@ public class OsmandRenderer { String name = ((MultyPolygon) obj).getName(i); if (name != null) { rc.clearText(); - name = renderObjectText(name, subtype, type, rc.zoom, true, rc); + name = render.renderObjectText(name, tag, value, rc); if (rc.textSize > 0 && name != null) { TextDrawInfo info = new TextDrawInfo(name); info.fillProperties(rc, xText / cnt, yText / cnt); @@ -594,7 +625,12 @@ public class OsmandRenderer { } } + private void drawPolygon(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype) { + TagValuePair pair = obj.getMapIndex().decodeType(type, subtype); + if(render == null || pair == null){ + return; + } float xText = 0; float yText = 0; int zoom = rc.zoom; @@ -603,8 +639,8 @@ public class OsmandRenderer { rc.second.emptyLine(); rc.main.color = Color.rgb(245, 245, 245); - PolygonRenderer.renderPolygon(rc, zoom, type, subtype, this); - if(!rc.main.fillArea){ + boolean rendered = render.renderPolygon(pair.tag, pair.value, zoom, rc, this); + if(!rendered){ return; } rc.visible++; @@ -635,7 +671,7 @@ public class OsmandRenderer { String name = obj.getName(); if(name != null){ rc.clearText(); - name = renderObjectText(name, subtype, type, rc.zoom, true, rc); + name = render.renderObjectText(name, pair.tag, pair.value, rc); if (rc.textSize > 0 && name != null) { TextDrawInfo info = new TextDrawInfo(name); info.fillProperties(rc, xText, yText); @@ -645,31 +681,23 @@ public class OsmandRenderer { } return; } - - - - public void clearCachedResources(){ - Collection values = new ArrayList(cachedIcons.values()); - cachedIcons.clear(); - for(Bitmap b : values){ - if(b != null){ - b.recycle(); - } - } - shaders.clear(); - } private void drawPoint(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype, boolean renderText) { - int resId = PointRenderer.getPointBitmap(rc.zoom, type, subtype); + TagValuePair pair = obj.getMapIndex().decodeType(type, subtype); + if(render == null || pair == null){ + return; + } + + Integer resId = render.getPointIcon(pair.tag, pair.value, rc.zoom); String name = null; if (renderText) { name = obj.getName(); if (name != null) { rc.clearText(); - name = renderObjectText(name, subtype, type, rc.zoom, true, rc); + name = render.renderObjectText(name, pair.tag, pair.value, rc); } } - if(resId == 0 && name == null){ + if(resId == null && name == null){ return; } int len = obj.getPointsLength(); @@ -685,7 +713,7 @@ public class OsmandRenderer { ps.y /= len; } - if(resId != 0){ + if(resId != null){ IconDrawInfo ico = new IconDrawInfo(); ico.x = ps.x; ico.y = ps.y; @@ -699,7 +727,7 @@ public class OsmandRenderer { } } - + private void drawPolyline(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype, int wholeType) { @@ -707,6 +735,136 @@ public class OsmandRenderer { rc.second.emptyLine(); rc.third.emptyLine(); rc.adds = null; + TagValuePair pair = obj.getMapIndex().decodeType(type, subtype); + if(render == null || pair == null){ + return; + } + render.renderPolyline(pair.tag, pair.value, rc.zoom, rc, this); + if(rc.main.strokeWidth == 0){ + return; + } + if("highway".equals(pair.tag) && rc.zoom >= 16 && MapRenderingTypes.isOneWayWay(obj.getHighwayAttributes())){ //$NON-NLS-1$ + rc.adds = PolylineRenderer.getOneWayProperties(); + } + + + + int length = obj.getPointsLength(); + if(length < 2){ + return; + } + rc.visible++; + + Path path = null; + float pathRotate = 0; + float xLength = 0; + float yLength = 0; + boolean inverse = false; + float xPrev = 0; + float yPrev = 0; + float xMid = 0; + float yMid = 0; + PointF middlePoint = new PointF(); + int middle = obj.getPointsLength() / 2; + + for (int i = 0; i < length ; i++) { + PointF p = calcPoint(obj, i, rc); + if(i == 0 || i == length -1){ + xMid += p.x; + yMid += p.y; + } + if (path == null) { + path = new Path(); + path.moveTo(p.x, p.y); + } else { + xLength += p.x - xPrev; // not abs + yLength += p.y - yPrev; // not abs + if(i == middle){ + middlePoint.set(p.x, p.y); + double rot = - Math.atan2(p.x - xPrev, p.y - yPrev) * 180 / Math.PI; + if (rot < 0) { + rot += 360; + } + if (rot < 180) { + rot += 180; + inverse = true; + } + pathRotate = (float) rot; + } + path.lineTo(p.x, p.y); + } + xPrev = p.x; + yPrev = p.y; + } + if (path != null) { + rc.main.updatePaint(paint); + canvas.drawPath(path, paint); + if (rc.second.strokeWidth != 0) { + rc.second.updatePaint(paint); + canvas.drawPath(path, paint); + if (rc.third.strokeWidth != 0) { + rc.third.updatePaint(paint); + canvas.drawPath(path, paint); + } + } + if (rc.adds != null) { + for (int i = 0; i < rc.adds.length; i++) { + rc.adds[i].updatePaint(paint); + canvas.drawPath(path, paint); + } + } + if (obj.getName() != null) { + String name = obj.getName(); + rc.clearText(); + name = TextRenderer.renderObjectText(name, subtype, type, rc.zoom, false, rc); + if(rc.textSize == 0 && rc.showAnotherText != null){ + name = TextRenderer.renderObjectText(rc.showAnotherText, subtype, type, rc.zoom, false, rc); + } + if (name != null && rc.textSize > 0) { + if (!rc.showTextOnPath) { + TextDrawInfo text = new TextDrawInfo(name); + text.fillProperties(rc, middlePoint.x, middlePoint.y); + rc.textToDraw.add(text); + } + if(rc.showAnotherText != null){ + name = TextRenderer.renderObjectText(rc.showAnotherText, subtype, type, rc.zoom, false, rc); + } + + if (rc.showTextOnPath && paintText.measureText(obj.getName()) < Math.max(Math.abs(xLength), Math.abs(yLength))) { + if (inverse) { + path.rewind(); + boolean st = true; + for (int i = obj.getPointsLength() - 1; i >= 0; i--) { + PointF p = calcPoint(obj, i, rc); + if (st) { + st = false; + path.moveTo(p.x, p.y); + } else { + path.lineTo(p.x, p.y); + } + } + } + + TextDrawInfo text = new TextDrawInfo(name); + text.fillProperties(rc, xMid / 2, yMid / 2); + text.pathRotate = pathRotate; + text.drawOnPath = path; + text.vOffset = rc.main.strokeWidth / 2 - 1; + rc.textToDraw.add(text); + + } + } + } + } + } + + + // TODO delete !!! + private void drawPolylineOld(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype, int wholeType) { + rc.main.emptyLine(); + rc.second.emptyLine(); + rc.third.emptyLine(); + rc.adds = null; PolylineRenderer.renderPolyline(type, subtype, wholeType, obj.getHighwayAttributes(), rc, this); @@ -781,9 +939,9 @@ public class OsmandRenderer { if (obj.getName() != null) { String name = obj.getName(); rc.clearText(); - name = renderObjectText(name, subtype, type, rc.zoom, false, rc); + name = TextRenderer.renderObjectText(name, subtype, type, rc.zoom, false, rc); if(rc.textSize == 0 && rc.showAnotherText != null){ - name = renderObjectText(rc.showAnotherText, subtype, type, rc.zoom, false, rc); + name = TextRenderer.renderObjectText(rc.showAnotherText, subtype, type, rc.zoom, false, rc); } if (name != null && rc.textSize > 0) { if (!rc.showTextOnPath) { @@ -792,7 +950,7 @@ public class OsmandRenderer { rc.textToDraw.add(text); } if(rc.showAnotherText != null){ - name = renderObjectText(rc.showAnotherText, subtype, type, rc.zoom, false, rc); + name = TextRenderer.renderObjectText(rc.showAnotherText, subtype, type, rc.zoom, false, rc); } if (rc.showTextOnPath && paintText.measureText(obj.getName()) < Math.max(Math.abs(xLength), Math.abs(yLength))) { @@ -822,760 +980,147 @@ public class OsmandRenderer { } } } - - private static int[] trunkShields = new int[]{R.drawable.tru_shield1, R.drawable.tru_shield2, R.drawable.tru_shield3, - R.drawable.tru_shield4, R.drawable.tru_shield5, R.drawable.tru_shield6, R.drawable.tru_shield7,}; - private static int[] motorShields = new int[]{R.drawable.mot_shield1, R.drawable.mot_shield2, R.drawable.mot_shield3, - R.drawable.mot_shield4, R.drawable.mot_shield5, R.drawable.mot_shield6, R.drawable.mot_shield7,}; - private static int[] primaryShields = new int[]{R.drawable.pri_shield1, R.drawable.pri_shield2, R.drawable.pri_shield3, - R.drawable.pri_shield4, R.drawable.pri_shield5, R.drawable.pri_shield6, R.drawable.pri_shield7,}; - private static int[] secondaryShields = new int[]{R.drawable.sec_shield1, R.drawable.sec_shield2, R.drawable.sec_shield3, - R.drawable.sec_shield4, R.drawable.sec_shield5, R.drawable.sec_shield6, R.drawable.sec_shield7,}; - private static int[] tertiaryShields = new int[]{R.drawable.ter_shield1, R.drawable.ter_shield2, R.drawable.ter_shield3, - R.drawable.ter_shield4, R.drawable.ter_shield5, R.drawable.ter_shield6, R.drawable.ter_shield7,}; - - public static String renderObjectText(String name, int subType, int type, int zoom, boolean point, RenderingContext rc) { - if(name == null || name.length() == 0){ - return null; - } - int textSize = 0; - int textColor = 0; - int wrapWidth = 0; - int shadowRadius = 0; - int textMinDistance = 0; - int textShield = 0; - int dy = 0; - boolean bold = false; - boolean showTextOnPath = false; + + private void drawPolygonOld(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype) { + float xText = 0; + float yText = 0; + int zoom = rc.zoom; + Path path = null; + rc.main.emptyArea(); + rc.second.emptyLine(); + rc.main.color = Color.rgb(245, 245, 245); - switch (type) { - case MapRenderingTypes.HIGHWAY : { - if(name.charAt(0) == MapRenderingTypes.REF_CHAR){ - name = name.substring(1); - for(int k = 0; k < name.length(); k++){ - if(name.charAt(k) == MapRenderingTypes.REF_CHAR){ - if(k < name.length() - 1 && zoom > 14){ - rc.showAnotherText = name.substring(k + 1); - } - name = name.substring(0, k); - break; - } - } - if(rc.showAnotherText != null && zoom >= 16){ - break; - } - if(name.length() > 6){ - name = name.substring(0, 6); - } - int len = name.length(); - if(len == 0){ - // skip it - } else { - textSize = 10; - textColor = Color.WHITE; - bold = true; - textMinDistance = 70; - // spacing = 750 - if (subType == MapRenderingTypes.PL_HW_TRUNK) { - textShield = trunkShields[len - 1]; - if(zoom < 10){ - textSize = 0; - } - } else if (subType == MapRenderingTypes.PL_HW_MOTORWAY) { - textShield = motorShields[len - 1]; - if(zoom < 10){ - textSize = 0; - } - } else if (subType == MapRenderingTypes.PL_HW_PRIMARY) { - textShield = primaryShields[len - 1]; - if(zoom < 11){ - textSize = 0; - } - } else if (subType == MapRenderingTypes.PL_HW_SECONDARY) { - if(zoom < 14){ - textSize = 0; - } - textShield = secondaryShields[len - 1]; - } else if (subType == MapRenderingTypes.PL_HW_TERTIARY) { - if(zoom < 15){ - textSize = 0; - } - textShield = tertiaryShields[len - 1]; - } else { - if(zoom < 16){ - textSize = 0; - } else { - showTextOnPath = true; - textColor = Color.BLACK; - textSize = 10; - textMinDistance = 40; - shadowRadius = 1; - // spacing = 750; - } - } - } + PolygonRenderer.renderPolygon(rc, zoom, type, subtype, this); + if(!rc.main.fillArea){ + return; + } + rc.visible++; + int len = obj.getPointsLength(); + for (int i = 0; i < obj.getPointsLength(); i++) { + + PointF p = calcPoint(obj, i, rc); + xText += p.x; + yText += p.y; + if (path == null) { + path = new Path(); + path.moveTo(p.x, p.y); } else { - if(subType == MapRenderingTypes.PL_HW_TRUNK || subType == MapRenderingTypes.PL_HW_PRIMARY - || subType == MapRenderingTypes.PL_HW_SECONDARY){ - textColor = Color.BLACK; - showTextOnPath = true; - if(zoom == 13 && type != MapRenderingTypes.PL_HW_SECONDARY){ - textSize = 8; - } else if(zoom == 14){ - textSize = 9; - } else if(zoom > 14 && zoom < 17){ - textSize = 10; - } else if(zoom > 16){ - textSize = 12; - } - } else if(subType == MapRenderingTypes.PL_HW_TERTIARY || subType == MapRenderingTypes.PL_HW_RESIDENTIAL - || subType == MapRenderingTypes.PL_HW_UNCLASSIFIED || subType == MapRenderingTypes.PL_HW_SERVICE){ - textColor = Color.BLACK; - showTextOnPath = true; - if(zoom < 15){ - textSize = 0; - } else if(zoom < 17){ - textSize = 9; - } else { - textSize = 11; - } - } else if(subType < 32){ - // highway subtype - if(zoom >= 16){ - textColor = Color.BLACK; - showTextOnPath = true; - textSize = 9; - } - } else if(subType == 40){ - // bus stop - if(zoom >= 17){ - textMinDistance = 20; - textColor = Color.BLACK; - textSize = 9; - wrapWidth = 25; - dy = 11; - } - } - } - } break; - case MapRenderingTypes.WATERWAY : { - if (subType == 1) { - if (zoom >= 15 /* && !tunnel */) { - showTextOnPath = true; - textSize = 8; - shadowRadius = 1; - textColor = 0xff6699cc; - } - } else if (subType == 2 || subType == 4) { - if (zoom >= 12 /* && !tunnel */) { - textSize = 9; - showTextOnPath = true; - shadowRadius = 1; - textColor = 0xff6699cc; - textMinDistance = 70; - } - } else if (subType == 5 || subType == 6) { - if (zoom >= 15 /* && !tunnel */) { - textSize = 8; - showTextOnPath = true; - shadowRadius = 1; - textColor = 0xff6699cc; - } - } else if (subType == 12) { - if(zoom >= 15){ - textColor = Color.BLACK; - textSize = 8; - shadowRadius = 1; - } - } else if (subType == 8) { - if (zoom >= 15) { - shadowRadius = 1; - textSize = 9; - textColor = 0xff0066ff; - wrapWidth = 70; - dy = 10; - } + path.lineTo(p.x, p.y); } } - break; - case MapRenderingTypes.AEROWAY: { - textColor = 0xff6692da; - shadowRadius = 1; - if(name.charAt(0) == MapRenderingTypes.REF_CHAR){ - name = name.substring(1); - } - if (subType == 7 || subType == 8) { - if (zoom >= 15) { - showTextOnPath = true; - textSize = 10; - textColor = 0xff333333; - textMinDistance = 50; - shadowRadius = 1; - // spacing = 750; - } - } else if (subType == 10) { - // airport - if (zoom >= 10 && zoom <= 12) { - textSize = 9; - dy = -12; - bold = true; - } - } else if (subType == 1) { - // aerodrome - if (zoom >= 10 && zoom <= 12) { - textSize = 8; - dy = -12; - } - } else if (subType == 12) { - if (zoom >= 17) { - textSize = 10; - textColor = 0xffaa66cc; - shadowRadius = 1; - wrapWidth = 10; - } - } - } - break; - case MapRenderingTypes.AERIALWAY: { - if (subType == 7) { - if (zoom >= 14) { - textColor = 0xff6666ff; - shadowRadius = 1; - if (zoom == 14) { - dy = -7; - textSize = 8; + if (path != null && len > 0) { + xText /= len; + yText /= len; - } else { - dy = -10; - textSize = 10; - } + rc.main.updatePaint(paint); + canvas.drawPath(path, paint); + if (rc.second.strokeWidth != 0) { + rc.second.updatePaint(paint); + canvas.drawPath(path, paint); + } + String name = obj.getName(); + if(name != null){ + rc.clearText(); + name = TextRenderer.renderObjectText(name, subtype, type, rc.zoom, true, rc); + if (rc.textSize > 0 && name != null) { + TextDrawInfo info = new TextDrawInfo(name); + info.fillProperties(rc, xText, yText); + rc.textToDraw.add(info); } + } + } + return; + } + + private void drawPointOld(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype, boolean renderText) { + int resId = PointRenderer.getPointBitmap(rc.zoom, type, subtype); + String name = null; + if (renderText) { + name = obj.getName(); + if (name != null) { + rc.clearText(); + name = TextRenderer.renderObjectText(name, subtype, type, rc.zoom, true, rc); + } + } + if(resId == 0 && name == null){ + return; + } + int len = obj.getPointsLength(); + rc.visible++; + PointF ps = new PointF(0, 0); + for (int i = 0; i < len; i++) { + PointF p = calcPoint(obj, i, rc); + ps.x += p.x; + ps.y += p.y; + } + if(len > 1){ + ps.x /= len; + ps.y /= len; + } + + if(resId != 0){ + IconDrawInfo ico = new IconDrawInfo(); + ico.x = ps.x; + ico.y = ps.y; + ico.resId = resId; + rc.iconsToDraw.add(ico); + } + if (name != null && rc.textSize > 0) { + TextDrawInfo info = new TextDrawInfo(name); + info.fillProperties(rc, ps.x, ps.y); + rc.textToDraw.add(info); + } + + } - } + private void drawMultiPolygonOld(BinaryMapDataObject obj, Canvas canvas, RenderingContext rc, int type, int subtype) { + Path path = null; + rc.main.emptyArea(); + rc.second.emptyLine(); + rc.main.color = Color.rgb(245, 245, 245); + PolygonRenderer.renderPolygon(rc, rc.zoom, type, subtype, this); + if (!rc.main.fillArea) { + return; } - break; - case MapRenderingTypes.RAILWAY: { - if (zoom >= 14) { - textColor = 0xff6666ff; - shadowRadius = 1; - if (subType == 13) { - bold = true; - if (zoom == 14) { - dy = -8; - textSize = 9; - } else { - dy = -10; - textSize = 11; - } - } else if (subType == 22 || subType == 23) { - if (zoom == 14) { - dy = -7; - textSize = 8; - } else { - dy = -10; - textSize = 10; + rc.visible++; + path = new Path(); + for (int i = 0; i < ((MultyPolygon) obj).getBoundsCount(); i++) { + int cnt = ((MultyPolygon) obj).getBoundPointsCount(i); + float xText = 0; + float yText = 0; + for (int j = 0; j < cnt; j++) { + PointF p = calcMultiPolygonPoint((MultyPolygon) obj, j, i, rc); + xText += p.x; + yText += p.y; + if (j == 0) { + path.moveTo(p.x, p.y); + } else { + path.lineTo(p.x, p.y); + } + } + if (cnt > 0) { + String name = ((MultyPolygon) obj).getName(i); + if (name != null) { + rc.clearText(); + name = TextRenderer.renderObjectText(name, subtype, type, rc.zoom, true, rc); + if (rc.textSize > 0 && name != null) { + TextDrawInfo info = new TextDrawInfo(name); + info.fillProperties(rc, xText / cnt, yText / cnt); + rc.textToDraw.add(info); } } } } - break; - case MapRenderingTypes.EMERGENCY: { - if (zoom >= 17) { - if (subType == 10) { - dy = 9; - textColor = 0xff734a08; - wrapWidth = 30; - textSize = 10; - } - } + rc.main.updatePaint(paint); + canvas.drawPath(path, paint); + if (rc.second.strokeWidth != 0) { + //rc.second.strokeWidth = 1.5f; + //rc.second.color = Color.BLACK; + + rc.second.updatePaint(paint); + canvas.drawPath(path, paint); } - break; - case MapRenderingTypes.NATURAL: { - if (subType == 23) { - if (zoom >= 12) { - shadowRadius = 2; - textColor = 0xff00000; - textSize = 10; - wrapWidth = 10; - } - } else if (subType == 13) { - if (zoom >= 14) { - shadowRadius = 1; - textColor = 0xff654321; - textSize = 9; - dy = 5; - } - } else if (subType == 3) { - if (zoom >= 15) { - shadowRadius = 1; - textColor = 0xff654321; - textSize = 10; - dy = 9; - wrapWidth = 20; - } - } else if (subType == 21) { - if (zoom >= 12) { - textSize = 10; - shadowRadius = 1; - wrapWidth = 20; - textColor = 0xff6699cc; - } - } else if (subType == 2) { - if (zoom >= 14) { - textSize = 10; - shadowRadius = 1; - wrapWidth = 20; - textColor = 0xff6699cc; - } - } else if (subType == 17) { - if (zoom >= 16) { - textSize = 8; - shadowRadius = 1; - dy = 10; - wrapWidth = 20; - textColor = 0xff6699cc; - } - } - } - break; - case MapRenderingTypes.LANDUSE: { - if (zoom >= 15) { - if (subType == 22) { - textSize = 10; - shadowRadius = 1; - wrapWidth = 20; - textColor = 0xff6699cc; - } else if (point) { - textColor = 0xff000000; - shadowRadius = 2; - wrapWidth = 10; - textSize = 9; - } - } - } - break; - case MapRenderingTypes.TOURISM: { - if (subType == 9) { - if (zoom >= 16) { - textColor = 0xff6699cc; - shadowRadius = 1; - dy = 15; - textSize = 9; - } - } else if (subType == 12 || subType == 13 || subType == 14) { - if (zoom >= 17) { - textColor = 0xff0066ff; - shadowRadius = 1; - dy = 14; - textSize = 10; - } - } else if (subType == 11) { - if (zoom >= 17) { - textColor = 0xff0066ff; - shadowRadius = 1; - dy = 13; - textSize = 8; - } - } else if (subType == 4) { - if (zoom >= 17) { - shadowRadius = 1; - textSize = 10; - textColor = 0xff0066ff; - wrapWidth = 70; - dy = 15; - } - } else if (subType == 5) { - if (zoom >= 17) { - shadowRadius = 1; - textSize = 10; - textColor = 0xff0066ff; - wrapWidth = 70; - dy = 19; - } - } else if (subType == 7) { - if (zoom >= 15) { - textColor = 0xff734a08; - textSize = 9; - wrapWidth = 30; - shadowRadius = 1; - } - } else if (subType == 15) { - if (zoom >= 17) { - textColor = 0xff734a08; - textSize = 10; - dy = 12; - shadowRadius = 1; - } - } - } - break; - case MapRenderingTypes.LEISURE: { - if (subType == 8) { - if (zoom >= 15) { - textColor = Color.BLUE; - textSize = 9; - wrapWidth = 30; - shadowRadius = 1; - } - } else if ((zoom >= 15 && !point) || zoom >= 17) { - textColor = 0xff000000; - shadowRadius = 2; - wrapWidth = 15; - textSize = 9; - } - } - break; - case MapRenderingTypes.HISTORIC: { - if (zoom >= 17) { - if (subType == 6) { - shadowRadius = 1; - textColor = 0xff654321; - textSize = 9; - dy = 12; - wrapWidth = 20; - } - } - } - break; - case MapRenderingTypes.AMENITY_TRANSPORTATION: { - if (zoom >= 17) { - if (subType == 1) { - dy = 9; - textColor = 0xff0066ff; - textSize = 9; - wrapWidth = 34; - } else if (subType == 4 || subType == 18) { - textColor = 0xff0066ff; - shadowRadius = 1; - dy = 13; - textSize = 9; - } - } - } - break; - case MapRenderingTypes.AMENITY_EDUCATION: { - if (subType == 4) { - if (zoom >= 17) { - dy = 12; - textColor = 0xff734a08; - bold = true; - textSize = 10; - } - } else if (subType == 5) { - if (zoom >= 15) { - textColor = 0xff000033; - bold = true; - textSize = 9; - wrapWidth = 16; - } - } else if (subType == 1 || subType == 2 || subType == 3) { - if (zoom >= 16) { - textColor = 0xff000033; - if(subType != 1){ - dy = 11; - } - textSize = 9; - wrapWidth = 16; - } - } - } - break; - case MapRenderingTypes.MAN_MADE: { - if (subType == 1 || subType == 5) { - if(zoom >= 16){ - textColor = 0xff444444; - textSize = 9; - if(zoom >= 17){ - textSize = 11; - if(zoom >= 18){ - textSize = 15; - } - } - wrapWidth = 16; - } - } else if (subType == 17) { - if (zoom >= 15) { - textColor = 0xff000033; - textSize = 9; - shadowRadius = 2; - dy = 16; - wrapWidth = 12; - } - } else if (subType == 27) { - if (zoom >= 17) { - textSize = 9; - textColor = 0xff734a08; - dy = 12; - shadowRadius = 1; - wrapWidth = 20; - } - } - } - break; - case MapRenderingTypes.AMENITY_ENTERTAINMENT: { - if (zoom >= 17) { - textSize = 9; - textColor = 0xff734a08; - dy = 12; - shadowRadius = 1; - wrapWidth = 15; - } - } break; - case MapRenderingTypes.AMENITY_FINANCE: { - if (subType == 2) { - if (zoom >= 17) { - shadowRadius = 1; - textSize = 9; - textColor = Color.BLACK; - dy = 14; - } - } - } - break; - case MapRenderingTypes.MILITARY: { - if (subType == 4) { - if (zoom >= 12) { - bold = true; - textSize = 9; - shadowRadius = 1; - wrapWidth = 10; - textColor = 0xffffc0cb; - } - } - } - break; - case MapRenderingTypes.SHOP: { - if (subType == 42 || subType == 13 || subType == 16 || subType == 19 || subType == 31 || subType == 48) { - if (zoom >= 17) { - textColor = 0xff993399; - textSize = 8; - dy = 13; - shadowRadius = 1; - wrapWidth = 14; - } - } else if (subType == 65 || subType == 17) { - if (zoom >= 16) { - textSize = 9; - textColor = 0xff993399; - dy = 13; - shadowRadius = 1; - wrapWidth = 20; - } - } - - } - break; - case MapRenderingTypes.AMENITY_HEALTHCARE: { - if (subType == 2) { - if (zoom >= 16) { - textSize = 8; - textColor = 0xffda0092; - dy = 12; - shadowRadius = 2; - wrapWidth = 24; - } - } else if (subType == 1) { - if (zoom >= 17) { - textSize = 8; - textColor = 0xffda0092; - dy = 11; - shadowRadius = 1; - wrapWidth = 12; - } - } - - } - break; - case MapRenderingTypes.AMENITY_OTHER: { - if (subType == 10) { - if (zoom >= 17) { - wrapWidth = 30; - textSize = 10; - textColor = 0xff734a08; - dy = 10; - } - } else if (subType == 26) { - if (zoom >= 17) { - wrapWidth = 30; - textSize = 11; - textColor = 0x000033; - dy = 10; - } - } else if (subType == 16) { - if (zoom >= 16) { - textColor = 0xff6699cc; - shadowRadius = 1; - dy = 15; - textSize = 9; - } - } else if (subType == 7) { - if (zoom >= 17) { - textColor = 0xff0066ff; - shadowRadius = 1; - wrapWidth = 20; - dy = 8; - textSize = 9; - } - } else if (subType == 13) { - if (zoom >= 17) { - textColor = 0xff734a08; - textSize = 10; - shadowRadius = 1; - wrapWidth = 20; - dy = 16; - } - } else if (subType == 2) { - if (zoom >= 16) { - textColor = 0xff660033; - textSize = 10; - shadowRadius = 2; - wrapWidth = 10; - } - } - } - break; - case MapRenderingTypes.AMENITY_SUSTENANCE: { - if (zoom >= 17) { - if (subType >= 1 && subType <= 4) { - shadowRadius = 1; - textColor = 0xff734a08; - wrapWidth = 34; - dy = 13; - textSize = 10; - } else if (subType >= 4 && subType <= 6) { - shadowRadius = 1; - textColor = 0xff734a08; - wrapWidth = 34; - dy = 13; - textSize = 10; - } - } - } - break; - case MapRenderingTypes.ADMINISTRATIVE: { - shadowRadius = 1; - switch (subType) { - case 11: { - if (zoom >= 14 && zoom < 16) { - textColor = 0xFF000000; - textSize = 8; - } else if (zoom >= 16) { - textColor = 0xFF777777; - textSize = 11; - } - } - break; - case 8: - case 9: { - if (zoom >= 12 && zoom < 15) { - textColor = 0xFF000000; - textSize = 9; - } else if (zoom >= 15) { - textColor = 0xFF777777; - textSize = 12; - } - } - break; - case 10: { - if (zoom >= 12 && zoom < 14) { - textColor = 0xFF000000; - textSize = 10; - } else if (zoom >= 14) { - textColor = 0xFF777777; - textSize = 13; - } - } - break; - case 19: { - if (zoom >= 8) { - textColor = 0xFF99cc99; - wrapWidth = 14; - if (zoom < 10) { - bold = true; - textSize = 8; - } else if (zoom < 12) { - bold = true; - textSize = 11; - } - } - } - break; - case 12: { - if (zoom >= 10) { - textColor = 0xFF000000; - textSize = 9; - } - } - break; - case 7: { - wrapWidth = 20; - if (zoom >= 9 && zoom < 11) { - textColor = 0xFF000000; - textSize = 8; - } else if (zoom >= 11 && zoom < 14) { - textColor = 0xFF000000; - textSize = 11; - } else if (zoom >= 14) { - textColor = 0xFF777777; - textSize = 13; - } - } - break; - case 6: { - wrapWidth = 20; - textColor = 0xFF000000; - if (zoom >= 6 && zoom < 9) { - textSize = 8; - } else if (zoom >= 9 && zoom < 11) { - textSize = 11; - } else if (zoom >= 11 && zoom <= 14) { - textSize = 14; - } - } - break; - case 42: { - wrapWidth = 20; - textColor = 0xff9d6c9d; - if (zoom >= 2 && zoom < 4) { - textSize = 8; - } else if (zoom >= 4 && zoom < 7) { - textSize = 10; - } - } - break; - case 43: - case 44: { - wrapWidth = 20; - textColor = 0xff9d6c9d; - if (zoom >= 4 && zoom < 8) { - textSize = 9; - } else if (zoom >= 7 && zoom < 9) { - textSize = 11; - } - } - break; - case 33: { - if (zoom >= 17) { - textSize = 9; - textColor = 0xff444444; - } - } - break; - } - } - break; - } - rc.textColor = textColor; - rc.textSize = textSize; - rc.textMinDistance = textMinDistance; - rc.showTextOnPath = showTextOnPath; - rc.textShield = textShield; - rc.textWrapWidth = wrapWidth; - rc.textHaloRadius = shadowRadius; - rc.textBold = bold; - rc.textDy = dy; - return name; } diff --git a/OsmAnd/src/net/osmand/render/RenderingIcons.java b/OsmAnd/src/net/osmand/render/RenderingIcons.java index 9e54913a58..a6a5d266c1 100644 --- a/OsmAnd/src/net/osmand/render/RenderingIcons.java +++ b/OsmAnd/src/net/osmand/render/RenderingIcons.java @@ -9,14 +9,14 @@ public class RenderingIcons { private static Map icons = new LinkedHashMap(); - public Map getIcons(){ + public static Map getIcons(){ if(icons.isEmpty()){ initIcons(); } return icons; } - private void initIcons() { + 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("alpinehut", R.drawable.h_alpinehut); //$NON-NLS-1$ diff --git a/OsmAnd/src/net/osmand/render/TextRenderer.java b/OsmAnd/src/net/osmand/render/TextRenderer.java new file mode 100644 index 0000000000..a9c746d9ea --- /dev/null +++ b/OsmAnd/src/net/osmand/render/TextRenderer.java @@ -0,0 +1,764 @@ +package net.osmand.render; + +import net.osmand.R; +import net.osmand.osm.MapRenderingTypes; +import net.osmand.render.OsmandRenderer.RenderingContext; +import android.graphics.Color; + +public class TextRenderer { + + private static int[] trunkShields = new int[]{R.drawable.tru_shield1, R.drawable.tru_shield2, R.drawable.tru_shield3, + R.drawable.tru_shield4, R.drawable.tru_shield5, R.drawable.tru_shield6, R.drawable.tru_shield7,}; + private static int[] motorShields = new int[]{R.drawable.mot_shield1, R.drawable.mot_shield2, R.drawable.mot_shield3, + R.drawable.mot_shield4, R.drawable.mot_shield5, R.drawable.mot_shield6, R.drawable.mot_shield7,}; + private static int[] primaryShields = new int[]{R.drawable.pri_shield1, R.drawable.pri_shield2, R.drawable.pri_shield3, + R.drawable.pri_shield4, R.drawable.pri_shield5, R.drawable.pri_shield6, R.drawable.pri_shield7,}; + private static int[] secondaryShields = new int[]{R.drawable.sec_shield1, R.drawable.sec_shield2, R.drawable.sec_shield3, + R.drawable.sec_shield4, R.drawable.sec_shield5, R.drawable.sec_shield6, R.drawable.sec_shield7,}; + private static int[] tertiaryShields = new int[]{R.drawable.ter_shield1, R.drawable.ter_shield2, R.drawable.ter_shield3, + R.drawable.ter_shield4, R.drawable.ter_shield5, R.drawable.ter_shield6, R.drawable.ter_shield7,}; + + public static String renderObjectText(String name, int subType, int type, int zoom, boolean point, RenderingContext rc) { + if(name == null || name.length() == 0){ + return null; + } + int textSize = 0; + int textColor = 0; + int wrapWidth = 0; + int shadowRadius = 0; + int textMinDistance = 0; + int textShield = 0; + int dy = 0; + boolean bold = false; + boolean showTextOnPath = false; + + switch (type) { + case MapRenderingTypes.HIGHWAY : { + if(name.charAt(0) == MapRenderingTypes.REF_CHAR){ + name = name.substring(1); + for(int k = 0; k < name.length(); k++){ + if(name.charAt(k) == MapRenderingTypes.REF_CHAR){ + if(k < name.length() - 1 && zoom > 14){ + rc.showAnotherText = name.substring(k + 1); + } + name = name.substring(0, k); + break; + } + } + if(rc.showAnotherText != null && zoom >= 16){ + break; + } + if(name.length() > 6){ + name = name.substring(0, 6); + } + int len = name.length(); + if(len == 0){ + // skip it + } else { + textSize = 10; + textColor = Color.WHITE; + bold = true; + textMinDistance = 70; + // spacing = 750 + if (subType == MapRenderingTypes.PL_HW_TRUNK) { + textShield = trunkShields[len - 1]; + if(zoom < 10){ + textSize = 0; + } + } else if (subType == MapRenderingTypes.PL_HW_MOTORWAY) { + textShield = motorShields[len - 1]; + if(zoom < 10){ + textSize = 0; + } + } else if (subType == MapRenderingTypes.PL_HW_PRIMARY) { + textShield = primaryShields[len - 1]; + if(zoom < 11){ + textSize = 0; + } + } else if (subType == MapRenderingTypes.PL_HW_SECONDARY) { + if(zoom < 14){ + textSize = 0; + } + textShield = secondaryShields[len - 1]; + } else if (subType == MapRenderingTypes.PL_HW_TERTIARY) { + if(zoom < 15){ + textSize = 0; + } + textShield = tertiaryShields[len - 1]; + } else { + if(zoom < 16){ + textSize = 0; + } else { + showTextOnPath = true; + textColor = Color.BLACK; + textSize = 10; + textMinDistance = 40; + shadowRadius = 1; + // spacing = 750; + } + } + } + } else { + if(subType == MapRenderingTypes.PL_HW_TRUNK || subType == MapRenderingTypes.PL_HW_PRIMARY + || subType == MapRenderingTypes.PL_HW_SECONDARY){ + textColor = Color.BLACK; + showTextOnPath = true; + if(zoom == 13 && type != MapRenderingTypes.PL_HW_SECONDARY){ + textSize = 8; + } else if(zoom == 14){ + textSize = 9; + } else if(zoom > 14 && zoom < 17){ + textSize = 10; + } else if(zoom > 16){ + textSize = 12; + } + } else if(subType == MapRenderingTypes.PL_HW_TERTIARY || subType == MapRenderingTypes.PL_HW_RESIDENTIAL + || subType == MapRenderingTypes.PL_HW_UNCLASSIFIED || subType == MapRenderingTypes.PL_HW_SERVICE){ + textColor = Color.BLACK; + showTextOnPath = true; + if(zoom < 15){ + textSize = 0; + } else if(zoom < 17){ + textSize = 9; + } else { + textSize = 11; + } + } else if(subType < 32){ + // highway subtype + if(zoom >= 16){ + textColor = Color.BLACK; + showTextOnPath = true; + textSize = 9; + } + } else if(subType == 40){ + // bus stop + if(zoom >= 17){ + textMinDistance = 20; + textColor = Color.BLACK; + textSize = 9; + wrapWidth = 25; + dy = 11; + } + } + } + } break; + case MapRenderingTypes.WATERWAY : { + if (subType == 1) { + if (zoom >= 15 /* && !tunnel */) { + showTextOnPath = true; + textSize = 8; + shadowRadius = 1; + textColor = 0xff6699cc; + } + } else if (subType == 2 || subType == 4) { + if (zoom >= 12 /* && !tunnel */) { + textSize = 9; + showTextOnPath = true; + shadowRadius = 1; + textColor = 0xff6699cc; + textMinDistance = 70; + } + } else if (subType == 5 || subType == 6) { + if (zoom >= 15 /* && !tunnel */) { + textSize = 8; + showTextOnPath = true; + shadowRadius = 1; + textColor = 0xff6699cc; + } + } else if (subType == 12) { + if(zoom >= 15){ + textColor = Color.BLACK; + textSize = 8; + shadowRadius = 1; + } + } else if (subType == 8) { + if (zoom >= 15) { + shadowRadius = 1; + textSize = 9; + textColor = 0xff0066ff; + wrapWidth = 70; + dy = 10; + } + } + } + break; + case MapRenderingTypes.AEROWAY: { + textColor = 0xff6692da; + shadowRadius = 1; + if(name.charAt(0) == MapRenderingTypes.REF_CHAR){ + name = name.substring(1); + } + if (subType == 7 || subType == 8) { + if (zoom >= 15) { + showTextOnPath = true; + textSize = 10; + textColor = 0xff333333; + textMinDistance = 50; + shadowRadius = 1; + // spacing = 750; + } + } else if (subType == 10) { + // airport + if (zoom >= 10 && zoom <= 12) { + textSize = 9; + dy = -12; + bold = true; + + } + } else if (subType == 1) { + // aerodrome + if (zoom >= 10 && zoom <= 12) { + textSize = 8; + dy = -12; + } + } else if (subType == 12) { + if (zoom >= 17) { + textSize = 10; + textColor = 0xffaa66cc; + shadowRadius = 1; + wrapWidth = 10; + } + } + } + break; + case MapRenderingTypes.AERIALWAY: { + if (subType == 7) { + if (zoom >= 14) { + textColor = 0xff6666ff; + shadowRadius = 1; + if (zoom == 14) { + dy = -7; + textSize = 8; + + } else { + dy = -10; + textSize = 10; + } + } + + } + } + break; + case MapRenderingTypes.RAILWAY: { + if (zoom >= 14) { + textColor = 0xff6666ff; + shadowRadius = 1; + if (subType == 13) { + bold = true; + if (zoom == 14) { + dy = -8; + textSize = 9; + } else { + dy = -10; + textSize = 11; + } + } else if (subType == 22 || subType == 23) { + if (zoom == 14) { + dy = -7; + textSize = 8; + } else { + dy = -10; + textSize = 10; + } + } + } + } + break; + case MapRenderingTypes.EMERGENCY: { + if (zoom >= 17) { + if (subType == 10) { + dy = 9; + textColor = 0xff734a08; + wrapWidth = 30; + textSize = 10; + } + } + } + break; + case MapRenderingTypes.NATURAL: { + if (subType == 23) { + if (zoom >= 12) { + shadowRadius = 2; + textColor = 0xff00000; + textSize = 10; + wrapWidth = 10; + } + } else if (subType == 13) { + if (zoom >= 14) { + shadowRadius = 1; + textColor = 0xff654321; + textSize = 9; + dy = 5; + } + } else if (subType == 3) { + if (zoom >= 15) { + shadowRadius = 1; + textColor = 0xff654321; + textSize = 10; + dy = 9; + wrapWidth = 20; + } + } else if (subType == 21) { + if (zoom >= 12) { + textSize = 10; + shadowRadius = 1; + wrapWidth = 20; + textColor = 0xff6699cc; + } + } else if (subType == 2) { + if (zoom >= 14) { + textSize = 10; + shadowRadius = 1; + wrapWidth = 20; + textColor = 0xff6699cc; + } + } else if (subType == 17) { + if (zoom >= 16) { + textSize = 8; + shadowRadius = 1; + dy = 10; + wrapWidth = 20; + textColor = 0xff6699cc; + } + } + } + break; + case MapRenderingTypes.LANDUSE: { + if (zoom >= 15) { + if (subType == 22) { + textSize = 10; + shadowRadius = 1; + wrapWidth = 20; + textColor = 0xff6699cc; + } else if (point) { + textColor = 0xff000000; + shadowRadius = 2; + wrapWidth = 10; + textSize = 9; + } + } + } + break; + case MapRenderingTypes.TOURISM: { + if (subType == 9) { + if (zoom >= 16) { + textColor = 0xff6699cc; + shadowRadius = 1; + dy = 15; + textSize = 9; + } + } else if (subType == 12 || subType == 13 || subType == 14) { + if (zoom >= 17) { + textColor = 0xff0066ff; + shadowRadius = 1; + dy = 14; + textSize = 10; + } + } else if (subType == 11) { + if (zoom >= 17) { + textColor = 0xff0066ff; + shadowRadius = 1; + dy = 13; + textSize = 8; + } + } else if (subType == 4) { + if (zoom >= 17) { + shadowRadius = 1; + textSize = 10; + textColor = 0xff0066ff; + wrapWidth = 70; + dy = 15; + } + } else if (subType == 5) { + if (zoom >= 17) { + shadowRadius = 1; + textSize = 10; + textColor = 0xff0066ff; + wrapWidth = 70; + dy = 19; + } + } else if (subType == 7) { + if (zoom >= 15) { + textColor = 0xff734a08; + textSize = 9; + wrapWidth = 30; + shadowRadius = 1; + } + } else if (subType == 15) { + if (zoom >= 17) { + textColor = 0xff734a08; + textSize = 10; + dy = 12; + shadowRadius = 1; + } + } + } + break; + case MapRenderingTypes.LEISURE: { + if (subType == 8) { + if (zoom >= 15) { + textColor = Color.BLUE; + textSize = 9; + wrapWidth = 30; + shadowRadius = 1; + } + } else if ((zoom >= 15 && !point) || zoom >= 17) { + textColor = 0xff000000; + shadowRadius = 2; + wrapWidth = 15; + textSize = 9; + } + } + break; + case MapRenderingTypes.HISTORIC: { + if (zoom >= 17) { + if (subType == 6) { + shadowRadius = 1; + textColor = 0xff654321; + textSize = 9; + dy = 12; + wrapWidth = 20; + } + } + } + break; + case MapRenderingTypes.AMENITY_TRANSPORTATION: { + if (zoom >= 17) { + if (subType == 1) { + dy = 9; + textColor = 0xff0066ff; + textSize = 9; + wrapWidth = 34; + } else if (subType == 4 || subType == 18) { + textColor = 0xff0066ff; + shadowRadius = 1; + dy = 13; + textSize = 9; + } + } + } + break; + case MapRenderingTypes.AMENITY_EDUCATION: { + if (subType == 4) { + if (zoom >= 17) { + dy = 12; + textColor = 0xff734a08; + bold = true; + textSize = 10; + } + } else if (subType == 5) { + if (zoom >= 15) { + textColor = 0xff000033; + bold = true; + textSize = 9; + wrapWidth = 16; + } + } else if (subType == 1 || subType == 2 || subType == 3) { + if (zoom >= 16) { + textColor = 0xff000033; + if(subType != 1){ + dy = 11; + } + textSize = 9; + wrapWidth = 16; + } + } + } + break; + case MapRenderingTypes.MAN_MADE: { + if (subType == 1 || subType == 5) { + if(zoom >= 16){ + textColor = 0xff444444; + textSize = 9; + if(zoom >= 17){ + textSize = 11; + if(zoom >= 18){ + textSize = 15; + } + } + wrapWidth = 16; + } + } else if (subType == 17) { + if (zoom >= 15) { + textColor = 0xff000033; + textSize = 9; + shadowRadius = 2; + dy = 16; + wrapWidth = 12; + } + } else if (subType == 27) { + if (zoom >= 17) { + textSize = 9; + textColor = 0xff734a08; + dy = 12; + shadowRadius = 1; + wrapWidth = 20; + } + } + } + break; + case MapRenderingTypes.AMENITY_ENTERTAINMENT: { + if (zoom >= 17) { + textSize = 9; + textColor = 0xff734a08; + dy = 12; + shadowRadius = 1; + wrapWidth = 15; + } + } break; + case MapRenderingTypes.AMENITY_FINANCE: { + if (subType == 2) { + if (zoom >= 17) { + shadowRadius = 1; + textSize = 9; + textColor = Color.BLACK; + dy = 14; + } + } + } + break; + case MapRenderingTypes.MILITARY: { + if (subType == 4) { + if (zoom >= 12) { + bold = true; + textSize = 9; + shadowRadius = 1; + wrapWidth = 10; + textColor = 0xffffc0cb; + } + } + } + break; + case MapRenderingTypes.SHOP: { + if (subType == 42 || subType == 13 || subType == 16 || subType == 19 || subType == 31 || subType == 48) { + if (zoom >= 17) { + textColor = 0xff993399; + textSize = 8; + dy = 13; + shadowRadius = 1; + wrapWidth = 14; + } + } else if (subType == 65 || subType == 17) { + if (zoom >= 16) { + textSize = 9; + textColor = 0xff993399; + dy = 13; + shadowRadius = 1; + wrapWidth = 20; + } + } + + } + break; + case MapRenderingTypes.AMENITY_HEALTHCARE: { + if (subType == 2) { + if (zoom >= 16) { + textSize = 8; + textColor = 0xffda0092; + dy = 12; + shadowRadius = 2; + wrapWidth = 24; + } + } else if (subType == 1) { + if (zoom >= 17) { + textSize = 8; + textColor = 0xffda0092; + dy = 11; + shadowRadius = 1; + wrapWidth = 12; + } + } + + } + break; + case MapRenderingTypes.AMENITY_OTHER: { + if (subType == 10) { + if (zoom >= 17) { + wrapWidth = 30; + textSize = 10; + textColor = 0xff734a08; + dy = 10; + } + } else if (subType == 26) { + if (zoom >= 17) { + wrapWidth = 30; + textSize = 11; + textColor = 0x000033; + dy = 10; + } + } else if (subType == 16) { + if (zoom >= 16) { + textColor = 0xff6699cc; + shadowRadius = 1; + dy = 15; + textSize = 9; + } + } else if (subType == 7) { + if (zoom >= 17) { + textColor = 0xff0066ff; + shadowRadius = 1; + wrapWidth = 20; + dy = 8; + textSize = 9; + } + } else if (subType == 13) { + if (zoom >= 17) { + textColor = 0xff734a08; + textSize = 10; + shadowRadius = 1; + wrapWidth = 20; + dy = 16; + } + } else if (subType == 2) { + if (zoom >= 16) { + textColor = 0xff660033; + textSize = 10; + shadowRadius = 2; + wrapWidth = 10; + } + } + } + break; + case MapRenderingTypes.AMENITY_SUSTENANCE: { + if (zoom >= 17) { + if (subType >= 1 && subType <= 4) { + shadowRadius = 1; + textColor = 0xff734a08; + wrapWidth = 34; + dy = 13; + textSize = 10; + } else if (subType >= 4 && subType <= 6) { + shadowRadius = 1; + textColor = 0xff734a08; + wrapWidth = 34; + dy = 13; + textSize = 10; + } + } + } + break; + case MapRenderingTypes.ADMINISTRATIVE: { + shadowRadius = 1; + switch (subType) { + case 11: { + if (zoom >= 14 && zoom < 16) { + textColor = 0xFF000000; + textSize = 8; + } else if (zoom >= 16) { + textColor = 0xFF777777; + textSize = 11; + } + } + break; + case 8: + case 9: { + if (zoom >= 12 && zoom < 15) { + textColor = 0xFF000000; + textSize = 9; + } else if (zoom >= 15) { + textColor = 0xFF777777; + textSize = 12; + } + } + break; + case 10: { + if (zoom >= 12 && zoom < 14) { + textColor = 0xFF000000; + textSize = 10; + } else if (zoom >= 14) { + textColor = 0xFF777777; + textSize = 13; + } + } + break; + case 19: { + if (zoom >= 8) { + textColor = 0xFF99cc99; + wrapWidth = 14; + if (zoom < 10) { + bold = true; + textSize = 8; + } else if (zoom < 12) { + bold = true; + textSize = 11; + } + } + } + break; + case 12: { + if (zoom >= 10) { + textColor = 0xFF000000; + textSize = 9; + } + } + break; + case 7: { + wrapWidth = 20; + if (zoom >= 9 && zoom < 11) { + textColor = 0xFF000000; + textSize = 8; + } else if (zoom >= 11 && zoom < 14) { + textColor = 0xFF000000; + textSize = 11; + } else if (zoom >= 14) { + textColor = 0xFF777777; + textSize = 13; + } + } + break; + case 6: { + wrapWidth = 20; + textColor = 0xFF000000; + if (zoom >= 6 && zoom < 9) { + textSize = 8; + } else if (zoom >= 9 && zoom < 11) { + textSize = 11; + } else if (zoom >= 11 && zoom <= 14) { + textSize = 14; + } + } + break; + case 42: { + wrapWidth = 20; + textColor = 0xff9d6c9d; + if (zoom >= 2 && zoom < 4) { + textSize = 8; + } else if (zoom >= 4 && zoom < 7) { + textSize = 10; + } + } + break; + case 43: + case 44: { + wrapWidth = 20; + textColor = 0xff9d6c9d; + if (zoom >= 4 && zoom < 8) { + textSize = 9; + } else if (zoom >= 7 && zoom < 9) { + textSize = 11; + } + } + break; + case 33: { + if (zoom >= 17) { + textSize = 9; + textColor = 0xff444444; + } + } + break; + } + } + break; + } + rc.textColor = textColor; + rc.textSize = textSize; + rc.textMinDistance = textMinDistance; + rc.showTextOnPath = showTextOnPath; + rc.textShield = textShield; + rc.textWrapWidth = wrapWidth; + rc.textHaloRadius = shadowRadius; + rc.textBold = bold; + rc.textDy = dy; + return name; + } +}