Render themes: symbol styles (#769)

This commit is contained in:
Andrey Novikov
2020-04-16 14:11:50 +03:00
committed by Emux
parent 1156976ea5
commit 635d5bacdd
10 changed files with 135 additions and 23 deletions

View File

@@ -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) {

View File

@@ -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;