Initial implementation

This commit is contained in:
Victor Shcherb 2011-10-17 23:20:43 +02:00
parent 279f0b1575
commit 44a6a749b0
6 changed files with 1850 additions and 2 deletions

View file

@ -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<String, RenderingRuleProperty> createDefaultRenderingRuleProperties() {
Map<String, RenderingRuleProperty> map = new LinkedHashMap<String, RenderingRuleProperty>();
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<String, RenderingRuleProperty> map, RenderingRuleProperty p) {
map.put(p.getAttrName(), p);
}
}

View file

@ -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<RenderingRuleProperty> properties;
private int[] intProperties;
private float[] floatProperties;
private final RenderingRulesStorage storage;
public RenderingRule(Map<String, String> attributes, RenderingRulesStorage storage){
this.storage = storage;
this.properties = new ArrayList<RenderingRuleProperty>();
process(attributes);
}
private void process(Map<String, String> attributes) {
properties = new ArrayList<RenderingRuleProperty>(attributes.size());
intProperties = new int[attributes.size()];
int i = 0;
Iterator<Entry<String, String>> it = attributes.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> 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++;
}
}
}

View file

@ -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<String> 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$
}
}

View file

@ -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<String> dictionary = new ArrayList<String>();
Map<String, Integer> dictionaryMap = new LinkedHashMap<String, Integer>();
final Map<String, RenderingRuleProperty> 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<Object> stack = new Stack<Object>();
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();
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -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;