From 191e94c670d494dce6c30cf03cb47f9f83d88b29 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Mon, 31 Mar 2014 14:58:36 +0200 Subject: [PATCH] merge Positive/NegativeRule into Rule --- vtm/src/org/oscim/theme/RenderTheme.java | 2 +- vtm/src/org/oscim/theme/rule/Closed.java | 25 -- vtm/src/org/oscim/theme/rule/Element.java | 24 -- .../org/oscim/theme/rule/NegativeRule.java | 78 ------ .../org/oscim/theme/rule/PositiveRule.java | 167 ------------ vtm/src/org/oscim/theme/rule/Rule.java | 248 +++++++++++++++--- vtm/src/org/oscim/theme/rule/RuleBuilder.java | 44 +++- vtm/src/org/oscim/theme/rule/Selector.java | 8 - 8 files changed, 252 insertions(+), 344 deletions(-) delete mode 100644 vtm/src/org/oscim/theme/rule/Closed.java delete mode 100644 vtm/src/org/oscim/theme/rule/Element.java delete mode 100644 vtm/src/org/oscim/theme/rule/NegativeRule.java delete mode 100644 vtm/src/org/oscim/theme/rule/PositiveRule.java delete mode 100644 vtm/src/org/oscim/theme/rule/Selector.java 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; -}