simplify rendertheme 'closed' and 'element' matching
This commit is contained in:
@@ -16,7 +16,7 @@ package org.mapsforge.android.rendertheme;
|
|||||||
|
|
||||||
import org.mapsforge.core.Tag;
|
import org.mapsforge.core.Tag;
|
||||||
|
|
||||||
final class AnyMatcher implements ElementMatcher, AttributeMatcher, ClosedMatcher {
|
final class AnyMatcher implements AttributeMatcher {
|
||||||
private static final AnyMatcher INSTANCE = new AnyMatcher();
|
private static final AnyMatcher INSTANCE = new AnyMatcher();
|
||||||
|
|
||||||
static AnyMatcher getInstance() {
|
static AnyMatcher getInstance() {
|
||||||
@@ -35,26 +35,6 @@ final class AnyMatcher implements ElementMatcher, AttributeMatcher, ClosedMatche
|
|||||||
return attributeMatcher == this;
|
return attributeMatcher == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCoveredBy(ClosedMatcher closedMatcher) {
|
|
||||||
return closedMatcher == this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCoveredBy(ElementMatcher elementMatcher) {
|
|
||||||
return elementMatcher == this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Closed closed) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Element element) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Tag[] tags) {
|
public boolean matches(Tag[] tags) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.rendertheme;
|
package org.mapsforge.android.rendertheme;
|
||||||
|
|
||||||
enum Closed {
|
class Closed {
|
||||||
ANY, NO, YES;
|
public static final int ANY = 0;
|
||||||
|
public static final int NO = 1;
|
||||||
|
public static final int YES = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.rendertheme;
|
|
||||||
|
|
||||||
interface ClosedMatcher {
|
|
||||||
boolean isCoveredBy(ClosedMatcher closedMatcher);
|
|
||||||
|
|
||||||
boolean matches(Closed closed);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.rendertheme;
|
|
||||||
|
|
||||||
final class ClosedWayMatcher implements ClosedMatcher {
|
|
||||||
private static final ClosedWayMatcher INSTANCE = new ClosedWayMatcher();
|
|
||||||
|
|
||||||
static ClosedWayMatcher getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent instantiation from other classes.
|
|
||||||
*/
|
|
||||||
private ClosedWayMatcher() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCoveredBy(ClosedMatcher closedMatcher) {
|
|
||||||
return closedMatcher.matches(Closed.YES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Closed closed) {
|
|
||||||
return closed == Closed.YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapsforge.android.rendertheme;
|
package org.mapsforge.android.rendertheme;
|
||||||
|
|
||||||
enum Element {
|
class Element {
|
||||||
ANY, NODE, WAY;
|
public static final int ANY = 0;
|
||||||
|
public static final int NODE = 1;
|
||||||
|
public static final int WAY = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.rendertheme;
|
|
||||||
|
|
||||||
interface ElementMatcher {
|
|
||||||
boolean isCoveredBy(ElementMatcher elementMatcher);
|
|
||||||
|
|
||||||
boolean matches(Element element);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.rendertheme;
|
|
||||||
|
|
||||||
final class ElementNodeMatcher implements ElementMatcher {
|
|
||||||
private static final ElementNodeMatcher INSTANCE = new ElementNodeMatcher();
|
|
||||||
|
|
||||||
static ElementNodeMatcher getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent instantiation from other classes.
|
|
||||||
*/
|
|
||||||
private ElementNodeMatcher() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCoveredBy(ElementMatcher elementMatcher) {
|
|
||||||
return elementMatcher.matches(Element.NODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Element element) {
|
|
||||||
return element == Element.NODE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.rendertheme;
|
|
||||||
|
|
||||||
final class ElementWayMatcher implements ElementMatcher {
|
|
||||||
private static final ElementWayMatcher INSTANCE = new ElementWayMatcher();
|
|
||||||
|
|
||||||
static ElementWayMatcher getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent instantiation from other classes.
|
|
||||||
*/
|
|
||||||
private ElementWayMatcher() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCoveredBy(ElementMatcher elementMatcher) {
|
|
||||||
return elementMatcher.matches(Element.WAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Element element) {
|
|
||||||
return element == Element.WAY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.mapsforge.android.rendertheme;
|
|
||||||
|
|
||||||
final class LinearWayMatcher implements ClosedMatcher {
|
|
||||||
private static final LinearWayMatcher INSTANCE = new LinearWayMatcher();
|
|
||||||
|
|
||||||
static LinearWayMatcher getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent instantiation from other classes.
|
|
||||||
*/
|
|
||||||
private LinearWayMatcher() {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCoveredBy(ClosedMatcher closedMatcher) {
|
|
||||||
return closedMatcher.matches(Closed.NO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Closed closed) {
|
|
||||||
return closed == Closed.NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,9 +19,9 @@ import org.mapsforge.core.Tag;
|
|||||||
class NegativeRule extends Rule {
|
class NegativeRule extends Rule {
|
||||||
final AttributeMatcher mAttributeMatcher;
|
final AttributeMatcher mAttributeMatcher;
|
||||||
|
|
||||||
NegativeRule(ElementMatcher elementMatcher, ClosedMatcher closedMatcher, byte zoomMin, byte zoomMax,
|
NegativeRule(int element, int closed, byte zoomMin, byte zoomMax,
|
||||||
AttributeMatcher attributeMatcher) {
|
AttributeMatcher attributeMatcher) {
|
||||||
super(elementMatcher, closedMatcher, zoomMin, zoomMax);
|
super(element, closed, zoomMin, zoomMax);
|
||||||
|
|
||||||
mAttributeMatcher = attributeMatcher;
|
mAttributeMatcher = attributeMatcher;
|
||||||
}
|
}
|
||||||
@@ -29,14 +29,15 @@ class NegativeRule extends Rule {
|
|||||||
@Override
|
@Override
|
||||||
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
||||||
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
||||||
&& (mElementMatcher == null || mElementMatcher.matches(Element.NODE))
|
&& (mElement == Element.NODE || mElement == Element.ANY)
|
||||||
&& mAttributeMatcher.matches(tags);
|
&& mAttributeMatcher.matches(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean matchesWay(Tag[] tags, byte zoomLevel, Closed closed) {
|
boolean matchesWay(Tag[] tags, byte zoomLevel, int closed) {
|
||||||
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
||||||
&& (mElementMatcher == null || mElementMatcher.matches(Element.WAY))
|
&& (mElement == Element.WAY || mElement == Element.ANY)
|
||||||
&& (mClosedMatcher == null || mClosedMatcher.matches(closed)) && mAttributeMatcher.matches(tags);
|
&& (mClosed == closed || mClosed == Closed.ANY)
|
||||||
|
&& mAttributeMatcher.matches(tags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ class PositiveRule extends Rule {
|
|||||||
final AttributeMatcher mKeyMatcher;
|
final AttributeMatcher mKeyMatcher;
|
||||||
final AttributeMatcher mValueMatcher;
|
final AttributeMatcher mValueMatcher;
|
||||||
|
|
||||||
PositiveRule(ElementMatcher elementMatcher, ClosedMatcher closedMatcher, byte zoomMin, byte zoomMax,
|
PositiveRule(int element, int closed, byte zoomMin, byte zoomMax,
|
||||||
AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
|
AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
|
||||||
super(elementMatcher, closedMatcher, zoomMin, zoomMax);
|
super(element, closed, zoomMin, zoomMax);
|
||||||
|
|
||||||
if (keyMatcher instanceof AnyMatcher)
|
if (keyMatcher instanceof AnyMatcher)
|
||||||
mKeyMatcher = null;
|
mKeyMatcher = null;
|
||||||
@@ -38,16 +38,16 @@ class PositiveRule extends Rule {
|
|||||||
@Override
|
@Override
|
||||||
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
boolean matchesNode(Tag[] tags, byte zoomLevel) {
|
||||||
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
||||||
&& (mElementMatcher == null || mElementMatcher.matches(Element.NODE))
|
&& (mElement == Element.NODE || mElement == Element.ANY)
|
||||||
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
||||||
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean matchesWay(Tag[] tags, byte zoomLevel, Closed closed) {
|
boolean matchesWay(Tag[] tags, byte zoomLevel, int closed) {
|
||||||
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
return mZoomMin <= zoomLevel && mZoomMax >= zoomLevel
|
||||||
&& (mElementMatcher == null || mElementMatcher.matches(Element.WAY))
|
&& (mElement == Element.WAY || mElement == Element.ANY)
|
||||||
&& (mClosedMatcher == null || mClosedMatcher.matches(closed))
|
&& (mClosed == closed || mClosed == Closed.ANY)
|
||||||
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
&& (mKeyMatcher == null || mKeyMatcher.matches(tags))
|
||||||
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
&& (mValueMatcher == null || mValueMatcher.matches(tags));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,15 +32,19 @@ public class RenderTheme {
|
|||||||
private static final int MATCHING_CACHE_SIZE = 1024;
|
private static final int MATCHING_CACHE_SIZE = 1024;
|
||||||
private static final int RENDER_THEME_VERSION = 1;
|
private static final int RENDER_THEME_VERSION = 1;
|
||||||
|
|
||||||
private static void validate(String elementName, Integer version, float baseStrokeWidth, float baseTextSize) {
|
private static void validate(String elementName, Integer version,
|
||||||
|
float baseStrokeWidth, float baseTextSize) {
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
throw new IllegalArgumentException("missing attribute version for element:" + elementName);
|
throw new IllegalArgumentException("missing attribute version for element:"
|
||||||
|
+ elementName);
|
||||||
} else if (version.intValue() != RENDER_THEME_VERSION) {
|
} else if (version.intValue() != RENDER_THEME_VERSION) {
|
||||||
throw new IllegalArgumentException("invalid render theme version:" + version);
|
throw new IllegalArgumentException("invalid render theme version:" + version);
|
||||||
} else if (baseStrokeWidth < 0) {
|
} else if (baseStrokeWidth < 0) {
|
||||||
throw new IllegalArgumentException("base-stroke-width must not be negative: " + baseStrokeWidth);
|
throw new IllegalArgumentException("base-stroke-width must not be negative: "
|
||||||
|
+ baseStrokeWidth);
|
||||||
} else if (baseTextSize < 0) {
|
} else if (baseTextSize < 0) {
|
||||||
throw new IllegalArgumentException("base-text-size must not be negative: " + baseTextSize);
|
throw new IllegalArgumentException("base-text-size must not be negative: "
|
||||||
|
+ baseTextSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +97,12 @@ public class RenderTheme {
|
|||||||
mBaseTextSize = baseTextSize;
|
mBaseTextSize = baseTextSize;
|
||||||
mRulesList = new ArrayList<Rule>();
|
mRulesList = new ArrayList<Rule>();
|
||||||
|
|
||||||
mMatchingCacheNodes = new LRUCache<MatchingCacheKey, RenderInstruction[]>(MATCHING_CACHE_SIZE);
|
mMatchingCacheNodes = new LRUCache<MatchingCacheKey, RenderInstruction[]>(
|
||||||
mMatchingCacheWay = new LRUCache<MatchingCacheKey, RenderInstruction[]>(MATCHING_CACHE_SIZE);
|
MATCHING_CACHE_SIZE);
|
||||||
mMatchingCacheArea = new LRUCache<MatchingCacheKey, RenderInstruction[]>(MATCHING_CACHE_SIZE);
|
mMatchingCacheWay = new LRUCache<MatchingCacheKey, RenderInstruction[]>(
|
||||||
|
MATCHING_CACHE_SIZE);
|
||||||
|
mMatchingCacheArea = new LRUCache<MatchingCacheKey, RenderInstruction[]>(
|
||||||
|
MATCHING_CACHE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,7 +214,8 @@ public class RenderTheme {
|
|||||||
* @param changed
|
* @param changed
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
public void matchWay(RenderCallback renderCallback, Tag[] tags, byte zoomLevel, boolean closed, boolean changed) {
|
public void matchWay(RenderCallback renderCallback, Tag[] tags, byte zoomLevel,
|
||||||
|
boolean closed, boolean changed) {
|
||||||
RenderInstruction[] renderInstructions = null;
|
RenderInstruction[] renderInstructions = null;
|
||||||
|
|
||||||
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
||||||
@@ -241,10 +249,11 @@ public class RenderTheme {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// cache miss
|
// cache miss
|
||||||
Closed c = (closed ? Closed.YES : Closed.NO);
|
int c = (closed ? Closed.YES : Closed.NO);
|
||||||
List<RenderInstruction> matchingList = new ArrayList<RenderInstruction>(4);
|
List<RenderInstruction> matchingList = new ArrayList<RenderInstruction>(4);
|
||||||
for (int i = 0, n = mRulesList.size(); i < n; ++i) {
|
for (int i = 0, n = mRulesList.size(); i < n; ++i) {
|
||||||
mRulesList.get(i).matchWay(renderCallback, tags, zoomLevel, c, matchingList);
|
mRulesList.get(i).matchWay(renderCallback, tags, zoomLevel, c,
|
||||||
|
matchingList);
|
||||||
}
|
}
|
||||||
int size = matchingList.size();
|
int size = matchingList.size();
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
|
|||||||
@@ -33,21 +33,20 @@ abstract class Rule {
|
|||||||
private static final Pattern SPLIT_PATTERN = Pattern.compile("\\|");
|
private static final Pattern SPLIT_PATTERN = Pattern.compile("\\|");
|
||||||
private static final String STRING_NEGATION = "~";
|
private static final String STRING_NEGATION = "~";
|
||||||
private static final String STRING_WILDCARD = "*";
|
private static final String STRING_WILDCARD = "*";
|
||||||
private static final String UNKNOWN_ENUM_VALUE = "unknown enum value: ";
|
|
||||||
|
|
||||||
private static Rule createRule(Stack<Rule> ruleStack, Element element, String keys, String values, Closed closed,
|
private static Rule createRule(Stack<Rule> ruleStack, int element, String keys,
|
||||||
|
String values, int closed,
|
||||||
byte zoomMin, byte zoomMax) {
|
byte zoomMin, byte zoomMax) {
|
||||||
ElementMatcher elementMatcher = getElementMatcher(element);
|
|
||||||
ClosedMatcher closedMatcher = getClosedMatcher(closed);
|
|
||||||
List<String> keyList = new ArrayList<String>(Arrays.asList(SPLIT_PATTERN.split(keys)));
|
|
||||||
List<String> valueList = new ArrayList<String>(Arrays.asList(SPLIT_PATTERN.split(values)));
|
|
||||||
|
|
||||||
elementMatcher = RuleOptimizer.optimize(elementMatcher, ruleStack);
|
List<String> keyList = new ArrayList<String>(Arrays.asList(SPLIT_PATTERN
|
||||||
closedMatcher = RuleOptimizer.optimize(closedMatcher, ruleStack);
|
.split(keys)));
|
||||||
|
List<String> valueList = new ArrayList<String>(Arrays.asList(SPLIT_PATTERN
|
||||||
|
.split(values)));
|
||||||
|
|
||||||
if (valueList.remove(STRING_NEGATION)) {
|
if (valueList.remove(STRING_NEGATION)) {
|
||||||
AttributeMatcher attributeMatcher = new NegativeMatcher(keyList, valueList);
|
AttributeMatcher attributeMatcher = new NegativeMatcher(keyList, valueList);
|
||||||
return new NegativeRule(elementMatcher, closedMatcher, zoomMin, zoomMax, attributeMatcher);
|
return new NegativeRule(element, closed, zoomMin, zoomMax,
|
||||||
|
attributeMatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeMatcher keyMatcher = getKeyMatcher(keyList);
|
AttributeMatcher keyMatcher = getKeyMatcher(keyList);
|
||||||
@@ -56,33 +55,8 @@ abstract class Rule {
|
|||||||
keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
|
keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
|
||||||
valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
|
valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
|
||||||
|
|
||||||
return new PositiveRule(elementMatcher, closedMatcher, zoomMin, zoomMax, keyMatcher, valueMatcher);
|
return new PositiveRule(element, closed, zoomMin, zoomMax,
|
||||||
}
|
keyMatcher, valueMatcher);
|
||||||
|
|
||||||
private static ClosedMatcher getClosedMatcher(Closed closed) {
|
|
||||||
switch (closed) {
|
|
||||||
case YES:
|
|
||||||
return ClosedWayMatcher.getInstance();
|
|
||||||
case NO:
|
|
||||||
return LinearWayMatcher.getInstance();
|
|
||||||
case ANY:
|
|
||||||
return AnyMatcher.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException(UNKNOWN_ENUM_VALUE + closed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ElementMatcher getElementMatcher(Element element) {
|
|
||||||
switch (element) {
|
|
||||||
case NODE:
|
|
||||||
return ElementNodeMatcher.getInstance();
|
|
||||||
case WAY:
|
|
||||||
return ElementWayMatcher.getInstance();
|
|
||||||
case ANY:
|
|
||||||
return AnyMatcher.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException(UNKNOWN_ENUM_VALUE + element);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AttributeMatcher getKeyMatcher(List<String> keyList) {
|
private static AttributeMatcher getKeyMatcher(List<String> keyList) {
|
||||||
@@ -119,28 +93,31 @@ abstract class Rule {
|
|||||||
return attributeMatcher;
|
return attributeMatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validate(String elementName, Element element, String keys, String values, byte zoomMin,
|
private static void validate(String elementName, String keys, String values,
|
||||||
byte zoomMax) {
|
byte zoomMin, byte zoomMax) {
|
||||||
if (element == null) {
|
if (keys == null) {
|
||||||
throw new IllegalArgumentException("missing attribute e for element: " + elementName);
|
throw new IllegalArgumentException("missing attribute k for element: "
|
||||||
} else if (keys == null) {
|
+ elementName);
|
||||||
throw new IllegalArgumentException("missing attribute k for element: " + elementName);
|
|
||||||
} else if (values == null) {
|
} else if (values == null) {
|
||||||
throw new IllegalArgumentException("missing attribute v for element: " + elementName);
|
throw new IllegalArgumentException("missing attribute v for element: "
|
||||||
|
+ elementName);
|
||||||
} else if (zoomMin < 0) {
|
} else if (zoomMin < 0) {
|
||||||
throw new IllegalArgumentException("zoom-min must not be negative: " + zoomMin);
|
throw new IllegalArgumentException("zoom-min must not be negative: "
|
||||||
|
+ zoomMin);
|
||||||
} else if (zoomMax < 0) {
|
} else if (zoomMax < 0) {
|
||||||
throw new IllegalArgumentException("zoom-max must not be negative: " + zoomMax);
|
throw new IllegalArgumentException("zoom-max must not be negative: "
|
||||||
|
+ zoomMax);
|
||||||
} else if (zoomMin > zoomMax) {
|
} else if (zoomMin > zoomMax) {
|
||||||
throw new IllegalArgumentException("zoom-min must be less or equal zoom-max: " + zoomMin);
|
throw new IllegalArgumentException(
|
||||||
|
"zoom-min must be less or equal zoom-max: " + zoomMin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Rule create(String elementName, Attributes attributes, Stack<Rule> ruleStack) {
|
static Rule create(String elementName, Attributes attributes, Stack<Rule> ruleStack) {
|
||||||
Element element = null;
|
int element = Element.ANY;
|
||||||
String keys = null;
|
String keys = null;
|
||||||
String values = null;
|
String values = null;
|
||||||
Closed closed = Closed.ANY;
|
int closed = Closed.ANY;
|
||||||
byte zoomMin = 0;
|
byte zoomMin = 0;
|
||||||
byte zoomMax = Byte.MAX_VALUE;
|
byte zoomMax = Byte.MAX_VALUE;
|
||||||
|
|
||||||
@@ -149,13 +126,21 @@ abstract class Rule {
|
|||||||
String value = attributes.getValue(i);
|
String value = attributes.getValue(i);
|
||||||
|
|
||||||
if ("e".equals(name)) {
|
if ("e".equals(name)) {
|
||||||
element = Element.valueOf(value.toUpperCase(Locale.ENGLISH));
|
String val = value.toUpperCase(Locale.ENGLISH);
|
||||||
|
if ("WAY".equals(val))
|
||||||
|
element = Element.WAY;
|
||||||
|
else if ("NODE".equals(val))
|
||||||
|
element = Element.NODE;
|
||||||
} else if ("k".equals(name)) {
|
} else if ("k".equals(name)) {
|
||||||
keys = value;
|
keys = value;
|
||||||
} else if ("v".equals(name)) {
|
} else if ("v".equals(name)) {
|
||||||
values = value;
|
values = value;
|
||||||
} else if ("closed".equals(name)) {
|
} else if ("closed".equals(name)) {
|
||||||
closed = Closed.valueOf(value.toUpperCase(Locale.ENGLISH));
|
String val = value.toUpperCase(Locale.ENGLISH);
|
||||||
|
if ("YES".equals(val))
|
||||||
|
closed = Closed.YES;
|
||||||
|
else if ("NO".equals(val))
|
||||||
|
closed = Closed.NO;
|
||||||
} else if ("zoom-min".equals(name)) {
|
} else if ("zoom-min".equals(name)) {
|
||||||
zoomMin = Byte.parseByte(value);
|
zoomMin = Byte.parseByte(value);
|
||||||
} else if ("zoom-max".equals(name)) {
|
} else if ("zoom-max".equals(name)) {
|
||||||
@@ -165,7 +150,7 @@ abstract class Rule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validate(elementName, element, keys, values, zoomMin, zoomMax);
|
validate(elementName, keys, values, zoomMin, zoomMax);
|
||||||
return createRule(ruleStack, element, keys, values, closed, zoomMin, zoomMax);
|
return createRule(ruleStack, element, keys, values, closed, zoomMin, zoomMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,22 +160,16 @@ abstract class Rule {
|
|||||||
private Rule[] mSubRuleArray;
|
private Rule[] mSubRuleArray;
|
||||||
private RenderInstruction[] mRenderInstructionArray;
|
private RenderInstruction[] mRenderInstructionArray;
|
||||||
|
|
||||||
final ClosedMatcher mClosedMatcher;
|
|
||||||
final ElementMatcher mElementMatcher;
|
|
||||||
final byte mZoomMax;
|
final byte mZoomMax;
|
||||||
final byte mZoomMin;
|
final byte mZoomMin;
|
||||||
|
final int mElement;
|
||||||
|
final int mClosed;
|
||||||
|
|
||||||
Rule(ElementMatcher elementMatcher, ClosedMatcher closedMatcher, byte zoomMin, byte zoomMax) {
|
Rule(int element, int closed, byte zoomMin,
|
||||||
if (elementMatcher instanceof AnyMatcher)
|
byte zoomMax) {
|
||||||
mElementMatcher = null;
|
|
||||||
else
|
|
||||||
mElementMatcher = elementMatcher;
|
|
||||||
|
|
||||||
if (closedMatcher instanceof AnyMatcher)
|
|
||||||
mClosedMatcher = null;
|
|
||||||
else
|
|
||||||
mClosedMatcher = closedMatcher;
|
|
||||||
|
|
||||||
|
mClosed = closed;
|
||||||
|
mElement = element;
|
||||||
mZoomMin = zoomMin;
|
mZoomMin = zoomMin;
|
||||||
mZoomMax = zoomMax;
|
mZoomMax = zoomMax;
|
||||||
|
|
||||||
@@ -208,7 +187,7 @@ abstract class Rule {
|
|||||||
|
|
||||||
abstract boolean matchesNode(Tag[] tags, byte zoomLevel);
|
abstract boolean matchesNode(Tag[] tags, byte zoomLevel);
|
||||||
|
|
||||||
abstract boolean matchesWay(Tag[] tags, byte zoomLevel, Closed closed);
|
abstract boolean matchesWay(Tag[] tags, byte zoomLevel, int closed);
|
||||||
|
|
||||||
void matchNode(RenderCallback renderCallback, Tag[] tags, byte zoomLevel) {
|
void matchNode(RenderCallback renderCallback, Tag[] tags, byte zoomLevel) {
|
||||||
if (matchesNode(tags, zoomLevel)) {
|
if (matchesNode(tags, zoomLevel)) {
|
||||||
@@ -221,7 +200,8 @@ abstract class Rule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void matchWay(RenderCallback renderCallback, Tag[] tags, byte zoomLevel, Closed closed,
|
void matchWay(RenderCallback renderCallback, Tag[] tags, byte zoomLevel,
|
||||||
|
int closed,
|
||||||
List<RenderInstruction> matchingList) {
|
List<RenderInstruction> matchingList) {
|
||||||
|
|
||||||
if (matchesWay(tags, zoomLevel, closed)) {
|
if (matchesWay(tags, zoomLevel, closed)) {
|
||||||
@@ -229,7 +209,8 @@ abstract class Rule {
|
|||||||
matchingList.add(mRenderInstructionArray[i]);
|
matchingList.add(mRenderInstructionArray[i]);
|
||||||
|
|
||||||
for (int i = 0, n = mSubRuleArray.length; i < n; i++)
|
for (int i = 0, n = mSubRuleArray.length; i < n; i++)
|
||||||
mSubRuleArray[i].matchWay(renderCallback, tags, zoomLevel, closed, matchingList);
|
mSubRuleArray[i].matchWay(renderCallback, tags, zoomLevel, closed,
|
||||||
|
matchingList);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ import java.util.logging.Logger;
|
|||||||
final class RuleOptimizer {
|
final class RuleOptimizer {
|
||||||
private static final Logger LOG = Logger.getLogger(RuleOptimizer.class.getName());
|
private static final Logger LOG = Logger.getLogger(RuleOptimizer.class.getName());
|
||||||
|
|
||||||
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher, Stack<Rule> ruleStack) {
|
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
|
||||||
|
Stack<Rule> ruleStack) {
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
if (ruleStack.get(i) instanceof PositiveRule) {
|
if (ruleStack.get(i) instanceof PositiveRule) {
|
||||||
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
||||||
if (positiveRule.mKeyMatcher != null && positiveRule.mKeyMatcher.isCoveredBy(attributeMatcher)) {
|
if (positiveRule.mKeyMatcher != null
|
||||||
|
&& positiveRule.mKeyMatcher.isCoveredBy(attributeMatcher)) {
|
||||||
return null; // AnyMatcher.getInstance();
|
return null; // AnyMatcher.getInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,12 +35,14 @@ final class RuleOptimizer {
|
|||||||
return attributeMatcher;
|
return attributeMatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AttributeMatcher optimizeValueMatcher(AttributeMatcher attributeMatcher, Stack<Rule> ruleStack) {
|
private static AttributeMatcher optimizeValueMatcher(
|
||||||
|
AttributeMatcher attributeMatcher, Stack<Rule> ruleStack) {
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
if (ruleStack.get(i) instanceof PositiveRule) {
|
if (ruleStack.get(i) instanceof PositiveRule) {
|
||||||
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
||||||
|
|
||||||
if (positiveRule.mValueMatcher != null && positiveRule.mValueMatcher.isCoveredBy(attributeMatcher)) {
|
if (positiveRule.mValueMatcher != null
|
||||||
|
&& positiveRule.mValueMatcher.isCoveredBy(attributeMatcher)) {
|
||||||
return null; // AnyMatcher.getInstance();
|
return null; // AnyMatcher.getInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +51,8 @@ final class RuleOptimizer {
|
|||||||
return attributeMatcher;
|
return attributeMatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AttributeMatcher optimize(AttributeMatcher attributeMatcher, Stack<Rule> ruleStack) {
|
static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
|
||||||
|
Stack<Rule> ruleStack) {
|
||||||
if (attributeMatcher instanceof AnyMatcher)
|
if (attributeMatcher instanceof AnyMatcher)
|
||||||
return attributeMatcher;// return null;
|
return attributeMatcher;// return null;
|
||||||
else if (attributeMatcher instanceof NegativeMatcher) {
|
else if (attributeMatcher instanceof NegativeMatcher) {
|
||||||
@@ -61,60 +66,61 @@ final class RuleOptimizer {
|
|||||||
} else if (attributeMatcher instanceof MultiValueMatcher) {
|
} else if (attributeMatcher instanceof MultiValueMatcher) {
|
||||||
return optimizeValueMatcher(attributeMatcher, ruleStack);
|
return optimizeValueMatcher(attributeMatcher, ruleStack);
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("unknown AttributeMatcher: " + attributeMatcher);
|
throw new IllegalArgumentException("unknown AttributeMatcher: "
|
||||||
|
+ attributeMatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClosedMatcher optimize(ClosedMatcher closedMatcher, Stack<Rule> ruleStack) {
|
// static ClosedMatcher optimize(ClosedMatcher closedMatcher, Stack<Rule> ruleStack) {
|
||||||
if (closedMatcher == null) {
|
// if (closedMatcher == null) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (closedMatcher instanceof AnyMatcher) {
|
// if (closedMatcher instanceof AnyMatcher) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
// for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
ClosedMatcher matcher = ruleStack.get(i).mClosedMatcher;
|
// ClosedMatcher matcher = ruleStack.get(i).mClosedMatcher;
|
||||||
if (matcher == null)
|
// if (matcher == null)
|
||||||
return null;
|
// return null;
|
||||||
|
//
|
||||||
if (matcher.isCoveredBy(closedMatcher)) {
|
// if (matcher.isCoveredBy(closedMatcher)) {
|
||||||
return null; // AnyMatcher.getInstance();
|
// return null; // AnyMatcher.getInstance();
|
||||||
|
//
|
||||||
} else if (!closedMatcher.isCoveredBy(ruleStack.get(i).mClosedMatcher)) {
|
// } else if (!closedMatcher.isCoveredBy(ruleStack.get(i).mClosedMatcher)) {
|
||||||
LOG.warning("unreachable rule (closed)");
|
// LOG.warning("unreachable rule (closed)");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return closedMatcher;
|
// return closedMatcher;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static ElementMatcher optimize(ElementMatcher elementMatcher, Stack<Rule> ruleStack) {
|
// static ElementMatcher optimize(ElementMatcher elementMatcher, Stack<Rule> ruleStack) {
|
||||||
|
//
|
||||||
if (elementMatcher == null) {
|
// if (elementMatcher == null) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (elementMatcher instanceof AnyMatcher) {
|
// if (elementMatcher instanceof AnyMatcher) {
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
// for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
ElementMatcher matcher = ruleStack.get(i).mElementMatcher;
|
// ElementMatcher matcher = ruleStack.get(i).mElementMatcher;
|
||||||
|
//
|
||||||
if (matcher == null)
|
// if (matcher == null)
|
||||||
return null;
|
// return null;
|
||||||
|
//
|
||||||
if (matcher.isCoveredBy(elementMatcher)) {
|
// if (matcher.isCoveredBy(elementMatcher)) {
|
||||||
return null; // AnyMatcher.getInstance();
|
// return null; // AnyMatcher.getInstance();
|
||||||
|
//
|
||||||
} else if (!elementMatcher.isCoveredBy(ruleStack.get(i).mElementMatcher)) {
|
// } else if (!elementMatcher.isCoveredBy(ruleStack.get(i).mElementMatcher)) {
|
||||||
LOG.warning("unreachable rule (e)");
|
// LOG.warning("unreachable rule (e)");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return elementMatcher;
|
// return elementMatcher;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor to prevent instantiation from other classes.
|
* Private constructor to prevent instantiation from other classes.
|
||||||
|
|||||||
@@ -8,9 +8,17 @@
|
|||||||
<rule e="way" k="*" v="*">
|
<rule e="way" k="*" v="*">
|
||||||
|
|
||||||
<!-- landuse -->
|
<!-- landuse -->
|
||||||
<rule e="way" k="landuse" v="*" zoom-min="10">
|
<rule e="way" k="landuse" v="*">
|
||||||
<rule e="way" k="landuse" v="residential|farmyard|retail|commercial">
|
<rule e="way" k="*" zoom-min="12" v="farmland|farm">
|
||||||
<area fill="#ededec" fade="10" />
|
<area fill="#fff8bf" fade="12" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="landuse" v="grass">
|
||||||
|
<area fill="#deecb9" fade="12" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" zoom-min="10" v="residential|farmyard|retail|commercial">
|
||||||
|
<area fill="#efefeb" fade="10" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<!-- <rule e="way" k="landuse" v="industrial|brownfield|railway"> <area
|
<!-- <rule e="way" k="landuse" v="industrial|brownfield|railway"> <area
|
||||||
@@ -19,9 +27,7 @@
|
|||||||
stroke="#e4e4e4" stroke-width="0.2" /> </rule> -->
|
stroke="#e4e4e4" stroke-width="0.2" /> </rule> -->
|
||||||
<!-- <rule e="way" k="landuse" v="garages"> <area fill="#d6d6e4" /> </rule> -->
|
<!-- <rule e="way" k="landuse" v="garages"> <area fill="#d6d6e4" /> </rule> -->
|
||||||
|
|
||||||
<rule e="way" k="landuse" v="grass">
|
|
||||||
<area fill="#deecb9" fade="12" />
|
|
||||||
</rule>
|
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="outline" v="*">
|
<rule e="way" k="outline" v="*">
|
||||||
@@ -103,9 +109,7 @@
|
|||||||
<rule e="way" k="*" v="meadow|scrub">
|
<rule e="way" k="*" v="meadow|scrub">
|
||||||
<area fill="#deecb9" fade="12" />
|
<area fill="#deecb9" fade="12" />
|
||||||
</rule>
|
</rule>
|
||||||
<rule e="way" k="*" v="farmland|farm">
|
|
||||||
<area fill="#fff8bf" fade="12" />
|
|
||||||
</rule>
|
|
||||||
<!-- <rule e="way" k="*" v="village_green|recreation_ground">
|
<!-- <rule e="way" k="*" v="village_green|recreation_ground">
|
||||||
<area fill="#daebaf" fade="12" />
|
<area fill="#daebaf" fade="12" />
|
||||||
</rule> -->
|
</rule> -->
|
||||||
@@ -130,9 +134,14 @@
|
|||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
|
||||||
<rule e="way" k="natural|landuse" v="forest|wood" zoom-min="10">
|
<rule e="way" k="natural|landuse" v="forest|wood" zoom-min="9">
|
||||||
<!-- <area fill="#BCCBB0" fade="10" /> -->
|
<!-- <area fill="#BCCBB0" fade="10" /> -->
|
||||||
<area fill="#cde2bc" fade="10" />
|
<!-- <rule e="way" k="*" v="*" zoom-max="11"> -->
|
||||||
|
<area fill="#d3dec8" fade="9" />
|
||||||
|
<!-- </rule> -->
|
||||||
|
<!-- <rule e="way" k="*" v="*" zoom-min="12">
|
||||||
|
<area fill="#cde2bc" fade="12" />
|
||||||
|
</rule> -->
|
||||||
<!-- <area fill="#87a670" fade="10" /> -->
|
<!-- <area fill="#87a670" fade="10" /> -->
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
@@ -169,8 +178,8 @@
|
|||||||
<area fill="#fcfeab" />
|
<area fill="#fcfeab" />
|
||||||
</rule>
|
</rule>
|
||||||
<!-- Heideland -->
|
<!-- Heideland -->
|
||||||
<rule e="way" k="*" v="heath">
|
<rule e="way" k="*" zoom-min="12" v="heath">
|
||||||
<area fill="#ffffc0" fade="10" />
|
<area fill="#ffffc0" fade="12" />
|
||||||
</rule>
|
</rule>
|
||||||
<rule e="way" k="*" v="marsh|wetland">
|
<rule e="way" k="*" v="marsh|wetland">
|
||||||
<area fill="#deecb9" fade="12" />
|
<area fill="#deecb9" fade="12" />
|
||||||
@@ -207,7 +216,8 @@
|
|||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="natural" v="water">
|
<rule e="way" k="natural" v="water">
|
||||||
<area fill="#b4cbdc" />
|
<line stroke="#eea4bbcc" fixed="true" stroke-width="1.4" stroke-linecap="butt" />
|
||||||
|
<area fill="#b4cbdc" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<!-- waterways -->
|
<!-- waterways -->
|
||||||
@@ -232,6 +242,7 @@
|
|||||||
fixed="true" />
|
fixed="true" />
|
||||||
</rule>
|
</rule>
|
||||||
<rule e="way" k="waterway" v="riverbank|dock">
|
<rule e="way" k="waterway" v="riverbank|dock">
|
||||||
|
<line stroke="#eea4bbcc" fixed="true" stroke-width="1.4" stroke-linecap="butt" />
|
||||||
<area fill="#b4cbdc" />
|
<area fill="#b4cbdc" />
|
||||||
</rule>
|
</rule>
|
||||||
<rule e="way" k="waterway" v="weir">
|
<rule e="way" k="waterway" v="weir">
|
||||||
@@ -323,9 +334,8 @@
|
|||||||
</rule>-->
|
</rule>-->
|
||||||
|
|
||||||
<rule e="way" k="*" v="*" zoom-min="15">
|
<rule e="way" k="*" v="*" zoom-min="15">
|
||||||
<line stroke="#c9c3c3" stroke-width="0.6" fixed="true"
|
<line stroke="#c9c3c1" stroke-width="0.6" fixed="true" stroke-linecap="butt" />
|
||||||
stroke-linecap="butt" />
|
<area fill="#e9e6e3" fade="15" />
|
||||||
<area fill="#e9e6e6" fade="15" />
|
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<!-- <rule e="way" k="*" v="*" zoom-min="17">
|
<!-- <rule e="way" k="*" v="*" zoom-min="17">
|
||||||
@@ -359,31 +369,31 @@
|
|||||||
<rule e="way" k="*" v="*" zoom-min="5" zoom-max="10">
|
<rule e="way" k="*" v="*" zoom-min="5" zoom-max="10">
|
||||||
|
|
||||||
<rule e="way" k="*" v="secondary|primary_link" zoom-min="9">
|
<rule e="way" k="*" v="secondary|primary_link" zoom-min="9">
|
||||||
<!-- <line stroke="#eeee4a" stroke-width="1.3" stroke-linecap="butt"
|
<!-- <line stroke="#eeee4a" stroke-width="1.8" stroke-linecap="butt"
|
||||||
fixed="true" /> -->
|
fixed="true" /> -->
|
||||||
<line stroke="#f2df6d" stroke-width="1.2" stroke-linecap="butt"
|
<line stroke="#f2df6d" stroke-width="1.7" stroke-linecap="butt"
|
||||||
fixed="true" />
|
fixed="true" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="*" v="trunk_link|motorway_link" zoom-min="8">
|
<rule e="way" k="*" v="trunk_link|motorway_link" zoom-min="8">
|
||||||
<line stroke="#fed6a3" stroke-width="1.4" stroke-linecap="butt"
|
<line stroke="#fed6a3" stroke-width="1.9" stroke-linecap="butt"
|
||||||
fixed="true" />
|
fixed="true" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="*" v="primary" zoom-min="8">
|
<rule e="way" k="*" v="primary" zoom-min="7">
|
||||||
<!-- <line stroke="#eeee4a" stroke-width="1.4" stroke-linecap="butt"
|
<!-- <line stroke="#eeee4a" stroke-width="1.4" stroke-linecap="butt"
|
||||||
fixed="true" /> -->
|
fixed="true" /> -->
|
||||||
<line stroke="#f2df6d" stroke-width="1.4" stroke-linecap="butt"
|
<line stroke="#f2df6d" stroke-width="1.9" stroke-linecap="butt"
|
||||||
fixed="true" />
|
fixed="true" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="*" v="trunk" zoom-min="8">
|
<rule e="way" k="*" v="trunk" zoom-min="7">
|
||||||
<line stroke="#fed6a3" stroke-width="1.4" stroke-linecap="butt"
|
<line stroke="#fed6a3" stroke-width="1.9" stroke-linecap="butt"
|
||||||
fixed="true" />
|
fixed="true" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="*" v="motorway">
|
<rule e="way" k="*" v="motorway">
|
||||||
<line stroke="#eec693" stroke-width="1.5" stroke-linecap="butt"
|
<line stroke="#eec693" stroke-width="2.0" stroke-linecap="butt"
|
||||||
fixed="true" />
|
fixed="true" />
|
||||||
</rule>
|
</rule>
|
||||||
</rule>
|
</rule>
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ public final class Line implements RenderInstruction {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if an I/O error occurs while reading a resource.
|
* if an I/O error occurs while reading a resource.
|
||||||
*/
|
*/
|
||||||
public static Line create(String elementName, Attributes attributes, int level) throws IOException {
|
public static Line create(String elementName, Attributes attributes, int level)
|
||||||
|
throws IOException {
|
||||||
String src = null;
|
String src = null;
|
||||||
int stroke = Color.BLACK;
|
int stroke = Color.BLACK;
|
||||||
float strokeWidth = 0;
|
float strokeWidth = 0;
|
||||||
@@ -83,12 +84,14 @@ public final class Line implements RenderInstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
validate(strokeWidth);
|
validate(strokeWidth);
|
||||||
return new Line(src, stroke, strokeWidth, strokeDasharray, strokeLinecap, level, outline, fixed);
|
return new Line(src, stroke, strokeWidth, strokeDasharray, strokeLinecap, level,
|
||||||
|
outline, fixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validate(float strokeWidth) {
|
private static void validate(float strokeWidth) {
|
||||||
if (strokeWidth < 0) {
|
if (strokeWidth < 0) {
|
||||||
throw new IllegalArgumentException("stroke-width must not be negative: " + strokeWidth);
|
throw new IllegalArgumentException("stroke-width must not be negative: "
|
||||||
|
+ strokeWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +134,8 @@ public final class Line implements RenderInstruction {
|
|||||||
*/
|
*/
|
||||||
public final boolean fixed;
|
public final boolean fixed;
|
||||||
|
|
||||||
private Line(String src, int stroke, float strokeWidth, float[] strokeDasharray, Cap strokeLinecap, int level,
|
private Line(String src, int stroke, float strokeWidth, float[] strokeDasharray,
|
||||||
|
Cap strokeLinecap, int level,
|
||||||
int outline, boolean fixed)
|
int outline, boolean fixed)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
super();
|
super();
|
||||||
@@ -146,7 +150,7 @@ public final class Line implements RenderInstruction {
|
|||||||
paint.setPathEffect(new DashPathEffect(strokeDasharray, 0));
|
paint.setPathEffect(new DashPathEffect(strokeDasharray, 0));
|
||||||
}
|
}
|
||||||
paint.setStrokeCap(strokeLinecap);
|
paint.setStrokeCap(strokeLinecap);
|
||||||
round = strokeLinecap == Cap.ROUND;
|
round = (strokeLinecap == Cap.ROUND);
|
||||||
this.color = stroke;
|
this.color = stroke;
|
||||||
this.strokeWidth = strokeWidth;
|
this.strokeWidth = strokeWidth;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
|||||||
Reference in New Issue
Block a user