348 lines
9.1 KiB
Java
348 lines
9.1 KiB
Java
package net.osmand.render;
|
|
|
|
|
|
import net.osmand.PlatformUtil;
|
|
import net.osmand.binary.BinaryMapDataObject;
|
|
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
|
|
public class RenderingRuleProperty {
|
|
private final static Log log = PlatformUtil.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;
|
|
|
|
// Fields C++
|
|
protected final int type;
|
|
protected final boolean input;
|
|
protected final String attrName;
|
|
|
|
protected int id = -1;
|
|
|
|
// use for custom rendering rule properties
|
|
protected String name;
|
|
protected String description;
|
|
protected String defaultValueDescription;
|
|
protected String[] possibleValues;
|
|
protected String category;
|
|
|
|
protected 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 void setId(int id) {
|
|
if (this.id != -1) {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
this.id = id;
|
|
}
|
|
|
|
public int getId() {
|
|
return id;
|
|
}
|
|
|
|
public String getAttrName() {
|
|
return attrName;
|
|
}
|
|
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
public String getCategory() {
|
|
return category;
|
|
}
|
|
|
|
public String getDescription() {
|
|
return description;
|
|
}
|
|
|
|
public String getDefaultValueDescription() {
|
|
return defaultValueDescription;
|
|
}
|
|
|
|
protected void setName(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
protected void setDescription(String description) {
|
|
this.description = description;
|
|
}
|
|
|
|
public void setDefaultValueDescription(String defaultValueDescription) {
|
|
this.defaultValueDescription = defaultValueDescription;
|
|
}
|
|
|
|
public void setCategory(String category) {
|
|
this.category = category;
|
|
}
|
|
|
|
protected void setPossibleValues(String[] possibleValues) {
|
|
this.possibleValues = possibleValues;
|
|
}
|
|
|
|
public String[] getPossibleValues() {
|
|
if (isBoolean()) {
|
|
return new String[] { "true", "false" };
|
|
}
|
|
return possibleValues;
|
|
}
|
|
|
|
public boolean isBoolean() {
|
|
return type == BOOLEAN_TYPE;
|
|
}
|
|
|
|
public boolean isFloat() {
|
|
return type == FLOAT_TYPE;
|
|
}
|
|
|
|
public boolean isInt() {
|
|
return type == INT_TYPE;
|
|
}
|
|
|
|
public boolean isColor() {
|
|
return type == COLOR_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, RenderingRuleSearchRequest req){
|
|
if(!isIntParse() || !input){
|
|
return false;
|
|
}
|
|
return ruleValue == renderingProperty;
|
|
}
|
|
|
|
public boolean accept(float ruleValue, float renderingProperty, RenderingRuleSearchRequest req){
|
|
if(type != FLOAT_TYPE || !input){
|
|
return false;
|
|
}
|
|
return ruleValue == renderingProperty;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "#RenderingRuleProperty " + getAttrName();
|
|
}
|
|
|
|
|
|
public int parseIntValue(String value){
|
|
if(type == INT_TYPE){
|
|
try {
|
|
int colon = value.indexOf(':');
|
|
if(colon != -1) {
|
|
int c = 0;
|
|
if(colon > 0) {
|
|
c += (int) Float.parseFloat(value.substring(0, colon));
|
|
}
|
|
c += (int) Float.parseFloat(value.substring(colon + 1));
|
|
return c;
|
|
}
|
|
return (int) Float.parseFloat(value);
|
|
} catch (NumberFormatException e) {
|
|
log.error("Rendering parse " + value + " in " + attrName);
|
|
}
|
|
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 parseColor(value);
|
|
} catch (RuntimeException e) {
|
|
log.error("Rendering parse " + e.getMessage() + " in " + attrName);
|
|
}
|
|
return -1;
|
|
} else if(type == FLOAT_TYPE){
|
|
// parse as complex value
|
|
try {
|
|
int colon = value.indexOf(':');
|
|
if(colon != -1) {
|
|
return (int) Float.parseFloat(value.substring(colon + 1));
|
|
}
|
|
return 0;
|
|
} catch (NumberFormatException e) {
|
|
log.error("Rendering parse " + value + " in " + attrName);
|
|
}
|
|
return -1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public float parseFloatValue(String value){
|
|
if(type == FLOAT_TYPE){
|
|
try {
|
|
int colon = value.indexOf(':');
|
|
if(colon != -1) {
|
|
if(colon > 0) {
|
|
return Float.parseFloat(value.substring(0, colon));
|
|
}
|
|
return 0;
|
|
}
|
|
return Float.parseFloat(value);
|
|
} catch (NumberFormatException e) {
|
|
log.error("Rendering parse " + value + " in " + attrName);
|
|
}
|
|
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, RenderingRuleSearchRequest req) {
|
|
if(!isIntParse() || !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, RenderingRuleSearchRequest req) {
|
|
if(!isIntParse() || !input){
|
|
return false;
|
|
}
|
|
return ruleValue <= renderingProperty;
|
|
}
|
|
};
|
|
}
|
|
|
|
public static RenderingRuleProperty createAdditionalStringProperty(String name) {
|
|
return new RenderingRuleProperty(name, STRING_TYPE, true) {
|
|
@Override
|
|
public boolean accept(int ruleValue, int renderingProperty, RenderingRuleSearchRequest req) {
|
|
BinaryMapDataObject obj = req.getObject();
|
|
String val = req.getStorage().getStringValue(ruleValue);
|
|
if (obj == null) {
|
|
int vl = req.getIntPropertyValue(this);
|
|
if(vl == -1) {
|
|
return false;
|
|
}
|
|
String val2 = req.getStorage().getStringValue(vl);
|
|
return val != null && (val.equals(val2) ||
|
|
(val2.indexOf(';') != -1 && val2.contains(val+';')));
|
|
}
|
|
|
|
int k = val.indexOf('=');
|
|
if (k != -1) {
|
|
String ts = val.substring(0, k);
|
|
String vs = val.substring(k + 1);
|
|
Integer ruleInd = req.getObject().getMapIndex().getRule(ts, vs);
|
|
if (ruleInd != null) {
|
|
if (req.getObject().containsAdditionalType(ruleInd)) {
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
String ts = val;
|
|
int[] additionalTypes = obj.getAdditionalTypes();
|
|
for (int i = 0; i < additionalTypes.length; i++) {
|
|
TagValuePair vp = obj.getMapIndex().decodeType(additionalTypes[i]);
|
|
if (vp != null && ts.equals(vp.tag)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 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$
|
|
}
|
|
|
|
|
|
|
|
}
|