Render themes: symbol styles (#769)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
* Copyright 2016-2019 devemux86
|
||||
* Copyright 2016-2017 Longri
|
||||
* Copyright 2016 Andrey Novikov
|
||||
* Copyright 2016-2020 Andrey Novikov
|
||||
* Copyright 2018-2019 Gustl22
|
||||
* Copyright 2018 Izumi Kawashima
|
||||
* Copyright 2019 Murray Hughes
|
||||
@@ -140,6 +140,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
private final HashMap<String, RenderStyle> mStyles = new HashMap<>(10);
|
||||
|
||||
private final HashMap<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
||||
private final HashMap<String, SymbolStyle.SymbolBuilder<?>> mSymbolStyles = new HashMap<>(10);
|
||||
|
||||
private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder();
|
||||
private final CircleBuilder<?> mCircleBuilder = CircleStyle.builder();
|
||||
@@ -196,6 +197,8 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
|
||||
mRulesList.clear();
|
||||
mStyles.clear();
|
||||
mTextStyles.clear();
|
||||
mSymbolStyles.clear();
|
||||
mRuleStack.clear();
|
||||
mElementStack.clear();
|
||||
|
||||
@@ -261,6 +264,10 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
checkState(localName, Element.STYLE);
|
||||
handleTextElement(localName, attributes, true, false);
|
||||
|
||||
} else if ("style-symbol".equals(localName)) {
|
||||
checkState(localName, Element.STYLE);
|
||||
handleSymbolElement(localName, attributes, true);
|
||||
|
||||
} else if ("style-area".equals(localName)) {
|
||||
checkState(localName, Element.STYLE);
|
||||
handleAreaElement(localName, attributes, true);
|
||||
@@ -298,9 +305,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
|
||||
} else if ("symbol".equals(localName)) {
|
||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||
SymbolStyle symbol = createSymbol(localName, attributes);
|
||||
if (symbol != null && isVisible(symbol))
|
||||
mCurrentRule.addStyle(symbol);
|
||||
handleSymbolElement(localName, attributes, false);
|
||||
|
||||
} else if ("outline".equals(localName)) {
|
||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||
@@ -1134,23 +1139,59 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
return b.build();
|
||||
}
|
||||
|
||||
private void handleSymbolElement(String localName, Attributes attributes, boolean isStyle)
|
||||
throws SAXException {
|
||||
|
||||
String style = attributes.getValue("use");
|
||||
SymbolBuilder<?> ps = null;
|
||||
|
||||
if (style != null) {
|
||||
ps = mSymbolStyles.get(style);
|
||||
if (ps == null) {
|
||||
log.debug("missing symbol style: " + style);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SymbolBuilder<?> b = createSymbol(localName, attributes, ps);
|
||||
if (isStyle) {
|
||||
log.debug("put style {}", b.style);
|
||||
mSymbolStyles.put(b.style, SymbolStyle.builder().from(b));
|
||||
} else {
|
||||
SymbolStyle symbol = buildSymbol(b);
|
||||
if (symbol != null && isVisible(symbol))
|
||||
mCurrentRule.addStyle(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new Symbol with the given rendering attributes.
|
||||
*/
|
||||
private SymbolStyle createSymbol(String elementName, Attributes attributes) {
|
||||
SymbolBuilder<?> b = mSymbolBuilder.reset();
|
||||
String src = null;
|
||||
private SymbolBuilder<?> createSymbol(String elementName, Attributes attributes,
|
||||
SymbolBuilder<?> style) {
|
||||
SymbolBuilder<?> b;
|
||||
if (style == null)
|
||||
b = mSymbolBuilder.reset();
|
||||
else
|
||||
b = mSymbolBuilder.from(style);
|
||||
b.themeCallback(mThemeCallback);
|
||||
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
String name = attributes.getLocalName(i);
|
||||
String value = attributes.getValue(i);
|
||||
|
||||
if ("src".equals(name))
|
||||
src = value;
|
||||
if ("id".equals(name))
|
||||
b.style = value;
|
||||
|
||||
else if ("src".equals(name))
|
||||
b.src(value);
|
||||
|
||||
else if ("cat".equals(name))
|
||||
b.cat(value);
|
||||
|
||||
else if ("use".equals(name))
|
||||
;// ignore
|
||||
|
||||
else if ("symbol-width".equals(name))
|
||||
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
|
||||
|
||||
@@ -1182,20 +1223,24 @@ public class XmlThemeBuilder extends DefaultHandler {
|
||||
logUnknownAttribute(elementName, name, value, i);
|
||||
}
|
||||
|
||||
validateExists("src", src, elementName);
|
||||
validateExists("src", b.src, elementName);
|
||||
|
||||
String lowSrc = src.toLowerCase(Locale.ENGLISH);
|
||||
return b;
|
||||
}
|
||||
|
||||
private SymbolStyle buildSymbol(SymbolBuilder<?> b) {
|
||||
String lowSrc = b.src.toLowerCase(Locale.ENGLISH);
|
||||
if (lowSrc.endsWith(".png") || lowSrc.endsWith(".svg")) {
|
||||
try {
|
||||
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
||||
Bitmap bitmap = CanvasAdapter.getBitmapAsset(mTheme.getRelativePathPrefix(), b.src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
|
||||
if (bitmap != null)
|
||||
return buildSymbol(b, src, bitmap);
|
||||
return buildSymbol(b, b.src, bitmap);
|
||||
} catch (Exception e) {
|
||||
log.error("{}: {}", src, e.getMessage());
|
||||
log.error("{}: {}", b.src, e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return b.texture(getAtlasRegion(src)).build();
|
||||
return b.texture(getAtlasRegion(b.src)).build();
|
||||
}
|
||||
|
||||
SymbolStyle buildSymbol(SymbolBuilder<?> b, String src, Bitmap bitmap) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
* Copyright 2016-2019 devemux86
|
||||
* Copyright 2017 Longri
|
||||
* Copyright 2020 Andrey Novikov
|
||||
*
|
||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||
*
|
||||
@@ -118,6 +119,7 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
|
||||
public Bitmap bitmap;
|
||||
public TextureRegion texture;
|
||||
public int hash;
|
||||
public String src;
|
||||
|
||||
public int symbolWidth;
|
||||
public int symbolHeight;
|
||||
@@ -133,6 +135,27 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
|
||||
public SymbolBuilder() {
|
||||
}
|
||||
|
||||
public T from(SymbolBuilder<?> other) {
|
||||
this.cat = other.cat;
|
||||
|
||||
this.bitmap = other.bitmap;
|
||||
this.texture = other.texture;
|
||||
this.hash = other.hash;
|
||||
this.src = other.src;
|
||||
|
||||
this.symbolWidth = other.symbolWidth;
|
||||
this.symbolHeight = other.symbolHeight;
|
||||
this.symbolPercent = other.symbolPercent;
|
||||
|
||||
this.billboard = other.billboard;
|
||||
this.repeat = other.repeat;
|
||||
this.repeatStart = other.repeatStart;
|
||||
this.repeatGap = other.repeatGap;
|
||||
this.rotate = other.rotate;
|
||||
|
||||
return self();
|
||||
}
|
||||
|
||||
public T set(SymbolStyle symbol) {
|
||||
if (symbol == null)
|
||||
return reset();
|
||||
@@ -171,6 +194,11 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
|
||||
return self();
|
||||
}
|
||||
|
||||
public T src(String src) {
|
||||
this.src = src;
|
||||
return self();
|
||||
}
|
||||
|
||||
public T symbolWidth(int symbolWidth) {
|
||||
this.symbolWidth = symbolWidth;
|
||||
return self();
|
||||
@@ -217,6 +245,7 @@ public final class SymbolStyle extends RenderStyle<SymbolStyle> {
|
||||
bitmap = null;
|
||||
texture = null;
|
||||
hash = 0;
|
||||
src = null;
|
||||
|
||||
symbolWidth = 0;
|
||||
symbolHeight = 0;
|
||||
|
||||
Reference in New Issue
Block a user