Initial implementation
This commit is contained in:
parent
279f0b1575
commit
44a6a749b0
6 changed files with 1850 additions and 2 deletions
|
@ -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);
|
||||
}
|
||||
}
|
49
DataExtractionOSM/src/net/osmand/render/RenderingRule.java
Normal file
49
DataExtractionOSM/src/net/osmand/render/RenderingRule.java
Normal 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++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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$
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
1333
DataExtractionOSM/src/net/osmand/render/new_default.render.xml
Normal file
1333
DataExtractionOSM/src/net/osmand/render/new_default.render.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue