org.oscim.theme.rule.RuleBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vtm Show documentation
Show all versions of vtm Show documentation
OpenGL vector map library written in Java - running on Android, iOS, Desktop and within the browser.
/*
* Copyright 2014 Hannes Janetzek
* Copyright 2016-2017 devemux86
*
* 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.theme.IRenderTheme.ThemeException;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RuleBuilder {
private static final String[] EMPTY_KV = {};
public enum RuleType {
POSITIVE,
NEGATIVE,
EXCLUDE
}
public String cat;
int zoom;
int element;
int selector;
RuleType type;
String keys[];
String values[];
ArrayList renderStyles = new ArrayList<>(4);
ArrayList subRules = new ArrayList<>(4);
StyleBuilder>[] styleBuilder;
private static final String STRING_NEGATION = "~";
private static final String STRING_EXCLUSIVE = "-";
private static final String SEPARATOR = "\\|";
//private static final String STRING_WILDCARD = "*";
public RuleBuilder(RuleType type, int element, int zoom, int selector,
String[] keys, String[] values) {
this.type = type;
this.element = element;
this.zoom = zoom;
this.selector = selector;
this.keys = keys;
this.values = values;
}
public RuleBuilder(RuleType type, String[] keys, String[] values) {
this.element = Element.ANY;
this.zoom = ~0;
this.type = type;
this.keys = keys;
this.values = values;
}
public RuleBuilder() {
this.type = RuleType.POSITIVE;
this.element = Element.ANY;
this.zoom = ~0;
this.keys = EMPTY_KV;
this.values = EMPTY_KV;
}
public static RuleBuilder create(String k, String v) {
String[] keys = EMPTY_KV;
String[] values = EMPTY_KV;
RuleType type = RuleType.POSITIVE;
if (v != null) {
String[] split = v.split(SEPARATOR);
List valueList = new ArrayList<>(Arrays.asList(split));
if (valueList.remove(STRING_NEGATION)) {
type = RuleType.NEGATIVE;
values = valueList.toArray(new String[valueList.size()]);
} else if (valueList.remove(STRING_EXCLUSIVE)) {
type = RuleType.EXCLUDE;
values = valueList.toArray(new String[valueList.size()]);
} else {
values = split;
}
}
if (k != null) {
keys = k.split(SEPARATOR);
}
if (type != RuleType.POSITIVE) {
if (keys == null || keys.length == 0)
throw new ThemeException("negative rule requires key");
}
return new RuleBuilder(type, keys, values);
}
public RuleBuilder zoom(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(int[] level) {
RenderStyle[] styles = null;
Rule[] rules = null;
if (styleBuilder != null)
for (StyleBuilder> style : styleBuilder) {
renderStyles.add(style.level(level[0]).build());
level[0] += 2;
}
if (renderStyles.size() > 0) {
styles = new RenderStyle[renderStyles.size()];
renderStyles.toArray(styles);
}
if (subRules.size() > 0) {
rules = new Rule[subRules.size()];
for (int i = 0; i < rules.length; i++)
rules[i] = subRules.get(i).onComplete(level);
}
int numKeys = keys.length;
int numVals = values.length;
if (numKeys == 0 && numVals == 0)
return new Rule(element, zoom, selector, rules, styles)
.setCat(cat);
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)
.setCat(cat);
if (numKeys == 1 && numVals == 0)
return new PositiveRuleK(element, zoom, selector, keys[0], rules, styles)
.setCat(cat);
if (numKeys == 0 && numVals == 1)
return new PositiveRuleV(element, zoom, selector, values[0], rules, styles)
.setCat(cat);
if (numKeys == 1 && numVals == 1)
return new PositiveRuleKV(element, zoom, selector, keys[0], values[0], rules, styles)
.setCat(cat);
return new PositiveRuleMultiKV(element, zoom, selector, keys, values, rules, styles)
.setCat(cat);
}
public RuleBuilder addStyle(RenderStyle style) {
renderStyles.add(style);
return this;
}
public RuleBuilder addSubRule(RuleBuilder rule) {
subRules.add(rule);
return this;
}
public RuleBuilder style(StyleBuilder>... styles) {
styleBuilder = styles;
return this;
}
public RuleBuilder rules(RuleBuilder... rules) {
Collections.addAll(subRules, rules);
return this;
}
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;
}
public RuleBuilder cat(String cat) {
this.cat = cat;
return this;
}
}