diff --git a/vtm/src/org/oscim/theme/RenderTheme.java b/vtm/src/org/oscim/theme/RenderTheme.java
index f951d4c5..e224ecf1 100644
--- a/vtm/src/org/oscim/theme/RenderTheme.java
+++ b/vtm/src/org/oscim/theme/RenderTheme.java
@@ -22,8 +22,8 @@ import java.util.List;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.TagSet;
-import org.oscim.theme.rule.Element;
import org.oscim.theme.rule.Rule;
+import org.oscim.theme.rule.Rule.Element;
import org.oscim.theme.rule.Rule.RuleVisitor;
import org.oscim.theme.styles.RenderStyle;
import org.oscim.utils.LRUCache;
diff --git a/vtm/src/org/oscim/theme/rule/Closed.java b/vtm/src/org/oscim/theme/rule/Closed.java
deleted file mode 100644
index 2a99bee9..00000000
--- a/vtm/src/org/oscim/theme/rule/Closed.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-public final class Closed {
- public static final int NO = 1 << 0;
- public static final int YES = 1 << 1;
- public static final int ANY = NO | YES;
-
-}
diff --git a/vtm/src/org/oscim/theme/rule/Element.java b/vtm/src/org/oscim/theme/rule/Element.java
deleted file mode 100644
index 2a91a24d..00000000
--- a/vtm/src/org/oscim/theme/rule/Element.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-public final class Element {
- public static final int NODE = 1 << 0;
- public static final int LINE = 1 << 1;
- public static final int POLY = 1 << 2;
- public static final int WAY = LINE | POLY;
- public static final int ANY = NODE | WAY;
-}
diff --git a/vtm/src/org/oscim/theme/rule/NegativeRule.java b/vtm/src/org/oscim/theme/rule/NegativeRule.java
deleted file mode 100644
index 9454a009..00000000
--- a/vtm/src/org/oscim/theme/rule/NegativeRule.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import org.oscim.core.Tag;
-import org.oscim.theme.rule.RuleBuilder.RuleType;
-import org.oscim.theme.styles.RenderStyle;
-
-class NegativeRule extends Rule {
-
- public final String[] keys;
- public final String[] values;
-
- /* (-) 'exclusive negation' matches when either KEY is not present
- * or KEY is present and any VALUE is NOT present
- *
- * (\) 'except negation' matches when KEY is present
- * none items of VALUE is present (TODO).
- * (can be emulated by ...)
- *
- * (~) 'non-exclusive negation' matches when either KEY is not present
- * or KEY is present and any VALUE is present */
-
- public final boolean exclusive;
-
- NegativeRule(RuleType type, int element, int zoom, int selector,
- String[] keys, String[] values,
- Rule[] subRules, RenderStyle[] styles) {
- super(element, zoom, selector, subRules, styles);
-
- for (int i = 0; i < keys.length; i++)
- keys[i] = keys[i].intern();
-
- for (int i = 0; i < values.length; i++)
- values[i] = values[i].intern();
-
- this.keys = keys;
- this.values = values;
- this.exclusive = type == RuleType.EXCLUDE;
- }
-
- @Override
- public boolean matchesTags(Tag[] tags) {
- if (keyListDoesNotContainKeys(tags))
- return true;
-
- for (Tag tag : tags)
- for (String value : values)
- if (value == tag.value)
- return !exclusive;
-
- return exclusive;
- }
-
- private boolean keyListDoesNotContainKeys(Tag[] tags) {
- for (Tag tag : tags)
- for (String key : keys)
- if (key == tag.key)
- return false;
-
- return true;
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/PositiveRule.java b/vtm/src/org/oscim/theme/rule/PositiveRule.java
deleted file mode 100644
index 59ecb111..00000000
--- a/vtm/src/org/oscim/theme/rule/PositiveRule.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import org.oscim.core.Tag;
-import org.oscim.theme.styles.RenderStyle;
-
-class PositiveRule {
-
- static class PositiveRuleK extends Rule {
- private final String mKey;
-
- PositiveRuleK(int element, int zoom, int selector, String key,
- Rule[] subRules, RenderStyle[] styles) {
-
- super(element, zoom, selector, subRules, styles);
- mKey = key;
- }
-
- @Override
- boolean matchesTags(Tag[] tags) {
- for (Tag tag : tags)
- if (mKey == tag.key)
- return true;
-
- return false;
- }
- }
-
- static class PositiveRuleV extends Rule {
- private final String mValue;
-
- PositiveRuleV(int element, int zoom, int selector, String value,
- Rule[] subRules, RenderStyle[] styles) {
-
- super(element, zoom, selector, subRules, styles);
- mValue = value;
- }
-
- @Override
- boolean matchesTags(Tag[] tags) {
- for (Tag tag : tags)
- if (mValue == tag.value)
- return true;
-
- return false;
- }
- }
-
- static class PositiveRuleKV extends Rule {
- private final String mKey;
- private final String mValue;
-
- PositiveRuleKV(int element, int zoom, int selector, String key, String value,
- Rule[] subRules, RenderStyle[] styles) {
-
- super(element, zoom, selector, subRules, styles);
- mKey = key;
- mValue = value;
- }
-
- @Override
- boolean matchesTags(Tag[] tags) {
- for (Tag tag : tags)
- if (mKey == tag.key)
- return (mValue == tag.value);
-
- return false;
- }
- }
-
- static class PositiveRuleMultiKV extends Rule {
- private final String mKeys[];
- private final String mValues[];
-
- PositiveRuleMultiKV(int element, int zoom, int selector, String keys[], String values[],
- Rule[] subRules, RenderStyle[] styles) {
-
- super(element, zoom, selector, subRules, styles);
- if (keys.length == 0) {
- mKeys = null;
- } else {
- for (int i = 0; i < keys.length; i++)
- keys[i] = keys[i].intern();
- mKeys = keys;
- }
-
- if (values.length == 0) {
- mValues = null;
- } else {
- for (int i = 0; i < values.length; i++)
- values[i] = values[i].intern();
- mValues = values;
- }
- }
-
- @Override
- boolean matchesTags(Tag[] tags) {
- if (mKeys == null) {
- for (Tag tag : tags) {
- for (String value : mValues) {
- if (value == tag.value)
- return true;
- }
- }
- return false;
- }
-
- for (Tag tag : tags)
- for (String key : mKeys) {
- if (key == tag.key) {
- if (mValues == null)
- return true;
-
- for (String value : mValues) {
- if (value == tag.value)
- return true;
- }
- }
- }
- return false;
- }
- }
-
- public static Rule create(int element, int zoom, int selector,
- String[] keys, String values[], Rule[] subRules, RenderStyle[] styles) {
- int numKeys = keys.length;
- int numVals = values.length;
-
- if (numKeys == 0 && numVals == 0)
- return new Rule(element, zoom, selector, subRules, styles);
-
- for (int i = 0; i < numVals; i++)
- values[i] = values[i].intern();
-
- for (int i = 0; i < numKeys; i++)
- keys[i] = keys[i].intern();
-
- if (numKeys == 1 && numKeys == 0) {
- return new PositiveRuleK(element, zoom, selector, keys[0], subRules, styles);
- }
-
- if (numKeys == 0 && numVals == 1) {
- return new PositiveRuleV(element, zoom, selector, values[0], subRules, styles);
- }
-
- if (numKeys == 1 && numVals == 1)
- return new PositiveRuleKV(element, zoom, selector, keys[0], values[0], subRules, styles);
-
- return new PositiveRuleMultiKV(element, zoom, selector, keys, values, subRules, styles);
-
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/Rule.java b/vtm/src/org/oscim/theme/rule/Rule.java
index 347792ca..8e1e3d09 100644
--- a/vtm/src/org/oscim/theme/rule/Rule.java
+++ b/vtm/src/org/oscim/theme/rule/Rule.java
@@ -19,9 +19,30 @@ package org.oscim.theme.rule;
import java.util.List;
import org.oscim.core.Tag;
+import org.oscim.theme.rule.RuleBuilder.RuleType;
import org.oscim.theme.styles.RenderStyle;
public class Rule {
+ public final class Element {
+ public static final int NODE = 1 << 0;
+ public static final int LINE = 1 << 1;
+ public static final int POLY = 1 << 2;
+ public static final int WAY = LINE | POLY;
+ public static final int ANY = NODE | WAY;
+ }
+
+ public final class Closed {
+ public static final int NO = 1 << 0;
+ public static final int YES = 1 << 1;
+ public static final int ANY = NO | YES;
+ }
+
+ public final class Selector {
+ public static final int ANY = 0;
+ public static final int FIRST = 1 << 0;
+ public static final int WHEN_MATCHED = 1 << 1;
+ }
+
public final static RenderStyle[] EMPTY_STYLE = new RenderStyle[0];
public final static Rule[] EMPTY_RULES = new Rule[0];
@@ -49,49 +70,45 @@ public class Rule {
}
public boolean matchElement(int type, Tag[] tags, int zoomLevel, List result) {
+ if (((element & type) == 0) || ((zoom & zoomLevel) == 0) || !matchesTags(tags))
+ return false;
- if (((element & type) != 0) && ((zoom & zoomLevel) != 0) && (matchesTags(tags))) {
- boolean matched = false;
+ boolean matched = false;
+ if (subRules != EMPTY_RULES) {
+ if (selectFirstMatch) {
+ /* only add first matching rule and when-matched rules iff a
+ * previous rule matched */
+ for (Rule r : subRules) {
+ /* continue if matched xor selectWhenMatch */
+ if (matched ^ r.selectWhenMatched)
+ continue;
- if (subRules != EMPTY_RULES) {
- if (selectFirstMatch) {
- /* only add first matching rule and when-matched rules iff a
- * previous rule matched */
- for (Rule r : subRules) {
- /* continue if matched xor selectWhenMatch */
- if (matched ^ r.selectWhenMatched)
- continue;
+ if (r.matchElement(type, tags, zoomLevel, result))
+ matched = true;
+ }
+ } else {
+ /* add all rules and when-matched rules iff a previous rule
+ * matched */
+ for (Rule r : subRules) {
+ if (r.selectWhenMatched && !matched)
+ continue;
- if (r.matchElement(type, tags, zoomLevel, result))
- matched = true;
- }
- } else {
- /* add all rules and when-matched rules iff a previous rule
- * matched */
- for (Rule r : subRules) {
- if (r.selectWhenMatched && !matched)
- continue;
-
- if (r.matchElement(type, tags, zoomLevel, result))
- matched = true;
- }
+ if (r.matchElement(type, tags, zoomLevel, result))
+ matched = true;
}
}
-
- if (styles == EMPTY_STYLE)
- /* matched if styles where added */
- return matched;
-
- /* add instructions for this rule */
- for (RenderStyle ri : styles)
- result.add(ri);
-
- /* this rule did not match */
- return true;
}
- /* this rule did not match */
- return false;
+ if (styles == EMPTY_STYLE)
+ /* matched if styles where added */
+ return matched;
+
+ /* add instructions for this rule */
+ for (RenderStyle ri : styles)
+ result.add(ri);
+
+ /* this rule did match */
+ return true;
}
public void dispose() {
@@ -152,4 +169,163 @@ public class Rule {
public void apply(RuleVisitor v) {
v.apply(this);
}
+
+ static class PositiveRuleK extends Rule {
+ private final String mKey;
+
+ PositiveRuleK(int element, int zoom, int selector, String key,
+ Rule[] subRules, RenderStyle[] styles) {
+
+ super(element, zoom, selector, subRules, styles);
+ mKey = key;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ for (Tag tag : tags)
+ if (mKey == tag.key)
+ return true;
+
+ return false;
+ }
+ }
+
+ static class PositiveRuleV extends Rule {
+ private final String mValue;
+
+ PositiveRuleV(int element, int zoom, int selector, String value,
+ Rule[] subRules, RenderStyle[] styles) {
+ super(element, zoom, selector, subRules, styles);
+ mValue = value;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ for (Tag tag : tags)
+ if (mValue == tag.value)
+ return true;
+
+ return false;
+ }
+ }
+
+ static class PositiveRuleKV extends Rule {
+ private final String mKey;
+ private final String mValue;
+
+ PositiveRuleKV(int element, int zoom, int selector,
+ String key, String value,
+ Rule[] subRules, RenderStyle[] styles) {
+ super(element, zoom, selector, subRules, styles);
+ mKey = key;
+ mValue = value;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ for (Tag tag : tags)
+ if (mKey == tag.key)
+ return (mValue == tag.value);
+
+ return false;
+ }
+ }
+
+ static class PositiveRuleMultiKV extends Rule {
+ private final String mKeys[];
+ private final String mValues[];
+
+ PositiveRuleMultiKV(int element, int zoom, int selector,
+ String keys[], String values[],
+ Rule[] subRules, RenderStyle[] styles) {
+
+ super(element, zoom, selector, subRules, styles);
+ if (keys.length == 0)
+ mKeys = null;
+ else
+ mKeys = keys;
+
+ if (values.length == 0)
+ mValues = null;
+ else
+ mValues = values;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ if (mKeys == null) {
+ for (Tag tag : tags) {
+ for (String value : mValues) {
+ if (value == tag.value)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ for (Tag tag : tags)
+ for (String key : mKeys) {
+ if (key == tag.key) {
+ if (mValues == null)
+ return true;
+
+ for (String value : mValues) {
+ if (value == tag.value)
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ static class NegativeRule extends Rule {
+ public final String[] keys;
+ public final String[] values;
+
+ /* (-) 'exclusive negation' matches when either KEY is not present
+ * or KEY is present and any VALUE is NOT present
+ *
+ * (\) 'except negation' matches when KEY is present
+ * none items of VALUE is present (TODO).
+ * (can be emulated by ...)
+ *
+ * (~) 'non-exclusive negation' matches when either KEY is not present
+ * or KEY is present and any VALUE is present */
+
+ public final boolean exclusive;
+
+ NegativeRule(RuleType type, int element, int zoom, int selector,
+ String[] keys, String[] values,
+ Rule[] subRules, RenderStyle[] styles) {
+ super(element, zoom, selector, subRules, styles);
+
+ this.keys = keys;
+ this.values = values;
+ this.exclusive = type == RuleType.EXCLUDE;
+ }
+
+ @Override
+ public boolean matchesTags(Tag[] tags) {
+ if (!containsKeys(tags))
+ return true;
+
+ for (Tag tag : tags)
+ for (String value : values)
+ if (value == tag.value)
+ return !exclusive;
+
+ return exclusive;
+ }
+
+ private boolean containsKeys(Tag[] tags) {
+ for (Tag tag : tags)
+ for (String key : keys)
+ if (key == tag.key)
+ return true;
+
+ return false;
+ }
+ }
+
}
diff --git a/vtm/src/org/oscim/theme/rule/RuleBuilder.java b/vtm/src/org/oscim/theme/rule/RuleBuilder.java
index 968679e5..20db3776 100644
--- a/vtm/src/org/oscim/theme/rule/RuleBuilder.java
+++ b/vtm/src/org/oscim/theme/rule/RuleBuilder.java
@@ -5,7 +5,15 @@ import java.util.Stack;
import org.oscim.theme.IRenderTheme.ThemeException;
import org.oscim.theme.XmlThemeBuilder;
+import org.oscim.theme.rule.Rule.Closed;
+import org.oscim.theme.rule.Rule.Element;
+import org.oscim.theme.rule.Rule.NegativeRule;
+import org.oscim.theme.rule.Rule.PositiveRuleK;
+import org.oscim.theme.rule.Rule.PositiveRuleKV;
+import org.oscim.theme.rule.Rule.PositiveRuleMultiKV;
+import org.oscim.theme.rule.Rule.PositiveRuleV;
import org.oscim.theme.styles.RenderStyle;
+import org.oscim.theme.styles.RenderStyle.StyleBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
@@ -93,9 +101,8 @@ public class RuleBuilder {
}
if (type != RuleType.POSITIVE) {
- if (keyList == null || keyList.length == 0) {
+ if (keyList == null || keyList.length == 0)
throw new ThemeException("negative rule requires key");
- }
}
return new RuleBuilder(type, keyList, valueList);
@@ -191,12 +198,39 @@ public class RuleBuilder {
rules[i] = subRules.get(i).onComplete();
}
+ int numKeys = keys.length;
+ int numVals = values.length;
+
+ if (numKeys == 0 && numVals == 0)
+ return new Rule(element, zoom, selector, rules, styles);
+
+ for (int i = 0; i < numVals; i++)
+ values[i] = values[i].intern();
+
+ for (int i = 0; i < numKeys; i++)
+ keys[i] = keys[i].intern();
+
if (type != RuleType.POSITIVE)
return new NegativeRule(type, element, zoom, selector,
keys, values, rules, styles);
- else
- return PositiveRule.create(element, zoom, selector,
- keys, values, rules, styles);
+
+ if (numKeys == 1 && numKeys == 0) {
+ return new PositiveRuleK(element, zoom, selector, keys[0],
+ rules, styles);
+ }
+
+ if (numKeys == 0 && numVals == 1) {
+ return new PositiveRuleV(element, zoom, selector, values[0],
+ rules, styles);
+ }
+
+ if (numKeys == 1 && numVals == 1)
+ return new PositiveRuleKV(element, zoom, selector,
+ keys[0], values[0], rules, styles);
+
+ return new PositiveRuleMultiKV(element, zoom, selector,
+ keys, values, rules, styles);
+
}
public void addStyle(RenderStyle style) {
diff --git a/vtm/src/org/oscim/theme/rule/Selector.java b/vtm/src/org/oscim/theme/rule/Selector.java
deleted file mode 100644
index 9ba12caf..00000000
--- a/vtm/src/org/oscim/theme/rule/Selector.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.oscim.theme.rule;
-
-public class Selector {
-
- public static final int ANY = 0;
- public static final int FIRST = 1 << 0;
- public static final int WHEN_MATCHED = 1 << 1;
-}