start ThemeBuilder api
This commit is contained in:
parent
494e553ac0
commit
b879830045
125
vtm/src/org/oscim/theme/ThemeBuilder.java
Normal file
125
vtm/src/org/oscim/theme/ThemeBuilder.java
Normal file
@ -0,0 +1,125 @@
|
||||
package org.oscim.theme;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.Tag;
|
||||
import org.oscim.core.TagSet;
|
||||
import org.oscim.theme.rule.Element;
|
||||
import org.oscim.theme.rule.Rule;
|
||||
import org.oscim.theme.rule.RuleBuilder;
|
||||
import org.oscim.theme.rule.Selector;
|
||||
import org.oscim.theme.rule.SingleKeyMatcher;
|
||||
import org.oscim.theme.rule.SingleValueMatcher;
|
||||
import org.oscim.theme.styles.Area;
|
||||
import org.oscim.theme.styles.Line;
|
||||
import org.oscim.theme.styles.RenderStyle;
|
||||
|
||||
public class ThemeBuilder {
|
||||
protected final ArrayList<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>();
|
||||
protected final Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
|
||||
|
||||
protected int mLevels = 0;
|
||||
protected int mMapBackground = 0xffffffff;
|
||||
protected float mBaseTextSize = 1;
|
||||
|
||||
protected RuleBuilder mCurrentRule;
|
||||
|
||||
protected RenderTheme build() {
|
||||
|
||||
Rule[] rules = new Rule[mRulesList.size()];
|
||||
for (int i = 0, n = rules.length; i < n; i++)
|
||||
rules[i] = mRulesList.get(i).onComplete();
|
||||
|
||||
RenderTheme theme = new RenderTheme(mMapBackground, mBaseTextSize, rules, mLevels);
|
||||
|
||||
mRulesList.clear();
|
||||
mRuleStack.clear();
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
public ThemeBuilder pop() {
|
||||
|
||||
mRuleStack.pop();
|
||||
if (mRuleStack.empty()) {
|
||||
mRulesList.add(mCurrentRule);
|
||||
} else {
|
||||
mCurrentRule = mRuleStack.peek();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ThemeBuilder push(RuleBuilder rule) {
|
||||
if (!mRuleStack.empty())
|
||||
mCurrentRule.addSubRule(rule);
|
||||
|
||||
mCurrentRule = rule;
|
||||
mRuleStack.push(mCurrentRule);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ThemeBuilder push(String key, String value) {
|
||||
RuleBuilder b = new RuleBuilder(true, Element.ANY, ~0, 0,
|
||||
key == null ? null : new SingleKeyMatcher(key),
|
||||
value == null ? null : new SingleValueMatcher(value));
|
||||
push(b);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RuleBuilder pushParse(String keys, String values) {
|
||||
|
||||
return RuleBuilder.create(mRuleStack, keys, values)
|
||||
.zoom(~0)
|
||||
.element(Element.ANY);
|
||||
}
|
||||
|
||||
public ThemeBuilder addStyle(RenderStyle style) {
|
||||
mCurrentRule.addStyle(style);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ThemeBuilder b = new ThemeBuilder();
|
||||
|
||||
//b.pushParse("highway", "residential|primary|motorway")
|
||||
|
||||
b.push(RuleBuilder.get().select(Selector.FIRST))
|
||||
.push("highway", null)
|
||||
.addStyle(new Line(1, 1, 1))
|
||||
.pop()
|
||||
|
||||
.push(RuleBuilder.get().select(Selector.WHEN_MATCHED))
|
||||
.addStyle(new Area(1, 1))
|
||||
.pop()
|
||||
.pop();
|
||||
|
||||
RenderTheme t = b.build();
|
||||
TagSet tags = new TagSet(1);
|
||||
RenderStyle[] styles;
|
||||
|
||||
tags.add(new Tag("ahighway", "residential"));
|
||||
styles = t.matchElement(GeometryType.LINE, tags, 1);
|
||||
System.out.println(Arrays.deepToString(styles));
|
||||
|
||||
// tags.clear();
|
||||
// tags.add(new Tag("highway", "motorway"));
|
||||
// styles = t.matchElement(GeometryType.LINE, tags, 1);
|
||||
// out.println(styles);
|
||||
//
|
||||
// tags.clear();
|
||||
// tags.add(new Tag("sup", "wup"));
|
||||
// styles = t.matchElement(GeometryType.LINE, tags, 1);
|
||||
// out.println(styles);
|
||||
//
|
||||
// tags.clear();
|
||||
// tags.add(new Tag("highway", "motorway"));
|
||||
// styles = t.matchElement(GeometryType.LINE, tags, 1);
|
||||
// out.println(styles);
|
||||
|
||||
}
|
||||
}
|
@ -863,13 +863,13 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
return new Extrusion(level, colorSide, colorTop, colorLine, defaultHeight);
|
||||
}
|
||||
|
||||
private static void validateNonNegative(String name, float value) {
|
||||
public static void validateNonNegative(String name, float value) {
|
||||
if (value < 0)
|
||||
throw new ThemeException(name + " must not be negative: "
|
||||
+ value);
|
||||
}
|
||||
|
||||
private static void validateExists(String name, Object obj, String elementName) {
|
||||
public static void validateExists(String name, Object obj, String elementName) {
|
||||
if (obj == null)
|
||||
throw new ThemeException("missing attribute " + name
|
||||
+ " for element: " + elementName);
|
||||
|
@ -47,13 +47,13 @@ public class RuleBuilder {
|
||||
this.valueMatcher = valueMatcher;
|
||||
}
|
||||
|
||||
private static RuleBuilder createRule(Stack<RuleBuilder> ruleStack, int element, String keys,
|
||||
String values, byte zoomMin, byte zoomMax, int selector) {
|
||||
public RuleBuilder(boolean positive, AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
|
||||
this.positiveRule = positive;
|
||||
this.keyMatcher = keyMatcher;
|
||||
this.valueMatcher = valueMatcher;
|
||||
}
|
||||
|
||||
// zoom-level bitmask
|
||||
int zoom = 0;
|
||||
for (int z = zoomMin; z <= zoomMax && z < 32; z++)
|
||||
zoom |= (1 << z);
|
||||
public static RuleBuilder create(Stack<RuleBuilder> ruleStack, String keys, String values) {
|
||||
|
||||
List<String> keyList = null, valueList = null;
|
||||
boolean negativeRule = false;
|
||||
@ -90,16 +90,16 @@ public class RuleBuilder {
|
||||
|
||||
if (negativeRule) {
|
||||
AttributeMatcher m = new NegativeMatcher(keyList, valueList, false);
|
||||
return new RuleBuilder(false, element, zoom, selector, m, null);
|
||||
return new RuleBuilder(false, m, null);
|
||||
} else if (exclusionRule) {
|
||||
AttributeMatcher m = new NegativeMatcher(keyList, valueList, true);
|
||||
return new RuleBuilder(false, element, zoom, selector, m, null);
|
||||
return new RuleBuilder(false, m, null);
|
||||
}
|
||||
|
||||
keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
|
||||
}
|
||||
|
||||
return new RuleBuilder(true, element, zoom, selector, keyMatcher, valueMatcher);
|
||||
return new RuleBuilder(true, keyMatcher, valueMatcher);
|
||||
}
|
||||
|
||||
private static AttributeMatcher getKeyMatcher(List<String> keyList) {
|
||||
@ -137,11 +137,9 @@ public class RuleBuilder {
|
||||
}
|
||||
|
||||
private static void validate(byte zoomMin, byte zoomMax) {
|
||||
if (zoomMin < 0)
|
||||
throw new ThemeException("zoom-min must not be negative: " + zoomMin);
|
||||
else if (zoomMax < 0)
|
||||
throw new ThemeException("zoom-max must not be negative: " + zoomMax);
|
||||
else if (zoomMin > zoomMax)
|
||||
XmlThemeBuilder.validateNonNegative("zoom-min", zoomMin);
|
||||
XmlThemeBuilder.validateNonNegative("zoom-max", zoomMax);
|
||||
if (zoomMin > zoomMax)
|
||||
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
||||
}
|
||||
|
||||
@ -196,7 +194,20 @@ public class RuleBuilder {
|
||||
|
||||
validate(zoomMin, zoomMax);
|
||||
|
||||
return createRule(ruleStack, element, keys, values, zoomMin, zoomMax, selector);
|
||||
RuleBuilder b = create(ruleStack, keys, values);
|
||||
b.setZoom(zoomMin, zoomMax);
|
||||
b.element = element;
|
||||
b.selector = selector;
|
||||
return b;
|
||||
}
|
||||
|
||||
public RuleBuilder setZoom(byte zoomMin, byte zoomMax) {
|
||||
// zoom-level bitmask
|
||||
zoom = 0;
|
||||
for (int z = zoomMin; z <= zoomMax && z < 32; z++)
|
||||
zoom |= (1 << z);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Rule onComplete() {
|
||||
@ -233,4 +244,28 @@ public class RuleBuilder {
|
||||
subRules.add(rule);
|
||||
}
|
||||
|
||||
RuleBuilder(boolean positive) {
|
||||
this.positiveRule = positive;
|
||||
this.element = Element.ANY;
|
||||
this.zoom = ~0;
|
||||
}
|
||||
|
||||
public static RuleBuilder get() {
|
||||
return new RuleBuilder(true);
|
||||
}
|
||||
|
||||
public RuleBuilder select(int selector) {
|
||||
this.selector = selector;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RuleBuilder zoom(int zoom) {
|
||||
this.zoom = zoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RuleBuilder element(int element) {
|
||||
this.element = element;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ package org.oscim.theme.rule;
|
||||
|
||||
import org.oscim.core.Tag;
|
||||
|
||||
class SingleKeyMatcher implements AttributeMatcher {
|
||||
public class SingleKeyMatcher implements AttributeMatcher {
|
||||
private final String mKey;
|
||||
|
||||
SingleKeyMatcher(String key) {
|
||||
public SingleKeyMatcher(String key) {
|
||||
mKey = key.intern();
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,10 @@ package org.oscim.theme.rule;
|
||||
|
||||
import org.oscim.core.Tag;
|
||||
|
||||
class SingleValueMatcher implements AttributeMatcher {
|
||||
public class SingleValueMatcher implements AttributeMatcher {
|
||||
private final String mValue;
|
||||
|
||||
SingleValueMatcher(String value) {
|
||||
public SingleValueMatcher(String value) {
|
||||
mValue = value.intern();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user