diff --git a/resources/rendertheme.xsd b/resources/rendertheme.xsd index 37ddc337..f46c49c8 100644 --- a/resources/rendertheme.xsd +++ b/resources/rendertheme.xsd @@ -233,7 +233,11 @@ - + + + + + @@ -332,6 +336,7 @@ + diff --git a/vtm-themes/resources/assets/vtm/default.xml b/vtm-themes/resources/assets/vtm/default.xml index 2160ac5f..dfef7c72 100644 --- a/vtm-themes/resources/assets/vtm/default.xml +++ b/vtm-themes/resources/assets/vtm/default.xml @@ -165,6 +165,11 @@ + + + + + @@ -1079,7 +1084,7 @@ - + diff --git a/vtm-themes/resources/assets/vtm/mapzen.xml b/vtm-themes/resources/assets/vtm/mapzen.xml index 45840445..de64bee4 100644 --- a/vtm-themes/resources/assets/vtm/mapzen.xml +++ b/vtm-themes/resources/assets/vtm/mapzen.xml @@ -129,6 +129,9 @@ + + + @@ -1038,7 +1041,7 @@ - + diff --git a/vtm-themes/resources/assets/vtm/newtron.xml b/vtm-themes/resources/assets/vtm/newtron.xml index 758b5a91..5790607a 100644 --- a/vtm-themes/resources/assets/vtm/newtron.xml +++ b/vtm-themes/resources/assets/vtm/newtron.xml @@ -118,6 +118,11 @@ + + + + + @@ -1080,7 +1085,7 @@ - + diff --git a/vtm-themes/resources/assets/vtm/openmaptiles.xml b/vtm-themes/resources/assets/vtm/openmaptiles.xml index 284507d6..2f5a2122 100644 --- a/vtm-themes/resources/assets/vtm/openmaptiles.xml +++ b/vtm-themes/resources/assets/vtm/openmaptiles.xml @@ -162,6 +162,11 @@ + + + + + @@ -332,7 +337,7 @@ - + diff --git a/vtm-themes/resources/assets/vtm/osmagray.xml b/vtm-themes/resources/assets/vtm/osmagray.xml index 84e24ad2..9b918f33 100644 --- a/vtm-themes/resources/assets/vtm/osmagray.xml +++ b/vtm-themes/resources/assets/vtm/osmagray.xml @@ -52,6 +52,11 @@ + + + + + @@ -959,7 +964,7 @@ - + diff --git a/vtm-themes/resources/assets/vtm/osmarender.xml b/vtm-themes/resources/assets/vtm/osmarender.xml index 326c87e6..facdc48b 100644 --- a/vtm-themes/resources/assets/vtm/osmarender.xml +++ b/vtm-themes/resources/assets/vtm/osmarender.xml @@ -52,6 +52,11 @@ + + + + + @@ -959,7 +964,7 @@ - + diff --git a/vtm-themes/resources/assets/vtm/tronrender.xml b/vtm-themes/resources/assets/vtm/tronrender.xml index 29a192e1..f566f849 100644 --- a/vtm-themes/resources/assets/vtm/tronrender.xml +++ b/vtm-themes/resources/assets/vtm/tronrender.xml @@ -119,6 +119,11 @@ + + + + + @@ -1073,7 +1078,7 @@ - + diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java index 2adf60c8..87bbee6e 100644 --- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java +++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java @@ -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 mStyles = new HashMap<>(10); private final HashMap> mTextStyles = new HashMap<>(10); + private final HashMap> 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) { diff --git a/vtm/src/org/oscim/theme/styles/SymbolStyle.java b/vtm/src/org/oscim/theme/styles/SymbolStyle.java index ce185652..3ba871aa 100644 --- a/vtm/src/org/oscim/theme/styles/SymbolStyle.java +++ b/vtm/src/org/oscim/theme/styles/SymbolStyle.java @@ -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 { 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 { 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 { 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 { bitmap = null; texture = null; hash = 0; + src = null; symbolWidth = 0; symbolHeight = 0;