diff --git a/resources/rendertheme.xsd b/resources/rendertheme.xsd
index 9ec1edab..cdfc815c 100644
--- a/resources/rendertheme.xsd
+++ b/resources/rendertheme.xsd
@@ -301,11 +301,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java b/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
index 86c7d30d..8264649e 100644
--- a/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
+++ b/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
@@ -251,6 +251,20 @@ public class RenderTheme implements IRenderTheme {
public void scaleTextSize(float scaleFactor) {
}
+ @Override
+ public String transformKey(String key) {
+ return null;
+ }
+
+ @Override
+ public Tag transformTag(Tag tag) {
+ return null;
+ }
+
+ @Override
+ public void updateStyles() {
+ }
+
public static void main(String[] args) {
RenderTheme t = new RenderTheme();
@@ -261,11 +275,4 @@ public class RenderTheme implements IRenderTheme {
t.matchElement(GeometryType.POLY, e.tags, 16);
t.matchElement(GeometryType.POLY, e.tags, 15);
}
-
- @Override
- public void updateStyles() {
- // TODO Auto-generated method stub
-
- }
-
}
diff --git a/vtm-playground/src/org/oscim/test/DebugTheme.java b/vtm-playground/src/org/oscim/test/DebugTheme.java
index ad1390a2..7845850f 100644
--- a/vtm-playground/src/org/oscim/test/DebugTheme.java
+++ b/vtm-playground/src/org/oscim/test/DebugTheme.java
@@ -2,6 +2,7 @@ package org.oscim.test;
import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer.GeometryType;
+import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.theme.IRenderTheme;
import org.oscim.theme.styles.AreaStyle;
@@ -46,6 +47,16 @@ public class DebugTheme implements IRenderTheme {
public void scaleTextSize(float scaleFactor) {
}
+ @Override
+ public String transformKey(String key) {
+ return null;
+ }
+
+ @Override
+ public Tag transformTag(Tag tag) {
+ return null;
+ }
+
@Override
public void updateStyles() {
}
diff --git a/vtm-themes/resources/assets/vtm/mapzen.xml b/vtm-themes/resources/assets/vtm/mapzen.xml
index 01c896a5..ec17fc38 100644
--- a/vtm-themes/resources/assets/vtm/mapzen.xml
+++ b/vtm-themes/resources/assets/vtm/mapzen.xml
@@ -3,6 +3,17 @@
version="1" xmlns="http://opensciencemap.org/rendertheme"
xsi:schemaLocation="http://opensciencemap.org/rendertheme https://raw.githubusercontent.com/mapsforge/vtm/master/resources/rendertheme.xsd">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vtm-themes/resources/assets/vtm/openmaptiles.xml b/vtm-themes/resources/assets/vtm/openmaptiles.xml
index 5453f06d..79282f32 100644
--- a/vtm-themes/resources/assets/vtm/openmaptiles.xml
+++ b/vtm-themes/resources/assets/vtm/openmaptiles.xml
@@ -3,6 +3,11 @@
version="1" xmlns="http://opensciencemap.org/rendertheme"
xsi:schemaLocation="http://opensciencemap.org/rendertheme https://raw.githubusercontent.com/mapsforge/vtm/master/resources/rendertheme.xsd">
+
+
+
+
+
diff --git a/vtm/src/org/oscim/core/MapElement.java b/vtm/src/org/oscim/core/MapElement.java
index b6b69b34..0cbc8ef2 100644
--- a/vtm/src/org/oscim/core/MapElement.java
+++ b/vtm/src/org/oscim/core/MapElement.java
@@ -19,6 +19,8 @@
*/
package org.oscim.core;
+import org.oscim.theme.IRenderTheme;
+
/**
* The MapElement class is a reusable container for a geometry
* with tags.
@@ -63,10 +65,9 @@ public class MapElement extends GeometryBuffer {
/**
* @return height in meters, if present
*/
- public Float getHeight() {
- String v = tags.getValue(Tag.KEY_HEIGHT);
- if (v == null)
- v = tags.getValue("render_height"); // OpenMapTiles
+ public Float getHeight(IRenderTheme theme) {
+ String res = theme.transformKey(Tag.KEY_HEIGHT);
+ String v = tags.getValue(res != null ? res : Tag.KEY_HEIGHT);
if (v != null)
return Float.parseFloat(v);
return null;
@@ -75,22 +76,21 @@ public class MapElement extends GeometryBuffer {
/**
* @return minimum height in meters, if present
*/
- public Float getMinHeight() {
- String v = tags.getValue(Tag.KEY_MIN_HEIGHT);
- if (v == null)
- v = tags.getValue("render_min_height"); // OpenMapTiles
+ public Float getMinHeight(IRenderTheme theme) {
+ String res = theme.transformKey(Tag.KEY_MIN_HEIGHT);
+ String v = tags.getValue(res != null ? res : Tag.KEY_MIN_HEIGHT);
if (v != null)
return Float.parseFloat(v);
return null;
}
- public boolean isBuilding() {
+ public boolean isBuilding() { // TODO from themes (with overzoom ref)
return tags.containsKey(Tag.KEY_BUILDING)
|| "building".equals(tags.getValue("kind")) // Mapzen
|| "building".equals(tags.getValue("layer")); // OpenMapTiles
}
- public boolean isBuildingPart() {
+ public boolean isBuildingPart() { // TODO from themes (with overzoom ref)
return tags.containsKey(Tag.KEY_BUILDING_PART)
|| "building_part".equals(tags.getValue("kind")) // Mapzen
|| "building:part".equals(tags.getValue("layer")); // OpenMapTiles
diff --git a/vtm/src/org/oscim/core/Tag.java b/vtm/src/org/oscim/core/Tag.java
index 808fd069..03105a0d 100644
--- a/vtm/src/org/oscim/core/Tag.java
+++ b/vtm/src/org/oscim/core/Tag.java
@@ -65,9 +65,9 @@ public class Tag {
public static final String KEY_BUILDING_MATERIAL = "building:material";
public static final String KEY_BUILDING_MIN_LEVEL = "building:min_level";
public static final String KEY_BUILDING_PART = "building:part";
- public static final String KEY_COLOR = "colour";
+ //public static final String KEY_COLOR = "colour";
public static final String KEY_HEIGHT = "height";
- public static final String KEY_MATERIAL = "material";
+ //public static final String KEY_MATERIAL = "material";
public static final String KEY_MIN_HEIGHT = "min_height";
public static final String KEY_ROOF = "roof";
public static final String KEY_ROOF_ANGLE = "roof:angle";
diff --git a/vtm/src/org/oscim/layers/tile/buildings/BuildingLayer.java b/vtm/src/org/oscim/layers/tile/buildings/BuildingLayer.java
index 9e63cffb..985b1f10 100644
--- a/vtm/src/org/oscim/layers/tile/buildings/BuildingLayer.java
+++ b/vtm/src/org/oscim/layers/tile/buildings/BuildingLayer.java
@@ -31,6 +31,7 @@ import org.oscim.renderer.OffscreenRenderer;
import org.oscim.renderer.OffscreenRenderer.Mode;
import org.oscim.renderer.bucket.ExtrusionBuckets;
import org.oscim.renderer.bucket.RenderBuckets;
+import org.oscim.theme.IRenderTheme;
import org.oscim.theme.styles.ExtrusionStyle;
import org.oscim.theme.styles.RenderStyle;
@@ -66,6 +67,8 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
private final ZoomLimiter mZoomLimiter;
+ protected final IRenderTheme mRenderTheme;
+
class BuildingElement {
MapElement element;
ExtrusionStyle style;
@@ -103,6 +106,8 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
mRenderer = new BuildingRenderer(tileLayer.tileRenderer(), mZoomLimiter, mesh, TRANSLUCENT);
if (POST_AA)
mRenderer = new OffscreenRenderer(Mode.SSAO_FXAA, mRenderer);
+
+ mRenderTheme = tileLayer.getTheme();
}
@Override
@@ -160,22 +165,22 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
int height = 0; // cm
int minHeight = 0; // cm
- Float f = element.getHeight();
+ Float f = element.getHeight(mRenderTheme);
if (f != null)
height = (int) (f * 100);
else {
// #TagFromTheme: generalize level/height tags
- String v = element.tags.getValue(Tag.KEY_BUILDING_LEVELS);
+ String v = getValue(element, Tag.KEY_BUILDING_LEVELS);
if (v != null)
height = (int) (Float.parseFloat(v) * BUILDING_LEVEL_HEIGHT);
}
- f = element.getMinHeight();
+ f = element.getMinHeight(mRenderTheme);
if (f != null)
minHeight = (int) (f * 100);
else {
// #TagFromTheme: level/height tags
- String v = element.tags.getValue(Tag.KEY_BUILDING_MIN_LEVEL);
+ String v = getValue(element, Tag.KEY_BUILDING_MIN_LEVEL);
if (v != null)
minHeight = (int) (Float.parseFloat(v) * BUILDING_LEVEL_HEIGHT);
}
@@ -202,15 +207,14 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
if (!partBuilding.element.isBuildingPart())
continue;
- String refId = partBuilding.element.tags.getValue(Tag.KEY_REF); // #TagFromTheme
- refId = refId == null ? partBuilding.element.tags.getValue("root_id") : refId; // Mapzen
+ String refId = getValue(partBuilding.element, Tag.KEY_REF);
if (refId == null)
continue;
// Search buildings which inherit parts
for (BuildingElement rootBuilding : tileBuildings) {
if (rootBuilding.element.isBuildingPart()
- || !(refId.equals(rootBuilding.element.tags.getValue(Tag.KEY_ID))))
+ || !(refId.equals(getValue(rootBuilding.element, Tag.KEY_ID))))
continue;
rootBuildings.add(rootBuilding);
@@ -239,6 +243,15 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook, ZoomLim
return ebs;
}
+ protected String getKeyOrDefault(String key) {
+ String res = mRenderTheme.transformKey(key);
+ return res != null ? res : key;
+ }
+
+ protected String getValue(MapElement element, String key) {
+ return element.tags.getValue(getKeyOrDefault(key));
+ }
+
@Override
public void complete(MapTile tile, boolean success) {
if (success) {
diff --git a/vtm/src/org/oscim/layers/tile/buildings/S3DBLayer.java b/vtm/src/org/oscim/layers/tile/buildings/S3DBLayer.java
index ef9e0897..93b0cee5 100644
--- a/vtm/src/org/oscim/layers/tile/buildings/S3DBLayer.java
+++ b/vtm/src/org/oscim/layers/tile/buildings/S3DBLayer.java
@@ -101,12 +101,12 @@ public class S3DBLayer extends BuildingLayer {
int roofHeight = 0;
// Get roof height
- String v = element.tags.getValue(Tag.KEY_ROOF_HEIGHT);
+ String v = getValue(element, Tag.KEY_ROOF_HEIGHT);
if (v != null) {
roofHeight = (int) (Float.parseFloat(v) * 100);
- } else if ((v = element.tags.getValue(Tag.KEY_ROOF_LEVELS)) != null) {
+ } else if ((v = getValue(element, Tag.KEY_ROOF_LEVELS)) != null) {
roofHeight = (int) (Float.parseFloat(v) * BUILDING_LEVEL_HEIGHT);
- } else if ((v = element.tags.getValue(Tag.KEY_ROOF_ANGLE)) != null) {
+ } else if ((v = getValue(element, Tag.KEY_ROOF_ANGLE)) != null) {
Box bb = null;
for (int k = 0; k < element.index[0]; k += 2) {
float p1 = element.points[k];
@@ -122,17 +122,17 @@ public class S3DBLayer extends BuildingLayer {
// Angle is simplified, 40 is an estimated constant
roofHeight = (int) ((Float.parseFloat(v) / 45.f) * (minSize * 40));
}
- } else if ((v = element.tags.getValue(Tag.KEY_ROOF_SHAPE)) != null && !v.equals(Tag.VALUE_FLAT)) {
+ } else if ((v = getValue(element, Tag.KEY_ROOF_SHAPE)) != null && !v.equals(Tag.VALUE_FLAT)) {
roofHeight = (2 * BUILDING_LEVEL_HEIGHT);
}
// Get building height
- v = element.tags.getValue(Tag.KEY_HEIGHT);
+ v = getValue(element, Tag.KEY_HEIGHT);
if (v != null) {
maxHeight = (int) (Float.parseFloat(v) * 100);
} else {
// #TagFromTheme: generalize level/height tags
- if ((v = element.tags.getValue(Tag.KEY_BUILDING_LEVELS)) != null) {
+ if ((v = getValue(element, Tag.KEY_BUILDING_LEVELS)) != null) {
maxHeight = (int) (Float.parseFloat(v) * BUILDING_LEVEL_HEIGHT);
maxHeight += roofHeight;
}
@@ -140,22 +140,22 @@ public class S3DBLayer extends BuildingLayer {
if (maxHeight == 0)
maxHeight = extrusion.defaultHeight * 100;
- v = element.tags.getValue(Tag.KEY_MIN_HEIGHT);
+ v = getValue(element, Tag.KEY_MIN_HEIGHT);
if (v != null)
minHeight = (int) (Float.parseFloat(v) * 100);
else {
// #TagFromTheme: level/height tags
- if ((v = element.tags.getValue(Tag.KEY_BUILDING_MIN_LEVEL)) != null)
+ if ((v = getValue(element, Tag.KEY_BUILDING_MIN_LEVEL)) != null)
minHeight = (int) (Float.parseFloat(v) * BUILDING_LEVEL_HEIGHT);
}
// Get building color
Integer bColor = null;
if (mColored) {
- if (element.tags.containsKey(Tag.KEY_BUILDING_COLOR)) {
- bColor = S3DBUtils.getColor(element.tags.getValue(Tag.KEY_BUILDING_COLOR), false, false);
- } else if (element.tags.containsKey(Tag.KEY_BUILDING_MATERIAL)) {
- bColor = S3DBUtils.getMaterialColor(element.tags.getValue(Tag.KEY_BUILDING_MATERIAL), false);
+ if ((v = getValue(element, Tag.KEY_BUILDING_COLOR)) != null) {
+ bColor = S3DBUtils.getColor(v, false, false);
+ } else if ((v = getValue(element, Tag.KEY_BUILDING_MATERIAL)) != null) {
+ bColor = S3DBUtils.getMaterialColor(v, false);
}
}
@@ -190,25 +190,32 @@ public class S3DBLayer extends BuildingLayer {
if (!partBuilding.element.isBuildingPart())
continue;
- TagSet partTags = partBuilding.element.tags;
- String refId = partTags.getValue(Tag.KEY_REF); // #TagFromTheme
- refId = refId == null ? partTags.getValue("root_id") : refId; // Mapzen
+ String refId = getValue(partBuilding.element, Tag.KEY_REF);
if (refId == null)
continue;
+ TagSet partTags = partBuilding.element.tags;
+
// Search buildings which inherit parts
for (BuildingElement rootBuilding : tileBuildings) {
if (rootBuilding.element.isBuildingPart()
|| !(refId.equals(rootBuilding.element.tags.getValue(Tag.KEY_ID))))
continue;
+ if ((getValue(rootBuilding.element, Tag.KEY_ROOF_SHAPE) != null)
+ && (getValue(partBuilding.element, Tag.KEY_ROOF_SHAPE) == null)) {
+ partBuilding.element.tags.add(rootBuilding.element.tags.get(getKeyOrDefault(Tag.KEY_ROOF_SHAPE)));
+ }
+
if (mColored) {
TagSet rootTags = rootBuilding.element.tags;
+
for (int i = 0; i < rootTags.size(); i++) {
Tag rTag = rootTags.get(i);
- if ((rTag.key.equals(Tag.KEY_COLOR) && !partTags.containsKey(Tag.KEY_MATERIAL)
- || rTag.key.equals(Tag.KEY_ROOF_COLOR) && !partTags.containsKey(Tag.KEY_ROOF_MATERIAL)
- || rTag.key.equals(Tag.KEY_ROOF_SHAPE))
+ if ((rTag.key.equals(getKeyOrDefault(Tag.KEY_BUILDING_COLOR))
+ && !partTags.containsKey(getKeyOrDefault(Tag.KEY_BUILDING_MATERIAL))
+ || rTag.key.equals(getKeyOrDefault(Tag.KEY_ROOF_COLOR))
+ && !partTags.containsKey(getKeyOrDefault(Tag.KEY_ROOF_MATERIAL)))
&& !partTags.containsKey(rTag.key)) {
partTags.add(rTag);
}
@@ -243,22 +250,22 @@ public class S3DBLayer extends BuildingLayer {
String v;
if (mColored) {
- v = element.tags.getValue(Tag.KEY_ROOF_COLOR);
+ v = getValue(element, Tag.KEY_ROOF_COLOR);
if (v != null)
roofColor = S3DBUtils.getColor(v, true, false);
- else if ((v = element.tags.getValue(Tag.KEY_ROOF_MATERIAL)) != null)
+ else if ((v = getValue(element, Tag.KEY_ROOF_MATERIAL)) != null)
roofColor = S3DBUtils.getMaterialColor(v, true);
}
boolean roofOrientationAcross = false;
- if ((v = element.tags.getValue(Tag.KEY_ROOF_ORIENTATION)) != null) {
+ if ((v = getValue(element, Tag.KEY_ROOF_ORIENTATION)) != null) {
if (v.equals(Tag.VALUE_ACROSS)) {
roofOrientationAcross = true;
}
}
// Calc roof shape
- v = element.tags.getValue(Tag.KEY_ROOF_SHAPE);
+ v = getValue(element, Tag.KEY_ROOF_SHAPE);
if (v == null) {
v = Tag.VALUE_FLAT;
}
diff --git a/vtm/src/org/oscim/theme/IRenderTheme.java b/vtm/src/org/oscim/theme/IRenderTheme.java
index 5973a984..e7725f5d 100644
--- a/vtm/src/org/oscim/theme/IRenderTheme.java
+++ b/vtm/src/org/oscim/theme/IRenderTheme.java
@@ -2,6 +2,7 @@
* Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2013 Hannes Janetzek
* Copyright 2017 devemux86
+ * Copyright 2018 Gustl22
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -19,6 +20,7 @@
package org.oscim.theme;
import org.oscim.core.GeometryBuffer.GeometryType;
+import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.theme.styles.RenderStyle;
@@ -63,6 +65,16 @@ public interface IRenderTheme {
*/
void scaleTextSize(float scaleFactor);
+ /**
+ * @return the transformed tag key of this RenderTheme.
+ */
+ String transformKey(String key);
+
+ /**
+ * @return the transformed tag of this RenderTheme.
+ */
+ Tag transformTag(Tag tag);
+
class ThemeException extends IllegalArgumentException {
public ThemeException(String string) {
super(string);
diff --git a/vtm/src/org/oscim/theme/RenderTheme.java b/vtm/src/org/oscim/theme/RenderTheme.java
index a3f787da..974f3076 100644
--- a/vtm/src/org/oscim/theme/RenderTheme.java
+++ b/vtm/src/org/oscim/theme/RenderTheme.java
@@ -2,6 +2,7 @@
* Copyright 2014 Hannes Janetzek
* Copyright 2017 Longri
* Copyright 2017 devemux86
+ * Copyright 2018 Gustl22
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -19,6 +20,7 @@
package org.oscim.theme;
import org.oscim.core.GeometryBuffer.GeometryType;
+import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.theme.rule.Rule;
import org.oscim.theme.rule.Rule.Element;
@@ -31,6 +33,7 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
public class RenderTheme implements IRenderTheme {
static final Logger log = LoggerFactory.getLogger(RenderTheme.class);
@@ -44,6 +47,9 @@ public class RenderTheme implements IRenderTheme {
private final Rule[] mRules;
private final boolean mMapsforgeTheme;
+ private final Map mTransformKeyMap;
+ private final Map mTransformTagMap;
+
class RenderStyleCache {
final int matchType;
final LRUCache cache;
@@ -79,7 +85,17 @@ public class RenderTheme implements IRenderTheme {
this(mapBackground, baseTextSize, rules, levels, false);
}
+ public RenderTheme(int mapBackground, float baseTextSize, Rule[] rules, int levels,
+ Map transformKeyMap, Map transformTagMap) {
+ this(mapBackground, baseTextSize, rules, levels, transformKeyMap, transformTagMap, false);
+ }
+
public RenderTheme(int mapBackground, float baseTextSize, Rule[] rules, int levels, boolean mapsforgeTheme) {
+ this(mapBackground, baseTextSize, rules, levels, null, null, mapsforgeTheme);
+ }
+
+ public RenderTheme(int mapBackground, float baseTextSize, Rule[] rules, int levels,
+ Map transformKeyMap, Map transformTagMap, boolean mapsforgeTheme) {
if (rules == null)
throw new IllegalArgumentException("rules missing");
@@ -89,6 +105,9 @@ public class RenderTheme implements IRenderTheme {
mRules = rules;
mMapsforgeTheme = mapsforgeTheme;
+ mTransformKeyMap = transformKeyMap;
+ mTransformTagMap = transformTagMap;
+
mStyleCache = new RenderStyleCache[3];
mStyleCache[0] = new RenderStyleCache(Element.NODE);
mStyleCache[1] = new RenderStyleCache(Element.LINE);
@@ -272,6 +291,20 @@ public class RenderTheme implements IRenderTheme {
rule.scaleTextSize(scaleFactor * mBaseTextSize);
}
+ @Override
+ public String transformKey(String key) {
+ if (mTransformKeyMap != null)
+ return mTransformKeyMap.get(key);
+ return null;
+ }
+
+ @Override
+ public Tag transformTag(Tag tag) {
+ if (mTransformTagMap != null)
+ return mTransformTagMap.get(tag);
+ return null;
+ }
+
@Override
public void updateStyles() {
for (Rule rule : mRules)
diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
index c5640d34..9681ba53 100644
--- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java
+++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
@@ -4,6 +4,7 @@
* Copyright 2016-2018 devemux86
* Copyright 2016-2017 Longri
* Copyright 2016 Andrey Novikov
+ * Copyright 2018 Gustl22
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -64,6 +65,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.Stack;
@@ -168,6 +170,9 @@ public class XmlThemeBuilder extends DefaultHandler {
private XmlRenderThemeStyleLayer mCurrentLayer;
private XmlRenderThemeStyleMenu mRenderThemeStyleMenu;
+ private Map mTransformKeyMap = new HashMap<>();
+ private Map mTransformTagMap = new HashMap<>();
+
public XmlThemeBuilder(ThemeFile theme) {
this(theme, null);
}
@@ -202,7 +207,7 @@ public class XmlThemeBuilder extends DefaultHandler {
}
RenderTheme createTheme(Rule[] rules) {
- return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mMapsforgeTheme);
+ return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mMapsforgeTheme);
}
@Override
@@ -369,6 +374,10 @@ public class XmlThemeBuilder extends DefaultHandler {
mRenderThemeStyleMenu = new XmlRenderThemeStyleMenu(getStringAttribute(attributes, "id"),
getStringAttribute(attributes, "defaultlang"), getStringAttribute(attributes, "defaultvalue"));
+ } else if ("tag-transform".equals(localName)) {
+ checkState(qName, Element.RENDERING_STYLE);
+ tagTransform(localName, attributes);
+
} else {
log.error("unknown element: {}", localName);
throw new SAXException("unknown element: " + localName);
@@ -1239,6 +1248,44 @@ public class XmlThemeBuilder extends DefaultHandler {
return dashIntervals;
}
+ private void tagTransform(String localName, Attributes attributes) {
+ String k, v, matchKey, matchValue;
+ k = v = matchKey = matchValue = null;
+
+ for (int i = 0; i < attributes.getLength(); i++) {
+ String name = attributes.getLocalName(i);
+ String value = attributes.getValue(i);
+
+ switch (name) {
+ case "k":
+ k = value;
+ break;
+ case "v":
+ v = value;
+ break;
+ case "k-match":
+ matchKey = value;
+ break;
+ case "v-match":
+ matchValue = value;
+ break;
+ default:
+ logUnknownAttribute(localName, name, value, i);
+ }
+ }
+
+ if (k == null || k.isEmpty() || matchKey == null || matchKey.isEmpty()) {
+ log.debug("empty key in element " + localName);
+ return;
+ }
+
+ if (v == null && matchValue == null) {
+ mTransformKeyMap.put(matchKey, k);
+ } else {
+ mTransformTagMap.put(new Tag(matchKey, matchValue), new Tag(k, v));
+ }
+ }
+
private static void validateNonNegative(String name, float value) {
if (value < 0)
throw new ThemeException(name + " must not be negative: "