From 44a6a749b06a50fd84dc04f22f5e92bd3bfd3d48 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 17 Oct 2011 23:20:43 +0200 Subject: [PATCH] Initial implementation --- .../DefaultRenderingRuleProperties.java | 97 ++ .../src/net/osmand/render/RenderingRule.java | 49 + .../osmand/render/RenderingRuleProperty.java | 203 +++ .../osmand/render/RenderingRulesStorage.java | 166 ++ .../net/osmand/render/new_default.render.xml | 1333 +++++++++++++++++ .../plus/activities/DownloadFileHelper.java | 4 +- 6 files changed, 1850 insertions(+), 2 deletions(-) create mode 100644 DataExtractionOSM/src/net/osmand/render/DefaultRenderingRuleProperties.java create mode 100644 DataExtractionOSM/src/net/osmand/render/RenderingRule.java create mode 100644 DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java create mode 100644 DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java create mode 100644 DataExtractionOSM/src/net/osmand/render/new_default.render.xml diff --git a/DataExtractionOSM/src/net/osmand/render/DefaultRenderingRuleProperties.java b/DataExtractionOSM/src/net/osmand/render/DefaultRenderingRuleProperties.java new file mode 100644 index 0000000000..812175f8e6 --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/render/DefaultRenderingRuleProperties.java @@ -0,0 +1,97 @@ +package net.osmand.render; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class DefaultRenderingRuleProperties { + + private static final String SHADOW_RADIUS = "shadowRadius"; + private static final String SHADOW_COLOR = "shadowColor"; + private static final String SHADER = "shader"; + private static final String CAP_3 = "cap_3"; + private static final String CAP_2 = "cap_2"; + private static final String CAP = "cap"; + private static final String PATH_EFFECT_3 = "pathEffect_3"; + private static final String PATH_EFFECT_2 = "pathEffect_2"; + private static final String PATH_EFFECT = "pathEffect"; + private static final String STROKE_WIDTH_3 = "strokeWidth_3"; + private static final String STROKE_WIDTH_2 = "strokeWidth_2"; + private static final String STROKE_WIDTH = "strokeWidth"; + private static final String COLOR_3 = "color_3"; + private static final String COLOR = "color"; + private static final String COLOR_2 = "color_2"; + private static final String TEXT_BOLD = "textBold"; + private static final String TEXT_ORDER = "textOrder"; + private static final String TEXT_MIN_DISTANCE = "textMinDistance"; + private static final String TEXT_ON_PATH = "textOnPath"; + private static final String ICON = "icon"; + private static final String LAYER = "layer"; + private static final String ORDER = "order"; + private static final String ORDER_TYPE = "order_type"; + public static final String TAG = "tag"; + public static final String VALUE = "value"; + public static final String MINZOOM = "minzoom"; + public static final String MAXZOOM = "maxzoom"; + public static final String NIGHT_MODE = "nightMode"; + public static final String TEXT_DY = "textDy"; + public static final String TEXT_SIZE = "textSize"; + public static final String TEXT_COLOR = "textColor"; + public static final String TEXT_HALO_RADIUS = "textHaloRadius"; + public static final String TEXT_WRAP_WIDTH = "textWrapWidth"; + + public static Map createDefaultRenderingRuleProperties() { + Map map = new LinkedHashMap(); + registerRule(map, RenderingRuleProperty.createInputStringProperty(TAG)); + registerRule(map, RenderingRuleProperty.createInputStringProperty(VALUE)); + registerRule(map, RenderingRuleProperty.createInputGreaterIntProperty(MINZOOM)); + registerRule(map, RenderingRuleProperty.createInputLessIntProperty(MAXZOOM)); + registerRule(map, RenderingRuleProperty.createInputBooleanProperty(NIGHT_MODE)); + registerRule(map, RenderingRuleProperty.createInputIntProperty(LAYER)); + + // order - no sense to make it float + registerRule(map, RenderingRuleProperty.createOutputIntProperty(ORDER)); + registerRule(map, RenderingRuleProperty.createInputStringProperty(ORDER)); + + // text properties + registerRule(map, RenderingRuleProperty.createOutputIntProperty(TEXT_WRAP_WIDTH)); + registerRule(map, RenderingRuleProperty.createOutputIntProperty(TEXT_DY)); + registerRule(map, RenderingRuleProperty.createOutputIntProperty(TEXT_HALO_RADIUS)); + registerRule(map, RenderingRuleProperty.createOutputIntProperty(TEXT_SIZE)); + registerRule(map, RenderingRuleProperty.createOutputIntProperty(TEXT_ORDER)); + registerRule(map, RenderingRuleProperty.createOutputIntProperty(TEXT_MIN_DISTANCE)); + + registerRule(map, RenderingRuleProperty.createOutputColorProperty(TEXT_COLOR)); + + registerRule(map, RenderingRuleProperty.createOutputBooleanProperty(TEXT_BOLD)); + registerRule(map, RenderingRuleProperty.createOutputBooleanProperty(TEXT_ON_PATH)); + + // point + registerRule(map, RenderingRuleProperty.createOutputStringProperty(ICON)); + + // polygon/way + registerRule(map, RenderingRuleProperty.createOutputColorProperty(COLOR)); + registerRule(map, RenderingRuleProperty.createOutputColorProperty(COLOR_2)); + registerRule(map, RenderingRuleProperty.createOutputColorProperty(COLOR_3)); + registerRule(map, RenderingRuleProperty.createOutputFloatProperty(STROKE_WIDTH)); + registerRule(map, RenderingRuleProperty.createOutputFloatProperty(STROKE_WIDTH_2)); + registerRule(map, RenderingRuleProperty.createOutputFloatProperty(STROKE_WIDTH_3)); + + registerRule(map, RenderingRuleProperty.createOutputStringProperty(PATH_EFFECT)); + registerRule(map, RenderingRuleProperty.createOutputStringProperty(PATH_EFFECT_2)); + registerRule(map, RenderingRuleProperty.createOutputStringProperty(PATH_EFFECT_3)); + registerRule(map, RenderingRuleProperty.createOutputStringProperty(CAP)); + registerRule(map, RenderingRuleProperty.createOutputStringProperty(CAP_2)); + registerRule(map, RenderingRuleProperty.createOutputStringProperty(CAP_3)); + registerRule(map, RenderingRuleProperty.createOutputStringProperty(SHADER)); + + registerRule(map, RenderingRuleProperty.createOutputColorProperty(SHADOW_COLOR)); + registerRule(map, RenderingRuleProperty.createOutputIntProperty(SHADOW_RADIUS)); + + + return map; + } + + private static void registerRule(Map map, RenderingRuleProperty p) { + map.put(p.getAttrName(), p); + } +} diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRule.java b/DataExtractionOSM/src/net/osmand/render/RenderingRule.java new file mode 100644 index 0000000000..b5a609b1dc --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRule.java @@ -0,0 +1,49 @@ +package net.osmand.render; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +public class RenderingRule { + + private List properties; + private int[] intProperties; + private float[] floatProperties; + + private final RenderingRulesStorage storage; + + public RenderingRule(Map attributes, RenderingRulesStorage storage){ + this.storage = storage; + this.properties = new ArrayList(); + process(attributes); + } + + private void process(Map attributes) { + properties = new ArrayList(attributes.size()); + intProperties = new int[attributes.size()]; + int i = 0; + Iterator> it = attributes.entrySet().iterator(); + while (it.hasNext()) { + Entry e = it.next(); + RenderingRuleProperty property = storage.getProperty(e.getKey()); + if (property != null) { + properties.add(property); + if (property.isString()) { + intProperties[i] = storage.getDictionaryValue(e.getValue()); + } else if (property.isFloat()) { + if (floatProperties == null) { + // lazy creates + floatProperties = new float[attributes.size()]; + } + floatProperties[i] = property.parseFloatValue(e.getValue()); + } else { + intProperties[i] = property.parseIntValue(e.getValue()); + } + } + i++; + } + } + +} diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java b/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java new file mode 100644 index 0000000000..1be645d100 --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java @@ -0,0 +1,203 @@ +package net.osmand.render; + +import java.util.List; + +import net.osmand.LogUtil; + +import org.apache.commons.logging.Log; + + +public class RenderingRuleProperty { + private final static Log log = LogUtil.getLog(RenderingRuleProperty.class); + + private final static int INT_TYPE = 1; + private final static int FLOAT_TYPE = 2; + private final static int STRING_TYPE = 3; + private final static int COLOR_TYPE = 4; + private final static int BOOLEAN_TYPE = 5; + + public static final int TRUE_VALUE = 1; + public static final int FALSE_VALUE = 0; + + protected final int type; + protected final boolean input; + protected final String attrName; + + // use for custom rendering rule properties + protected String name; + protected String description; + protected List possibleValues; + + private RenderingRuleProperty(String attrName, int type, boolean input){ + this.attrName = attrName; + this.type = type; + this.input = input; + } + + public boolean isInputProperty() { + return input; + } + + public boolean isOutputProperty() { + return !input; + } + + public String getAttrName() { + return attrName; + } + + public boolean isFloat() { + return type == FLOAT_TYPE; + } + + public boolean isInt() { + return type == INT_TYPE; + } + + public boolean isString() { + return type == STRING_TYPE; + } + + public boolean isIntParse(){ + return type == INT_TYPE || type == STRING_TYPE || type == COLOR_TYPE || type == BOOLEAN_TYPE; + } + + public boolean accept(int ruleValue, int renderingProperty){ + if(!isIntParse() || !input){ + return false; + } + return ruleValue == renderingProperty; + } + + public boolean accept(float ruleValue, float renderingProperty){ + if(type != FLOAT_TYPE || !input){ + return false; + } + return ruleValue == renderingProperty; + } + + public int parseIntValue(String value){ + if(type == INT_TYPE){ + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + log.error("Rendering parse " + value); + } + return -1; + } else if(type == BOOLEAN_TYPE){ + return Boolean.parseBoolean(value) ? TRUE_VALUE : FALSE_VALUE; + } else if(type == STRING_TYPE){ + // requires dictionary to parse + return -1; + } else if(type == COLOR_TYPE){ + try { + return Integer.parseInt(value); + } catch (RuntimeException e) { + log.error("Rendering parse " + e.getMessage()); + } + return -1; + } else { + return -1; + } + } + + public float parseFloatValue(String value){ + if(type == FLOAT_TYPE){ + try { + return Float.parseFloat(value); + } catch (NumberFormatException e) { + log.error("Rendering parse " + value); + } + return -1; + } else { + return -1; + } + } + + + + public static RenderingRuleProperty createOutputIntProperty(String name){ + return new RenderingRuleProperty(name, INT_TYPE, false); + } + + public static RenderingRuleProperty createOutputBooleanProperty(String name){ + return new RenderingRuleProperty(name, BOOLEAN_TYPE, false); + } + + public static RenderingRuleProperty createInputBooleanProperty(String name){ + return new RenderingRuleProperty(name, BOOLEAN_TYPE, true); + } + + public static RenderingRuleProperty createOutputFloatProperty(String name){ + return new RenderingRuleProperty(name, FLOAT_TYPE, false); + } + + public static RenderingRuleProperty createOutputStringProperty(String name){ + return new RenderingRuleProperty(name, STRING_TYPE, false); + } + + public static RenderingRuleProperty createInputIntProperty(String name){ + return new RenderingRuleProperty(name, INT_TYPE, true); + } + + public static RenderingRuleProperty createInputColorProperty(String name){ + return new RenderingRuleProperty(name, COLOR_TYPE, true); + } + + public static RenderingRuleProperty createOutputColorProperty(String name){ + return new RenderingRuleProperty(name, COLOR_TYPE, false); + } + + public static RenderingRuleProperty createInputStringProperty(String name){ + return new RenderingRuleProperty(name, STRING_TYPE, true); + } + + public static RenderingRuleProperty createInputLessIntProperty(String name){ + return new RenderingRuleProperty(name, INT_TYPE, true) { + @Override + public boolean accept(int ruleValue, int renderingProperty) { + if((type != INT_TYPE || type != STRING_TYPE) && input){ + return false; + } + return ruleValue >= renderingProperty; + } + }; + } + + public static RenderingRuleProperty createInputGreaterIntProperty(String name){ + return new RenderingRuleProperty(name, INT_TYPE, true) { + @Override + public boolean accept(int ruleValue, int renderingProperty) { + if(!isIntParse() || !input){ + return false; + } + return ruleValue <= renderingProperty; + } + }; + } + + /** + * Parse the color string, and return the corresponding color-int. + * If the string cannot be parsed, throws an IllegalArgumentException + * exception. Supported formats are: + * #RRGGBB + * #AARRGGBB + * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', + * 'yellow', 'lightgray', 'darkgray' + */ + public static int parseColor(String colorString) { + if (colorString.charAt(0) == '#') { + // Use a long to avoid rollovers on #ffXXXXXX + long color = Long.parseLong(colorString.substring(1), 16); + if (colorString.length() == 7) { + // Set the alpha value + color |= 0x00000000ff000000; + } else if (colorString.length() != 9) { + throw new IllegalArgumentException("Unknown color" + colorString); //$NON-NLS-1$ + } + return (int)color; + } + throw new IllegalArgumentException("Unknown color" + colorString); //$NON-NLS-1$ + } + +} diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java b/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java new file mode 100644 index 0000000000..fa089f4242 --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java @@ -0,0 +1,166 @@ +package net.osmand.render; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.apache.commons.logging.Log; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import net.osmand.LogUtil; +import net.osmand.osm.MapRenderingTypes; +import net.osmand.render.OsmandRenderingRulesParser.EffectAttributes; +import net.osmand.render.OsmandRenderingRulesParser.FilterState; +import net.osmand.render.OsmandRenderingRulesParser.RenderingRuleVisitor; +import net.osmand.render.OsmandRenderingRulesParser.SwitchState; +import net.osmand.render.OsmandRenderingRulesParser.TextAttributes; + +public class RenderingRulesStorage { + + private final static Log log = LogUtil.getLog(RenderingRulesStorage.class); + + public final static int POINT_STATE = 1; + public final static int LINE_STATE = 2; + public final static int POLYGON_STATE = 3; + public final static int TEXT_STATE = 4; + public final static int ORDER_STATE = 5; + + List dictionary = new ArrayList(); + Map dictionaryMap = new LinkedHashMap(); + final Map properties; + + private int bgColor = 0; + private int bgNightColor = 0; + private String renderingName; + private String depends; + + + public RenderingRulesStorage(){ + properties = DefaultRenderingRuleProperties.createDefaultRenderingRuleProperties(); + } + + public int getDictionaryValue(String val) { + if(dictionaryMap.containsKey(val)){ + return dictionaryMap.get(val); + } + int nextInd = dictionaryMap.size(); + dictionaryMap.put(val, nextInd); + dictionary.add(val); + return nextInd; + + } + + public String getStringValue(int i){ + return dictionary.get(i); + } + + public RenderingRuleProperty getProperty(String name){ + return properties.get(name); + } + + public String getName() { + return renderingName; + } + + public int getBgColor() { + return bgColor; + } + + public int getBgNightColor() { + return bgNightColor; + } + + + public void parseRulesFromXmlInputStream(InputStream is) throws SAXException, IOException { + try { + final SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); + saxParser.parse(is, new RenderingRulesHandler(saxParser)); + } catch (ParserConfigurationException e) { + throw new SAXException(e); + } + } + + public static String colorToString(int color) { + if ((0xFF000000 & color) == 0xFF000000) { + return "#" + Integer.toHexString(color & 0x00FFFFFF); //$NON-NLS-1$ + } else { + return "#" + Integer.toHexString(color); //$NON-NLS-1$ + } + } + + private class RenderingRulesHandler extends DefaultHandler { + private final SAXParser parser; + private int state; + + Stack stack = new Stack(); + + + public RenderingRulesHandler(SAXParser parser){ + this.parser = parser; + } + + @Override + public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { + name = parser.isNamespaceAware() ? localName : name; + if("filter".equals(name)){ //$NON-NLS-1$ + FilterState st = parseFilterAttributes(attributes); + stack.push(st); + } else if("order".equals(name)){ //$NON-NLS-1$ + state = ORDER_STATE; + } else if("text".equals(name)){ //$NON-NLS-1$ + state = TEXT_STATE; + } else if("point".equals(name)){ //$NON-NLS-1$ + state = POINT_STATE; + } else if("line".equals(name)){ //$NON-NLS-1$ + state = LINE_STATE; + } else if("polygon".equals(name)){ //$NON-NLS-1$ + state = POLYGON_STATE; + } else if("switch".equals(name)){ //$NON-NLS-1$ + SwitchState st = new SwitchState(); + stack.push(st); + } 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$ + String dc = attributes.getValue("defaultColor"); + int defaultColor = 0; + if(dc != null && dc.length() > 0){ + bgColor = RenderingRuleProperty.parseColor(dc); + } + String dnc = attributes.getValue("defaultNightColor"); + int defautNightColor = defaultColor; + if(dnc != null && dnc.length() > 0){ + bgNightColor = RenderingRuleProperty.parseColor(dnc); + } + renderingName = attributes.getValue("name"); + depends = attributes.getValue("depends"); + } else { + log.warn("Unknown tag" + name); //$NON-NLS-1$ + } + } + + @Override + public void endElement(String uri, String localName, String name) throws SAXException { + name = parser.isNamespaceAware() ? localName : name; + if ("filter".equals(name)) { //$NON-NLS-1$ + + } else if("switch".equals(name)){ //$NON-NLS-1$ + stack.pop(); + } + } + + + + } +} diff --git a/DataExtractionOSM/src/net/osmand/render/new_default.render.xml b/DataExtractionOSM/src/net/osmand/render/new_default.render.xml new file mode 100644 index 0000000000..8e7fa3d33c --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/render/new_default.render.xml @@ -0,0 +1,1333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/DownloadFileHelper.java b/OsmAnd/src/net/osmand/plus/activities/DownloadFileHelper.java index ce08ea1d7c..e3e10f3e15 100644 --- a/OsmAnd/src/net/osmand/plus/activities/DownloadFileHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/DownloadFileHelper.java @@ -160,7 +160,7 @@ public class DownloadFileHelper { fs = toIndex; first = false; } else { - String name = entry.getName(); + String name = entry.getAttrName(); // small simplification int ind = name.lastIndexOf('_'); if (ind > 0) { @@ -174,7 +174,7 @@ public class DownloadFileHelper { toIndex = fs; } } else { - fs = new File(fileToUnZip, entry.getName()); + fs = new File(fileToUnZip, entry.getAttrName()); } out = new FileOutputStream(fs); int read;