diff --git a/vtm-android-app b/vtm-android-app
index 43a6277c..7449e47e 160000
--- a/vtm-android-app
+++ b/vtm-android-app
@@ -1 +1 @@
-Subproject commit 43a6277c1aa089f778f10ec1f2fd9b7034e63f0a
+Subproject commit 7449e47e8ec147c816eb3b8b77d07109035fab4d
diff --git a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java
index 93728447..08e5f616 100644
--- a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java
+++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java
@@ -22,7 +22,7 @@ import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
-import org.oscim.theme.RenderThemeHandler;
+import org.oscim.theme.XmlThemeBuilder;
import org.oscim.tiling.TileSource.OpenResult;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -40,7 +40,7 @@ public final class ValidRenderTheme implements ValidFileFilter {
try {
inputStream = new FileInputStream(file);
- RenderThemeHandler renderThemeHandler = new RenderThemeHandler();
+ XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder();
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
xmlReader.setContentHandler(renderThemeHandler);
xmlReader.parse(new InputSource(inputStream));
diff --git a/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java b/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java
index 8f47e9ec..60a41530 100644
--- a/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java
+++ b/vtm-jeo/src/org/oscim/layers/JeoVectorLayer.java
@@ -15,8 +15,8 @@ import org.oscim.jeo.JeoUtils;
import org.oscim.map.Map;
import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.MeshLayer;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.LineStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,7 +117,7 @@ public class JeoVectorLayer extends JtsLayer {
if (ll.line == null) {
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
- ll.line = new Line(0, JeoUtils.color(color), width);
+ ll.line = new LineStyle(0, JeoUtils.color(color), width);
ll.setDropDistance(0.5f);
}
@@ -131,14 +131,14 @@ public class JeoVectorLayer extends JtsLayer {
if (ll.line == null) {
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
- ll.line = new Line(0, JeoUtils.color(color), width);
+ ll.line = new LineStyle(0, JeoUtils.color(color), width);
ll.setDropDistance(0.5f);
}
MeshLayer mesh = t.layers.getMeshLayer(0);
if (mesh.area == null) {
int color = JeoUtils.color(rule.color(f, CartoCSS.POLYGON_FILL, RGB.red));
- mesh.area = new Area(color);
+ mesh.area = new AreaStyle(color);
}
addPolygon(t, g, mesh, ll);
diff --git a/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java b/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java
index 11139ea8..688145cb 100644
--- a/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java
+++ b/vtm-jeo/src/org/oscim/layers/OSMIndoorLayer.java
@@ -15,9 +15,10 @@ import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.MeshLayer;
import org.oscim.renderer.elements.TextItem;
import org.oscim.renderer.elements.TextLayer;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.LineStyle;
+import org.oscim.theme.styles.TextStyle;
+import org.oscim.theme.styles.TextStyle.TextBuilder;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
@@ -26,7 +27,10 @@ import com.vividsolutions.jts.geom.LineString;
public class OSMIndoorLayer extends JeoVectorLayer {
protected TextLayer mTextLayer;
- protected Text mText = Text.createText(16, 2.2f, Color.BLACK, Color.WHITE, true);
+ protected TextStyle mText = new TextBuilder()
+ .setFontSize(16).setColor(Color.BLACK)
+ .setStrokeWidth(2.2f).setStroke(Color.WHITE)
+ .build();
public OSMIndoorLayer(Map map, VectorDataset data, Style style) {
super(map, data, style);
@@ -58,7 +62,7 @@ public class OSMIndoorLayer extends JeoVectorLayer {
if (ll.line == null) {
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
- ll.line = new Line(0, JeoUtils.color(color), width);
+ ll.line = new LineStyle(0, JeoUtils.color(color), width);
ll.heightOffset = level * 4;
ll.setDropDistance(0);
}
@@ -80,7 +84,7 @@ public class OSMIndoorLayer extends JeoVectorLayer {
if (level > -2 && !active)
color = Color.fade(color, 0.1f);
- ll.line = new Line(0, color, width);
+ ll.line = new LineStyle(0, color, width);
ll.heightOffset = level * 4;
ll.setDropDistance(0);
}
@@ -91,7 +95,7 @@ public class OSMIndoorLayer extends JeoVectorLayer {
if (level > -2 && !active)
color = Color.fade(color, 0.1f);
- mesh.area = new Area(color);
+ mesh.area = new AreaStyle(color);
//mesh.area = new Area(Color.fade(Color.DKGRAY, 0.1f));
mesh.heightOffset = level * 4f;
}
diff --git a/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java b/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
index 92c7f398..5fb4ea01 100644
--- a/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
+++ b/vtm-jeo/src/org/oscim/theme/carto/RenderTheme.java
@@ -19,8 +19,8 @@ import org.oscim.core.MapElement;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.theme.IRenderTheme;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.theme.styles.RenderStyle;
public class RenderTheme implements IRenderTheme {
@@ -147,11 +147,11 @@ public class RenderTheme implements IRenderTheme {
}
if (p != null) {
- s.ri[0] = new Area(mCurLevel++, color(p));
+ s.ri[0] = new AreaStyle(mCurLevel++, color(p));
}
if (l != null) {
- s.ri[1] = new Line(mCurLevel++, color(l), 1);
+ s.ri[1] = new LineStyle(mCurLevel++, color(l), 1);
}
if (p != null || l != null) {
@@ -198,7 +198,7 @@ public class RenderTheme implements IRenderTheme {
RGB c = r.color(f, CartoCSS.POLYGON_FILL, RGB.black);
out.println(z + " " + c);
return new RenderStyle[] {
- new Area(z, color(c))
+ new AreaStyle(z, color(c))
};
} else if (type == GeometryType.LINE) {
@@ -207,7 +207,7 @@ public class RenderTheme implements IRenderTheme {
//out.println(z + " " + c);
return new RenderStyle[] {
- new Line(100 + z, color(c), width)
+ new LineStyle(100 + z, color(c), width)
};
} else if (type == GeometryType.POINT) {
@@ -258,7 +258,7 @@ public class RenderTheme implements IRenderTheme {
}
@Override
- public void updateInstructions() {
+ public void updateStyles() {
// TODO Auto-generated method stub
}
diff --git a/vtm-themes/resources/assets/styles/default.xml b/vtm-themes/resources/assets/styles/default.xml
index c2e33b93..9b40e02a 100644
--- a/vtm-themes/resources/assets/styles/default.xml
+++ b/vtm-themes/resources/assets/styles/default.xml
@@ -79,7 +79,7 @@
stipple-stroke="#be6253" />
-
+
@@ -143,7 +143,7 @@
-
+
@@ -151,11 +151,11 @@
-
+
-
+
@@ -1064,7 +1064,10 @@
-
+
+
+
+
@@ -1089,7 +1092,9 @@
-
+
+
+
@@ -1152,7 +1157,9 @@
-
+
+
+
@@ -1176,17 +1183,18 @@
-
+
+
-
-
-
+
+
+
+
-
@@ -1200,7 +1208,10 @@
-
+
+
+
+
diff --git a/vtm-themes/resources/assets/styles/osmarender.xml b/vtm-themes/resources/assets/styles/osmarender.xml
index 18ed3052..5ae034bc 100644
--- a/vtm-themes/resources/assets/styles/osmarender.xml
+++ b/vtm-themes/resources/assets/styles/osmarender.xml
@@ -779,19 +779,19 @@
-
+
-
+
-
+
@@ -803,69 +803,69 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/vtm-themes/resources/assets/styles/tronrender.xml b/vtm-themes/resources/assets/styles/tronrender.xml
index 9d3d007d..a37c8cb5 100644
--- a/vtm-themes/resources/assets/styles/tronrender.xml
+++ b/vtm-themes/resources/assets/styles/tronrender.xml
@@ -2,7 +2,7 @@
-
+
@@ -62,10 +62,10 @@
-
-
-
+
@@ -1312,7 +1312,7 @@
-
+
@@ -1332,7 +1332,7 @@
-
+
diff --git a/vtm/src/org/oscim/layers/PathLayer.java b/vtm/src/org/oscim/layers/PathLayer.java
index 7f05b6be..d6aaf286 100644
--- a/vtm/src/org/oscim/layers/PathLayer.java
+++ b/vtm/src/org/oscim/layers/PathLayer.java
@@ -32,7 +32,7 @@ import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.FastMath;
import org.oscim.utils.async.SimpleWorker;
import org.oscim.utils.geom.LineClipper;
@@ -45,14 +45,14 @@ public class PathLayer extends Layer {
protected boolean mUpdatePoints;
/** Line style */
- Line mLineStyle;
+ LineStyle mLineStyle;
final Worker mWorker;
public PathLayer(Map map, int lineColor, float lineWidth) {
super(map);
mWorker = new Worker(map);
- mLineStyle = new Line(lineColor, lineWidth, Cap.BUTT);
+ mLineStyle = new LineStyle(lineColor, lineWidth, Cap.BUTT);
mRenderer = new RenderPath();
mPoints = new ArrayList();
}
diff --git a/vtm/src/org/oscim/layers/TileGridLayer.java b/vtm/src/org/oscim/layers/TileGridLayer.java
index 7ab673a5..541521d9 100644
--- a/vtm/src/org/oscim/layers/TileGridLayer.java
+++ b/vtm/src/org/oscim/layers/TileGridLayer.java
@@ -3,8 +3,8 @@ package org.oscim.layers;
import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.map.Map;
import org.oscim.renderer.GridRenderer;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.LineStyle;
+import org.oscim.theme.styles.TextStyle;
public class TileGridLayer extends GenericLayer {
@@ -13,10 +13,10 @@ public class TileGridLayer extends GenericLayer {
}
public TileGridLayer(Map map, int color, float width, int repeat) {
- super(map, new GridRenderer(repeat, new Line(color, width, Cap.BUTT), null));
+ super(map, new GridRenderer(repeat, new LineStyle(color, width, Cap.BUTT), null));
}
- public TileGridLayer(Map map, int color, float width, Text text, int repeat) {
- super(map, new GridRenderer(repeat, new Line(color, width, Cap.BUTT), text));
+ public TileGridLayer(Map map, int color, float width, TextStyle text, int repeat) {
+ super(map, new GridRenderer(repeat, new LineStyle(color, width, Cap.BUTT), text));
}
}
diff --git a/vtm/src/org/oscim/layers/tile/example/TestTileLayer.java b/vtm/src/org/oscim/layers/tile/example/TestTileLayer.java
index bb38c7af..154bc7da 100644
--- a/vtm/src/org/oscim/layers/tile/example/TestTileLayer.java
+++ b/vtm/src/org/oscim/layers/tile/example/TestTileLayer.java
@@ -28,7 +28,7 @@ import org.oscim.layers.tile.VectorTileRenderer;
import org.oscim.map.Map;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.LineStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -52,7 +52,7 @@ public class TestTileLayer extends TileLayer {
}
GeometryBuffer mGeom = new GeometryBuffer(128, 16);
- Line mLineStyle = new Line(Color.BLUE, 2f, Cap.ROUND);
+ LineStyle mLineStyle = new LineStyle(Color.BLUE, 2f, Cap.ROUND);
@Override
public boolean loadTile(MapTile tile) {
diff --git a/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java b/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java
index fd50be23..e2549e14 100644
--- a/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java
+++ b/vtm/src/org/oscim/layers/tile/vector/VectorTileLoader.java
@@ -40,14 +40,13 @@ import org.oscim.renderer.elements.SymbolItem;
import org.oscim.renderer.elements.TextItem;
import org.oscim.theme.IRenderTheme;
import org.oscim.theme.RenderTheme;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Circle;
-import org.oscim.theme.styles.Extrusion;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.LineSymbol;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.CircleStyle;
+import org.oscim.theme.styles.ExtrusionStyle;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.theme.styles.RenderStyle;
-import org.oscim.theme.styles.Symbol;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.SymbolStyle;
+import org.oscim.theme.styles.TextStyle;
import org.oscim.tiling.ITileDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -248,7 +247,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
/*** RenderThemeCallback ***/
@Override
- public void renderWay(Line line, int level) {
+ public void renderWay(LineStyle line, int level) {
int numLayer = mCurLayer + level;
if (line.stipple == 0) {
@@ -297,7 +296,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
protected final static boolean USE_MESH_POLY = false;
@Override
- public void renderArea(Area area, int level) {
+ public void renderArea(AreaStyle area, int level) {
int numLayer = mCurLayer + level;
if (USE_MESH_POLY) {
MeshLayer l = mTile.layers.getMeshLayer(numLayer);
@@ -311,7 +310,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
}
@Override
- public void renderAreaText(Text text) {
+ public void renderAreaText(TextStyle text) {
// TODO place somewhere on polygon
String value = mElement.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
@@ -332,7 +331,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
}
@Override
- public void renderPointText(Text text) {
+ public void renderPointText(TextStyle text) {
String value = mElement.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return;
@@ -344,7 +343,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
}
@Override
- public void renderWayText(Text text) {
+ public void renderWayText(TextStyle text) {
String value = mElement.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return;
@@ -362,11 +361,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
}
@Override
- public void renderPointCircle(Circle circle, int level) {
+ public void renderPointCircle(CircleStyle circle, int level) {
}
@Override
- public void renderPointSymbol(Symbol symbol) {
+ public void renderPointSymbol(SymbolStyle symbol) {
if (symbol.texture == null)
return;
@@ -380,16 +379,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
}
@Override
- public void renderAreaSymbol(Symbol symbol) {
+ public void renderAreaSymbol(SymbolStyle symbol) {
}
@Override
- public void renderWaySymbol(LineSymbol symbol) {
-
- }
-
- @Override
- public void renderExtrusion(Extrusion extrusion, int level) {
+ public void renderExtrusion(ExtrusionStyle extrusion, int level) {
int height = 0;
int minHeight = 0;
diff --git a/vtm/src/org/oscim/layers/tile/vector/WayDecorator.java b/vtm/src/org/oscim/layers/tile/vector/WayDecorator.java
index 89148307..0bbb7378 100644
--- a/vtm/src/org/oscim/layers/tile/vector/WayDecorator.java
+++ b/vtm/src/org/oscim/layers/tile/vector/WayDecorator.java
@@ -20,14 +20,14 @@ package org.oscim.layers.tile.vector;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.renderer.elements.TextItem;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.TextStyle;
import org.oscim.utils.geom.GeometryUtils;
import org.oscim.utils.geom.LineClipper;
public final class WayDecorator {
public static void renderText(LineClipper clipper, float[] coordinates, String string,
- Text text, int pos, int len, MapTile tile) {
+ TextStyle text, int pos, int len, MapTile tile) {
//TextItem items = textItems;
TextItem t = null;
diff --git a/vtm/src/org/oscim/layers/tile/vector/labeling/Debug.java b/vtm/src/org/oscim/layers/tile/vector/labeling/Debug.java
index 88c81cd1..fa8c69ca 100644
--- a/vtm/src/org/oscim/layers/tile/vector/labeling/Debug.java
+++ b/vtm/src/org/oscim/layers/tile/vector/labeling/Debug.java
@@ -22,7 +22,7 @@ import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.LineStyle;
class Debug {
@@ -71,12 +71,12 @@ class Debug {
int alpha = 0xaaffffff;
dbg.clear();
- dbg.addLineLayer(0, new Line((Color.BLUE & alpha), 2));
- dbg.addLineLayer(1, new Line((Color.RED & alpha), 2));
- dbg.addLineLayer(3, new Line((Color.YELLOW & alpha), 2));
- dbg.addLineLayer(2, new Line((Color.GREEN & alpha), 2));
- dbg.addLineLayer(4, new Line((Color.CYAN & alpha), 2));
- dbg.addLineLayer(5, new Line((Color.MAGENTA & alpha), 2));
+ dbg.addLineLayer(0, new LineStyle((Color.BLUE & alpha), 2));
+ dbg.addLineLayer(1, new LineStyle((Color.RED & alpha), 2));
+ dbg.addLineLayer(3, new LineStyle((Color.YELLOW & alpha), 2));
+ dbg.addLineLayer(2, new LineStyle((Color.GREEN & alpha), 2));
+ dbg.addLineLayer(4, new LineStyle((Color.CYAN & alpha), 2));
+ dbg.addLineLayer(5, new LineStyle((Color.MAGENTA & alpha), 2));
}
public static void draw(MapPosition pos, GLViewport m, ElementLayers layers) {
diff --git a/vtm/src/org/oscim/renderer/GridRenderer.java b/vtm/src/org/oscim/renderer/GridRenderer.java
index b970c79b..93da94d9 100644
--- a/vtm/src/org/oscim/renderer/GridRenderer.java
+++ b/vtm/src/org/oscim/renderer/GridRenderer.java
@@ -23,12 +23,13 @@ import org.oscim.core.Tile;
import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem;
import org.oscim.renderer.elements.TextLayer;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.LineStyle;
+import org.oscim.theme.styles.TextStyle;
+import org.oscim.theme.styles.TextStyle.TextBuilder;
public class GridRenderer extends ElementRenderer {
private final TextLayer mTextLayer;
- private final Text mText;
+ private final TextStyle mText;
private final LineLayer mLineLayer;
private final GeometryBuffer mLines;
private final StringBuffer mStringBuffer;
@@ -36,11 +37,11 @@ public class GridRenderer extends ElementRenderer {
private int mCurX, mCurY, mCurZ;
public GridRenderer() {
- this(1, new Line(Color.LTGRAY, 1.2f, Cap.BUTT),
- Text.createText(22, 0, Color.RED, 0, false));
+ this(1, new LineStyle(Color.LTGRAY, 1.2f, Cap.BUTT),
+ new TextBuilder().setFontSize(22).setColor(Color.RED).build());
}
- public GridRenderer(int numLines, Line lineStyle, Text textStyle) {
+ public GridRenderer(int numLines, LineStyle lineStyle, TextStyle textStyle) {
int size = Tile.SIZE;
// not needed to set but we know:
diff --git a/vtm/src/org/oscim/renderer/elements/ElementLayers.java b/vtm/src/org/oscim/renderer/elements/ElementLayers.java
index 756daeee..7671973a 100644
--- a/vtm/src/org/oscim/renderer/elements/ElementLayers.java
+++ b/vtm/src/org/oscim/renderer/elements/ElementLayers.java
@@ -25,8 +25,8 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20;
import org.oscim.renderer.BufferObject;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.LineStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,7 +83,7 @@ public class ElementLayers {
* add the LineLayer for a level with a given Line style. Levels are
* ordered from bottom (0) to top
*/
- public LineLayer addLineLayer(int level, Line style) {
+ public LineLayer addLineLayer(int level, LineStyle style) {
LineLayer l = (LineLayer) getLayer(level, LINE);
if (l == null)
return null;
@@ -93,7 +93,7 @@ public class ElementLayers {
return l;
}
- public PolygonLayer addPolygonLayer(int level, Area style) {
+ public PolygonLayer addPolygonLayer(int level, AreaStyle style) {
PolygonLayer l = (PolygonLayer) getLayer(level, POLYGON);
if (l == null)
return null;
@@ -101,7 +101,7 @@ public class ElementLayers {
return l;
}
- public MeshLayer addMeshLayer(int level, Area style) {
+ public MeshLayer addMeshLayer(int level, AreaStyle style) {
MeshLayer l = (MeshLayer) getLayer(level, MESH);
if (l == null)
return null;
diff --git a/vtm/src/org/oscim/renderer/elements/LineLayer.java b/vtm/src/org/oscim/renderer/elements/LineLayer.java
index 197944f1..796b4721 100644
--- a/vtm/src/org/oscim/renderer/elements/LineLayer.java
+++ b/vtm/src/org/oscim/renderer/elements/LineLayer.java
@@ -29,7 +29,7 @@ import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,7 +64,7 @@ public final class LineLayer extends RenderElement {
/* lines referenced by this outline layer */
public LineLayer outlines;
- public Line line;
+ public LineStyle line;
public float scale = 1;
public boolean roundCap;
@@ -749,7 +749,7 @@ public final class LineLayer extends RenderElement {
RenderElement l = curLayer;
for (; l != null && l.type == RenderElement.LINE; l = l.next) {
LineLayer ll = (LineLayer) l;
- Line line = (Line) ll.line.getCurrent();
+ LineStyle line = (LineStyle) ll.line.getCurrent();
if (ll.heightOffset != heightOffset) {
heightOffset = ll.heightOffset;
@@ -758,9 +758,9 @@ public final class LineLayer extends RenderElement {
MercatorProjection.groundResolution(v.pos));
}
- if (line.fade < v.pos.zoomLevel) {
+ if (line.fadeScale < v.pos.zoomLevel) {
GLUtils.setColor(uLineColor, line.color, 1);
- } else if (line.fade > v.pos.zoomLevel) {
+ } else if (line.fadeScale > v.pos.zoomLevel) {
continue;
} else {
float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1;
@@ -820,7 +820,7 @@ public final class LineLayer extends RenderElement {
/* draw LineLayers references by this outline */
for (LineLayer ref = ll.outlines; ref != null; ref = ref.outlines) {
- Line core = (Line) ref.line.getCurrent();
+ LineStyle core = (LineStyle) ref.line.getCurrent();
// core width
if (core.fixed) {
diff --git a/vtm/src/org/oscim/renderer/elements/LineTexLayer.java b/vtm/src/org/oscim/renderer/elements/LineTexLayer.java
index d91cdcfa..c7c5fbb1 100644
--- a/vtm/src/org/oscim/renderer/elements/LineTexLayer.java
+++ b/vtm/src/org/oscim/renderer/elements/LineTexLayer.java
@@ -26,7 +26,7 @@ import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -86,7 +86,7 @@ public final class LineTexLayer extends RenderElement {
/* lines referenced by this outline layer */
public LineLayer outlines;
- public Line line;
+ public LineStyle line;
public float width;
//public boolean roundCap;
@@ -362,7 +362,7 @@ public final class LineTexLayer extends RenderElement {
RenderElement l = curLayer;
for (; l != null && l.type == TEXLINE; l = l.next) {
LineTexLayer ll = (LineTexLayer) l;
- Line line = ll.line;
+ LineStyle line = ll.line;
GLUtils.setColor(hTexColor, line.stippleColor, 1);
GLUtils.setColor(hBgColor, line.color, 1);
diff --git a/vtm/src/org/oscim/renderer/elements/MeshLayer.java b/vtm/src/org/oscim/renderer/elements/MeshLayer.java
index 07cb80b0..59edce7c 100644
--- a/vtm/src/org/oscim/renderer/elements/MeshLayer.java
+++ b/vtm/src/org/oscim/renderer/elements/MeshLayer.java
@@ -27,7 +27,7 @@ import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
-import org.oscim.theme.styles.Area;
+import org.oscim.theme.styles.AreaStyle;
import org.oscim.utils.Tessellator;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
@@ -41,7 +41,7 @@ public class MeshLayer extends RenderElement {
int numIndices;
VertexItem indiceItems;
- public Area area;
+ public AreaStyle area;
public float heightOffset;
public MeshLayer(int level) {
diff --git a/vtm/src/org/oscim/renderer/elements/PolygonLayer.java b/vtm/src/org/oscim/renderer/elements/PolygonLayer.java
index 6b5db5d5..fe40349a 100644
--- a/vtm/src/org/oscim/renderer/elements/PolygonLayer.java
+++ b/vtm/src/org/oscim/renderer/elements/PolygonLayer.java
@@ -29,7 +29,7 @@ import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
-import org.oscim.theme.styles.Area;
+import org.oscim.theme.styles.AreaStyle;
import org.oscim.utils.FastMath;
import org.oscim.utils.math.Interpolation;
import org.oscim.utils.pool.Inlist;
@@ -46,7 +46,7 @@ public final class PolygonLayer extends RenderElement {
private static final boolean enableTexture = true;
- public Area area;
+ public AreaStyle area;
PolygonLayer(int layer) {
super(RenderElement.POLYGON);
@@ -181,7 +181,7 @@ public final class PolygonLayer extends RenderElement {
int shader = polyShader;
for (int c = start; c < end; c++) {
- Area a = (Area) mFillPolys[c].area.getCurrent();
+ AreaStyle a = (AreaStyle) mFillPolys[c].area.getCurrent();
if (enableTexture && a.texture != null) {
shader = texShader;
@@ -194,10 +194,10 @@ public final class PolygonLayer extends RenderElement {
GLState.blend(true);
a.texture.bind();
- } else if (a.fade >= zoom) {
+ } else if (a.fadeScale >= zoom) {
float f = 1.0f;
/* fade in/out */
- if (a.fade >= zoom) {
+ if (a.fadeScale >= zoom) {
if (scale > FADE_START)
f = scale - 1;
else
@@ -207,11 +207,11 @@ public final class PolygonLayer extends RenderElement {
GLUtils.setColor(hPolygonColor[shader], a.color, f);
- } else if (a.blend > 0 && a.blend <= zoom) {
+ } else if (a.blendScale > 0 && a.blendScale <= zoom) {
/* blend colors (not alpha) */
GLState.blend(false);
- if (a.blend == zoom)
+ if (a.blendScale == zoom)
GLUtils.setColorBlend(hPolygonColor[shader],
a.color, a.blendColor, scale - 1.0f);
else
@@ -301,7 +301,7 @@ public final class PolygonLayer extends RenderElement {
PolygonLayer pl = (PolygonLayer) l;
// fade out polygon layers (set in RenderTheme)
- if (pl.area.fade > 0 && pl.area.fade > zoom)
+ if (pl.area.fadeScale > 0 && pl.area.fadeScale > zoom)
continue;
if (cur == start) {
diff --git a/vtm/src/org/oscim/renderer/elements/TextItem.java b/vtm/src/org/oscim/renderer/elements/TextItem.java
index 1c48a99f..6185d6e2 100644
--- a/vtm/src/org/oscim/renderer/elements/TextItem.java
+++ b/vtm/src/org/oscim/renderer/elements/TextItem.java
@@ -16,7 +16,7 @@
*/
package org.oscim.renderer.elements;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.TextStyle;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.SyncPool;
@@ -57,7 +57,7 @@ public class TextItem extends Inlist {
return ti;
}
- public TextItem set(float x, float y, String string, Text text) {
+ public TextItem set(float x, float y, String string, TextStyle text) {
this.x = x;
this.y = y;
this.string = string;
@@ -77,7 +77,7 @@ public class TextItem extends Inlist {
public String string;
// text style
- public Text text;
+ public TextStyle text;
// label width
public float width;
diff --git a/vtm/src/org/oscim/renderer/test/AtlasRenderLayer.java b/vtm/src/org/oscim/renderer/test/AtlasRenderLayer.java
index af99a791..efb10ee0 100644
--- a/vtm/src/org/oscim/renderer/test/AtlasRenderLayer.java
+++ b/vtm/src/org/oscim/renderer/test/AtlasRenderLayer.java
@@ -28,8 +28,9 @@ import org.oscim.renderer.atlas.TextureAtlas.Slot;
import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem;
import org.oscim.renderer.elements.TextLayer;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.LineStyle;
+import org.oscim.theme.styles.TextStyle;
+import org.oscim.theme.styles.TextStyle.TextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,19 +43,19 @@ public class AtlasRenderLayer extends ElementRenderer {
TextureAtlas mAtlas = TextureAtlas.create(2048, 2048, 1);
LineLayer ll = layers.getLineLayer(0);
- ll.line = new Line(Color.BLUE, 3, Cap.BUTT);
+ ll.line = new LineStyle(Color.BLUE, 3, Cap.BUTT);
ll.scale = 1f;
LineLayer ll2 = layers.getLineLayer(1);
- ll2.line = new Line(Color.RED, 3, Cap.BUTT);
+ ll2.line = new LineStyle(Color.RED, 3, Cap.BUTT);
ll2.scale = 1f;
LineLayer ll3 = layers.getLineLayer(2);
- ll3.line = new Line(Color.GREEN, 3, Cap.BUTT);
+ ll3.line = new LineStyle(Color.GREEN, 3, Cap.BUTT);
ll3.scale = 1f;
TextLayer tl = new TextLayer();
- Text t = Text.createText(20, 0, Color.BLACK, 0, false);
+ TextStyle t = new TextBuilder().setFontSize(20).setColor(Color.BLACK).build();
layers.setTextureLayers(tl);
float[] points = new float[10];
diff --git a/vtm/src/org/oscim/renderer/test/BezierPathLayer.java b/vtm/src/org/oscim/renderer/test/BezierPathLayer.java
index e5eb9f59..adbf422d 100644
--- a/vtm/src/org/oscim/renderer/test/BezierPathLayer.java
+++ b/vtm/src/org/oscim/renderer/test/BezierPathLayer.java
@@ -8,7 +8,7 @@ import org.oscim.core.Point;
import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.LineLayer;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.geom.BezierPath;
public class BezierPathLayer extends ElementRenderer {
@@ -27,7 +27,7 @@ public class BezierPathLayer extends ElementRenderer {
// System.out.println(pts[i]);
g.addPoint(pts[i]);
}
- LineLayer ll = layers.addLineLayer(0, new Line(Color.BLUE, 2f));
+ LineLayer ll = layers.addLineLayer(0, new LineStyle(Color.BLUE, 2f));
ll.addLine(g);
List ctrl = BezierPath.cubicSplineControlPoints(pts, 0.1f);
@@ -49,7 +49,7 @@ public class BezierPathLayer extends ElementRenderer {
}
p0 = p3;
}
- ll = layers.addLineLayer(1, new Line(Color.CYAN, 2f));
+ ll = layers.addLineLayer(1, new LineStyle(Color.CYAN, 2f));
ll.addLine(g);
}
diff --git a/vtm/src/org/oscim/theme/DebugTheme.java b/vtm/src/org/oscim/theme/DebugTheme.java
index 9caaae8d..11998d2c 100644
--- a/vtm/src/org/oscim/theme/DebugTheme.java
+++ b/vtm/src/org/oscim/theme/DebugTheme.java
@@ -3,14 +3,14 @@ package org.oscim.theme;
import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.TagSet;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Line;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.theme.styles.RenderStyle;
public class DebugTheme implements IRenderTheme {
- private final static Line[] line = { new Line(1, Color.MAGENTA, 2) };
- private final static Area[] area = { new Area(0, Color.CYAN) };
+ private final static LineStyle[] line = { new LineStyle(1, Color.MAGENTA, 2) };
+ private final static AreaStyle[] area = { new AreaStyle(0, Color.CYAN) };
@Override
public RenderStyle[] matchElement(GeometryType type, TagSet tags, int zoomLevel) {
@@ -41,7 +41,7 @@ public class DebugTheme implements IRenderTheme {
}
@Override
- public void updateInstructions() {
+ public void updateStyles() {
}
diff --git a/vtm/src/org/oscim/theme/IRenderTheme.java b/vtm/src/org/oscim/theme/IRenderTheme.java
index ce8de7e6..6b0ec196 100644
--- a/vtm/src/org/oscim/theme/IRenderTheme.java
+++ b/vtm/src/org/oscim/theme/IRenderTheme.java
@@ -19,14 +19,13 @@ package org.oscim.theme;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.TagSet;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Circle;
-import org.oscim.theme.styles.Extrusion;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.LineSymbol;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.CircleStyle;
+import org.oscim.theme.styles.ExtrusionStyle;
+import org.oscim.theme.styles.LineStyle;
import org.oscim.theme.styles.RenderStyle;
-import org.oscim.theme.styles.Symbol;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.SymbolStyle;
+import org.oscim.theme.styles.TextStyle;
public interface IRenderTheme {
@@ -56,7 +55,7 @@ public interface IRenderTheme {
*/
public abstract int getMapBackground();
- public void updateInstructions();
+ public void updateStyles();
/**
* Scales the text size of this RenderTheme by the given factor.
@@ -76,7 +75,7 @@ public interface IRenderTheme {
* @param area
* @param level
*/
- void renderArea(Area area, int level);
+ void renderArea(AreaStyle area, int level);
/**
* Renders an extrusion with the given parameters.
@@ -84,7 +83,7 @@ public interface IRenderTheme {
* @param extrusion
* @param level
*/
- void renderExtrusion(Extrusion extrusion, int level);
+ void renderExtrusion(ExtrusionStyle extrusion, int level);
/**
* Renders an area symbol with the given bitmap.
@@ -92,7 +91,7 @@ public interface IRenderTheme {
* @param symbol
* the symbol to be rendered.
*/
- void renderAreaSymbol(Symbol symbol);
+ void renderAreaSymbol(SymbolStyle symbol);
/**
* Renders an area caption with the given text.
@@ -100,7 +99,7 @@ public interface IRenderTheme {
* @param text
* the text to be rendered.
*/
- void renderAreaText(Text text);
+ void renderAreaText(TextStyle text);
/**
* Renders a point of interest circle with the given parameters.
@@ -110,7 +109,7 @@ public interface IRenderTheme {
* @param level
* the drawing level on which the circle should be rendered.
*/
- void renderPointCircle(Circle circle, int level);
+ void renderPointCircle(CircleStyle circle, int level);
/**
* Renders a point of interest symbol with the given bitmap.
@@ -118,7 +117,7 @@ public interface IRenderTheme {
* @param symbol
* the symbol to be rendered.
*/
- void renderPointSymbol(Symbol symbol);
+ void renderPointSymbol(SymbolStyle symbol);
/**
* Renders a point of interest caption with the given text.
@@ -126,7 +125,7 @@ public interface IRenderTheme {
* @param text
* the text to be rendered.
*/
- void renderPointText(Text text);
+ void renderPointText(TextStyle text);
/**
* Renders a way with the given parameters.
@@ -134,22 +133,14 @@ public interface IRenderTheme {
* @param line
* @param level
*/
- void renderWay(Line line, int level);
-
- /**
- * Renders a way with the given symbol along the way path.
- *
- * @param symbol
- * the symbol to be rendered.
- */
- void renderWaySymbol(LineSymbol symbol);
+ void renderWay(LineStyle line, int level);
/**
* Renders a way with the given text along the way path.
*
* @param text
*/
- void renderWayText(Text text);
+ void renderWayText(TextStyle text);
}
diff --git a/vtm/src/org/oscim/theme/RenderTheme.java b/vtm/src/org/oscim/theme/RenderTheme.java
index 71e51ecd..f951d4c5 100644
--- a/vtm/src/org/oscim/theme/RenderTheme.java
+++ b/vtm/src/org/oscim/theme/RenderTheme.java
@@ -1,6 +1,5 @@
/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
+ * Copyright 2014 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -25,14 +24,12 @@ import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.TagSet;
import org.oscim.theme.rule.Element;
import org.oscim.theme.rule.Rule;
+import org.oscim.theme.rule.Rule.RuleVisitor;
import org.oscim.theme.styles.RenderStyle;
import org.oscim.utils.LRUCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
- * A RenderTheme defines how map elements are drawn.
- */
public class RenderTheme implements IRenderTheme {
static final Logger log = LoggerFactory.getLogger(RenderTheme.class);
@@ -41,8 +38,8 @@ public class RenderTheme implements IRenderTheme {
private final float mBaseTextSize;
private final int mMapBackground;
- private int mLevels;
- private Rule[] mRules;
+ private final int mLevels;
+ private final Rule[] mRules;
class RenderStyleCache {
final int matchType;
@@ -75,9 +72,14 @@ public class RenderTheme implements IRenderTheme {
private final RenderStyleCache[] mStyleCache;
- public RenderTheme(int mapBackground, float baseStrokeWidth, float baseTextSize) {
+ public RenderTheme(int mapBackground, float baseTextSize, Rule[] rules, int levels) {
+ if (rules == null)
+ throw new IllegalArgumentException("rules missing");
+
mMapBackground = mapBackground;
mBaseTextSize = baseTextSize;
+ mLevels = levels;
+ mRules = rules;
mStyleCache = new RenderStyleCache[3];
mStyleCache[0] = new RenderStyleCache(Element.NODE);
@@ -91,10 +93,8 @@ public class RenderTheme implements IRenderTheme {
for (int i = 0; i < 3; i++)
mStyleCache[i].cache.clear();
- if (mRules != null) {
- for (int i = 0, n = mRules.length; i < n; i++)
- mRules[i].onDestroy();
- }
+ for (Rule rule : mRules)
+ rule.dispose();
}
@Override
@@ -107,13 +107,17 @@ public class RenderTheme implements IRenderTheme {
return mMapBackground;
}
+ //AtomicInteger hitCount = new AtomicInteger(0);
+ //AtomicInteger missCount = new AtomicInteger(0);
+ //AtomicInteger sameCount = new AtomicInteger(0);
+
@Override
public RenderStyle[] matchElement(GeometryType geometryType, TagSet tags, int zoomLevel) {
- // list of renderinsctruction items in cache
+ /* list of items in cache */
RenderStyleItem ris = null;
- // the item matching tags and zoomlevel
+ /* the item matching tags and zoomlevel */
RenderStyleItem ri = null;
int type = geometryType.nativeInt;
@@ -124,35 +128,42 @@ public class RenderTheme implements IRenderTheme {
RenderStyleCache cache = mStyleCache[type - 1];
- // NOTE: maximum zoom level supported is 32
+ /* NOTE: maximum zoom level supported is 32 */
int zoomMask = 1 << zoomLevel;
synchronized (cache) {
if ((cache.prevItem == null) || (cache.prevItem.zoom & zoomMask) == 0) {
- // previous instructions zoom does not match
+ /* previous instructions zoom does not match */
cache.cacheKey.set(tags, null);
} else {
- // compare if tags match previous instructions
+ /* compare if tags match previous instructions */
if (cache.cacheKey.set(tags, cache.prevItem.key)) {
- //log.debug("same as previous " + Arrays.deepToString(tags));
ri = cache.prevItem;
+ //log.debug(hitCount + "/" + sameCount.incrementAndGet()
+ // + "/" + missCount + "same hit " + tags);
}
}
if (ri == null) {
- // get instruction for current cacheKey
+ /* get instruction for current cacheKey */
ris = cache.getRenderInstructions();
- for (ri = ris; ri != null; ri = ri.next)
- if ((ri.zoom & zoomMask) != 0)
- // cache hit
+ for (ri = ris; ri != null; ri = ri.next) {
+ if ((ri.zoom & zoomMask) != 0) {
+ /* cache hit */
+
+ //log.debug(hitCount.incrementAndGet()
+ // + "/" + sameCount + "/" + missCount
+ // + " cache hit " + tags);
break;
+ }
+ }
}
if (ri == null) {
- // cache miss
- //log.debug(missCnt++ + " / " + hitCnt + " Cache Miss");
+ /* cache miss */
+ //missCount.incrementAndGet();
List matches = cache.instructionList;
matches.clear();
@@ -176,13 +187,13 @@ public class RenderTheme implements IRenderTheme {
}
}
}
- // check if same instructions are used in another level
+ /* check if same instructions are used in another level */
for (ri = ris; ri != null; ri = ri.next) {
if (size == 0) {
if (ri.list != null)
continue;
- // both matchinglists are empty
+ /* both matchinglists are empty */
break;
}
@@ -199,13 +210,13 @@ public class RenderTheme implements IRenderTheme {
i++;
}
if (i == size)
- // both matching lists contain the same items
+ /* both matching lists contain the same items */
break;
}
if (ri != null) {
- // we found a same matchting list on another zoomlevel add
- // this zoom level to the existing RenderInstructionItem.
+ /* we found a same matchting list on another zoomlevel add
+ * this zoom level to the existing RenderInstructionItem. */
ri.zoom |= zoomMask;
//log.debug(zoomLevel + " same instructions " + size + " "
@@ -222,7 +233,7 @@ public class RenderTheme implements IRenderTheme {
matches.toArray(ri.list);
}
- // attach this list to the one found for MatchingKey
+ /* attach this list to the one found for MatchingKey */
if (ris != null) {
ri.next = ris.next;
ri.key = ris.key;
@@ -233,34 +244,26 @@ public class RenderTheme implements IRenderTheme {
}
}
}
-
cache.prevItem = ri;
}
-
return ri.list;
}
- void complete(List rulesList, int levels) {
- mLevels = levels;
-
- mRules = new Rule[rulesList.size()];
- rulesList.toArray(mRules);
-
- for (int i = 0, n = mRules.length; i < n; i++) {
- mRules[i].onComplete();
- }
- }
-
@Override
public void scaleTextSize(float scaleFactor) {
-
- for (int i = 0, n = mRules.length; i < n; i++)
- mRules[i].scaleTextSize(scaleFactor * mBaseTextSize);
+ for (Rule rule : mRules)
+ rule.scaleTextSize(scaleFactor * mBaseTextSize);
}
@Override
- public void updateInstructions() {
- for (int i = 0, n = mRules.length; i < n; i++)
- mRules[i].updateInstructions();
+ public void updateStyles() {
+ for (Rule rule : mRules)
+ rule.updateStyles();
}
+
+ public void traverseRules(RuleVisitor visitor) {
+ for (Rule rule : mRules)
+ rule.apply(visitor);
+ }
+
}
diff --git a/vtm/src/org/oscim/theme/ThemeBuilder.java b/vtm/src/org/oscim/theme/ThemeBuilder.java
new file mode 100644
index 00000000..dd20f9ab
--- /dev/null
+++ b/vtm/src/org/oscim/theme/ThemeBuilder.java
@@ -0,0 +1,125 @@
+package org.oscim.theme;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Stack;
+
+import org.oscim.core.GeometryBuffer.GeometryType;
+import org.oscim.core.Tag;
+import org.oscim.core.TagSet;
+import org.oscim.theme.rule.Element;
+import org.oscim.theme.rule.Rule;
+import org.oscim.theme.rule.RuleBuilder;
+import org.oscim.theme.rule.Selector;
+import org.oscim.theme.rule.SingleKeyMatcher;
+import org.oscim.theme.rule.SingleValueMatcher;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.LineStyle;
+import org.oscim.theme.styles.RenderStyle;
+
+public class ThemeBuilder {
+ protected final ArrayList mRulesList = new ArrayList();
+ protected final Stack mRuleStack = new Stack();
+
+ protected int mLevels = 0;
+ protected int mMapBackground = 0xffffffff;
+ protected float mBaseTextSize = 1;
+
+ protected RuleBuilder mCurrentRule;
+
+ protected RenderTheme build() {
+
+ Rule[] rules = new Rule[mRulesList.size()];
+ for (int i = 0, n = rules.length; i < n; i++)
+ rules[i] = mRulesList.get(i).onComplete();
+
+ RenderTheme theme = new RenderTheme(mMapBackground, mBaseTextSize, rules, mLevels);
+
+ mRulesList.clear();
+ mRuleStack.clear();
+
+ return theme;
+ }
+
+ public ThemeBuilder pop() {
+
+ mRuleStack.pop();
+ if (mRuleStack.empty()) {
+ mRulesList.add(mCurrentRule);
+ } else {
+ mCurrentRule = mRuleStack.peek();
+ }
+ return this;
+ }
+
+ public ThemeBuilder push(RuleBuilder rule) {
+ if (!mRuleStack.empty())
+ mCurrentRule.addSubRule(rule);
+
+ mCurrentRule = rule;
+ mRuleStack.push(mCurrentRule);
+
+ return this;
+ }
+
+ public ThemeBuilder push(String key, String value) {
+ RuleBuilder b = new RuleBuilder(true, Element.ANY, ~0, 0,
+ key == null ? null : new SingleKeyMatcher(key),
+ value == null ? null : new SingleValueMatcher(value));
+ push(b);
+ return this;
+ }
+
+ public RuleBuilder pushParse(String keys, String values) {
+
+ return RuleBuilder.create(mRuleStack, keys, values)
+ .zoom(~0)
+ .element(Element.ANY);
+ }
+
+ public ThemeBuilder addStyle(RenderStyle style) {
+ mCurrentRule.addStyle(style);
+ return this;
+ }
+
+ public static void main(String[] args) {
+
+ ThemeBuilder b = new ThemeBuilder();
+
+ //b.pushParse("highway", "residential|primary|motorway")
+
+ b.push(RuleBuilder.get().select(Selector.FIRST))
+ .push("highway", null)
+ .addStyle(new LineStyle(1, 1, 1))
+ .pop()
+
+ .push(RuleBuilder.get().select(Selector.WHEN_MATCHED))
+ .addStyle(new AreaStyle(1, 1))
+ .pop()
+ .pop();
+
+ RenderTheme t = b.build();
+ TagSet tags = new TagSet(1);
+ RenderStyle[] styles;
+
+ tags.add(new Tag("ahighway", "residential"));
+ styles = t.matchElement(GeometryType.LINE, tags, 1);
+ System.out.println(Arrays.deepToString(styles));
+
+ // tags.clear();
+ // tags.add(new Tag("highway", "motorway"));
+ // styles = t.matchElement(GeometryType.LINE, tags, 1);
+ // out.println(styles);
+ //
+ // tags.clear();
+ // tags.add(new Tag("sup", "wup"));
+ // styles = t.matchElement(GeometryType.LINE, tags, 1);
+ // out.println(styles);
+ //
+ // tags.clear();
+ // tags.add(new Tag("highway", "motorway"));
+ // styles = t.matchElement(GeometryType.LINE, tags, 1);
+ // out.println(styles);
+
+ }
+}
diff --git a/vtm/src/org/oscim/theme/ThemeLoader.java b/vtm/src/org/oscim/theme/ThemeLoader.java
index c49a9213..71b39fd6 100644
--- a/vtm/src/org/oscim/theme/ThemeLoader.java
+++ b/vtm/src/org/oscim/theme/ThemeLoader.java
@@ -45,7 +45,7 @@ public class ThemeLoader {
InputStream inputStream = null;
try {
inputStream = theme.getRenderThemeAsStream();
- IRenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
+ IRenderTheme t = XmlThemeBuilder.read(inputStream);
if (t != null)
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f);
diff --git a/vtm/src/org/oscim/theme/RenderThemeHandler.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
similarity index 59%
rename from vtm/src/org/oscim/theme/RenderThemeHandler.java
rename to vtm/src/org/oscim/theme/XmlThemeBuilder.java
index 0c1363d5..4bbc5bb4 100644
--- a/vtm/src/org/oscim/theme/RenderThemeHandler.java
+++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
@@ -17,6 +17,10 @@
*/
package org.oscim.theme;
+import static java.lang.Boolean.parseBoolean;
+import static java.lang.Float.parseFloat;
+import static java.lang.Integer.parseInt;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -36,14 +40,17 @@ import org.oscim.renderer.atlas.TextureRegion;
import org.oscim.renderer.elements.TextureItem;
import org.oscim.theme.IRenderTheme.ThemeException;
import org.oscim.theme.rule.Rule;
-import org.oscim.theme.styles.Area;
-import org.oscim.theme.styles.Circle;
-import org.oscim.theme.styles.Extrusion;
-import org.oscim.theme.styles.Line;
-import org.oscim.theme.styles.LineSymbol;
+import org.oscim.theme.rule.RuleBuilder;
+import org.oscim.theme.styles.AreaStyle;
+import org.oscim.theme.styles.AreaStyle.AreaBuilder;
+import org.oscim.theme.styles.CircleStyle;
+import org.oscim.theme.styles.ExtrusionStyle;
+import org.oscim.theme.styles.LineStyle;
+import org.oscim.theme.styles.LineStyle.LineBuilder;
import org.oscim.theme.styles.RenderStyle;
-import org.oscim.theme.styles.Symbol;
-import org.oscim.theme.styles.Text;
+import org.oscim.theme.styles.SymbolStyle;
+import org.oscim.theme.styles.TextStyle;
+import org.oscim.theme.styles.TextStyle.TextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
@@ -51,8 +58,8 @@ import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
-public class RenderThemeHandler extends DefaultHandler {
- static final Logger log = LoggerFactory.getLogger(RenderThemeHandler.class);
+public class XmlThemeBuilder extends DefaultHandler {
+ static final Logger log = LoggerFactory.getLogger(XmlThemeBuilder.class);
private static final int RENDER_THEME_VERSION = 1;
@@ -60,7 +67,7 @@ public class RenderThemeHandler extends DefaultHandler {
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS;
}
- //private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme";
+ private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme";
private static final String ELEMENT_NAME_MATCH = "m";
private static final String UNEXPECTED_ELEMENT = "unexpected element: ";
@@ -82,10 +89,10 @@ public class RenderThemeHandler extends DefaultHandler {
* @throws IOException
* if an I/O error occurs while reading from the input stream.
*/
- public static IRenderTheme getRenderTheme(InputStream inputStream)
+ public static IRenderTheme read(InputStream inputStream)
throws SAXException, IOException {
- RenderThemeHandler renderThemeHandler = new RenderThemeHandler();
+ XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder();
new XMLReaderAdapter().parse(renderThemeHandler, inputStream);
@@ -118,36 +125,39 @@ public class RenderThemeHandler extends DefaultHandler {
log.debug(sb.toString());
}
- private ArrayList mRulesList = new ArrayList();
- private Rule mCurrentRule;
-
- private Stack mElementStack = new Stack();
- private Stack mRuleStack = new Stack();
- private HashMap mStyles =
+ private final ArrayList mRulesList = new ArrayList();
+ private final Stack mElementStack = new Stack();
+ private final Stack mRuleStack = new Stack();
+ private final HashMap mStyles =
new HashMap(10);
+ private final TextBuilder mTextBuilder = new TextBuilder();
+ private final AreaBuilder mAreaBuilder = new AreaBuilder();
+ private final LineBuilder mLineBuilder = new LineBuilder();
+
+ private RuleBuilder mCurrentRule;
private TextureAtlas mTextureAtlas;
- private int mLevel;
+ private int mLevels = 0;
+ private int mMapBackground = 0xffffffff;
+ private float mBaseTextSize = 1;
+
private RenderTheme mRenderTheme;
@Override
public void endDocument() {
- if (mRenderTheme == null) {
- throw new IllegalArgumentException("missing element: rules");
- }
- mRenderTheme.complete(mRulesList, mLevel);
+ Rule[] rules = new Rule[mRulesList.size()];
+ for (int i = 0, n = rules.length; i < n; i++)
+ rules[i] = mRulesList.get(i).onComplete();
+
+ mRenderTheme = new RenderTheme(mMapBackground, mBaseTextSize, rules, mLevels);
mRulesList.clear();
mStyles.clear();
mRuleStack.clear();
mElementStack.clear();
- mStyles = null;
- mRuleStack = null;
- mRulesList = null;
- mElementStack = null;
mTextureAtlas = null;
}
@@ -179,13 +189,13 @@ public class RenderThemeHandler extends DefaultHandler {
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
try {
- if ("rendertheme".equals(localName)) {
+ if (ELEMENT_NAME_RENDER_THEME.equals(localName)) {
checkState(localName, Element.RENDER_THEME);
- mRenderTheme = createRenderTheme(localName, attributes);
+ createRenderTheme(localName, attributes);
} else if (ELEMENT_NAME_MATCH.equals(localName)) {
checkState(localName, Element.RULE);
- Rule rule = Rule.create(localName, attributes, mRuleStack);
+ RuleBuilder rule = RuleBuilder.create(localName, attributes, mRuleStack);
if (!mRuleStack.empty()) {
mCurrentRule.addSubRule(rule);
}
@@ -194,7 +204,7 @@ public class RenderThemeHandler extends DefaultHandler {
} else if ("style-text".equals(localName)) {
checkState(localName, Element.STYLE);
- Text text = createText(localName, attributes, false);
+ TextStyle text = createText(localName, attributes, false);
mStyles.put(TEXT_STYLE + text.style, text);
} else if ("style-area".equals(localName)) {
@@ -207,7 +217,7 @@ public class RenderThemeHandler extends DefaultHandler {
} else if ("outline-layer".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
- Line line = createLine(null, localName, attributes, mLevel++, true);
+ LineStyle line = createLine(null, localName, attributes, mLevels++, true);
mStyles.put(OUTLINE_STYLE + line.style, line);
} else if ("area".equals(localName)) {
@@ -216,40 +226,35 @@ public class RenderThemeHandler extends DefaultHandler {
} else if ("caption".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
- Text text = createText(localName, attributes, true);
- mCurrentRule.addRenderingInstruction(text);
+ TextStyle text = createText(localName, attributes, true);
+ mCurrentRule.addStyle(text);
} else if ("circle".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
- Circle circle = createCircle(localName, attributes, mLevel++);
- mCurrentRule.addRenderingInstruction(circle);
+ CircleStyle circle = createCircle(localName, attributes, mLevels++);
+ mCurrentRule.addStyle(circle);
} else if ("line".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
handleLineElement(localName, attributes, false);
- } else if ("lineSymbol".equals(localName)) {
- checkState(localName, Element.RENDERING_INSTRUCTION);
- LineSymbol lineSymbol = createLineSymbol(localName, attributes);
- mCurrentRule.addRenderingInstruction(lineSymbol);
-
} else if ("text".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
String style = attributes.getValue("use");
if (style == null) {
- Text text = createText(localName, attributes, false);
- mCurrentRule.addRenderingInstruction(text);
+ TextStyle text = createText(localName, attributes, false);
+ mCurrentRule.addStyle(text);
} else {
- Text pt = (Text) mStyles.get(TEXT_STYLE + style);
+ TextStyle pt = (TextStyle) mStyles.get(TEXT_STYLE + style);
if (pt != null)
- mCurrentRule.addRenderingInstruction(pt);
+ mCurrentRule.addStyle(pt);
else
log.debug("BUG not a path text style: " + style);
}
} else if ("symbol".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
- Symbol symbol = createSymbol(localName, attributes);
- mCurrentRule.addRenderingInstruction(symbol);
+ SymbolStyle symbol = createSymbol(localName, attributes);
+ mCurrentRule.addStyle(symbol);
} else if ("outline".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
@@ -257,8 +262,8 @@ public class RenderThemeHandler extends DefaultHandler {
} else if ("extrusion".equals(localName)) {
checkState(localName, Element.RENDERING_INSTRUCTION);
- Extrusion extrusion = createExtrusion(localName, attributes, mLevel++);
- mCurrentRule.addRenderingInstruction(extrusion);
+ ExtrusionStyle extrusion = createExtrusion(localName, attributes, mLevels++);
+ mCurrentRule.addStyle(extrusion);
} else if ("atlas".equals(localName)) {
checkState(localName, Element.ATLAS);
@@ -295,22 +300,22 @@ public class RenderThemeHandler extends DefaultHandler {
throws SAXException {
String use = attributes.getValue("use");
- Line style = null;
+ LineStyle style = null;
if (use != null) {
- style = (Line) mStyles.get(LINE_STYLE + use);
+ style = (LineStyle) mStyles.get(LINE_STYLE + use);
if (style == null) {
log.debug("missing line style 'use': " + use);
return;
}
}
- Line line = createLine(style, localName, attributes, mLevel++, false);
+ LineStyle line = createLine(style, localName, attributes, mLevels++, false);
if (isStyle) {
mStyles.put(LINE_STYLE + line.style, line);
} else {
- mCurrentRule.addRenderingInstruction(line);
+ mCurrentRule.addStyle(line);
// Note 'outline' will not be inherited, it's just a
// shorcut to add the outline RenderInstruction.
addOutline(attributes.getValue("outline"));
@@ -320,53 +325,24 @@ public class RenderThemeHandler extends DefaultHandler {
/**
* @param line
* optional: line style defaults
- * @param elementName
- * the name of the XML element.
- * @param attributes
- * the attributes of the XML element.
* @param level
* the drawing level of this instruction.
* @param isOutline
* is outline layer
* @return a new Line with the given rendering attributes.
*/
- private static Line createLine(Line line, String elementName, Attributes attributes,
+ private LineStyle createLine(LineStyle line, String elementName, Attributes attributes,
int level, boolean isOutline) {
-
- // Style name
- String style = null;
- float width = 0;
- Cap cap = Cap.ROUND;
-
- // Extras
- int fade = -1;
- boolean fixed = false;
- float blur = 0;
-
- // Stipple
- int stipple = 0;
- float stippleWidth = 1;
-
- int color = Color.TRANSPARENT;
- int stippleColor = Color.BLACK;
-
- if (line != null) {
- color = line.color;
- fixed = line.fixed;
- fade = line.fade;
- cap = line.cap;
- blur = line.blur;
- stipple = line.stipple;
- stippleColor = line.stippleColor;
- stippleWidth = line.stippleWidth;
- }
+ LineBuilder b = mLineBuilder.set(line);
+ b.isOutline(isOutline);
+ b.level(level);
for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
if ("id".equals(name))
- style = value;
+ b.style = value;
else if ("src".equals(name))
;// src = value;
@@ -378,34 +354,43 @@ public class RenderThemeHandler extends DefaultHandler {
;// ignore
else if ("stroke".equals(name))
- color = Color.parseColor(value);
-
- else if ("width".equals(name) || "stroke-width".equals(name))
- width = Float.parseFloat(value);
+ b.color(value);
+ else if ("width".equals(name) || "stroke-width".equals(name)) {
+ float width = parseFloat(value);
+ if (line == null) {
+ validateNonNegative("width", width);
+ } else {
+ /* use stroke width relative to 'line' */
+ width += line.width;
+ if (width <= 0)
+ width = 1;
+ }
+ b.width = width;
+ }
else if ("cap".equals(name) || "stroke-linecap".equals(name))
- cap = Cap.valueOf(value.toUpperCase());
+ b.cap = Cap.valueOf(value.toUpperCase());
else if ("fix".equals(name))
- fixed = Boolean.parseBoolean(value);
+ b.fixed = parseBoolean(value);
else if ("stipple".equals(name))
- stipple = Integer.parseInt(value);
+ b.stipple = parseInt(value);
else if ("stipple-stroke".equals(name))
- stippleColor = Color.parseColor(value);
+ b.stippleColor(value);
else if ("stipple-width".equals(name))
- stippleWidth = Float.parseFloat(value);
+ b.stippleWidth = parseFloat(value);
else if ("fade".equals(name))
- fade = Integer.parseInt(value);
+ b.fadeScale = Integer.parseInt(value);
else if ("min".equals(name))
; //min = Float.parseFloat(value);
else if ("blur".equals(name))
- blur = Float.parseFloat(value);
+ b.blur = parseFloat(value);
else if ("style".equals(name))
; // ignore
@@ -416,92 +401,49 @@ public class RenderThemeHandler extends DefaultHandler {
else
logUnknownAttribute(elementName, name, value, i);
}
-
- // inherit properties from 'line'
- if (line != null) {
- // use stroke width relative to 'line'
- width = line.width + width;
- if (width <= 0)
- width = 1;
-
- } else if (!isOutline) {
- validateLine(width);
- }
-
- return new Line(level, style, color, width, cap, fixed,
- stipple, stippleColor, stippleWidth,
- fade, blur, isOutline);
- }
-
- private static void validateLine(float strokeWidth) {
- if (strokeWidth < 0)
- throw new ThemeException("width must not be negative: " + strokeWidth);
+ return b.build();
}
private void handleAreaElement(String localName, Attributes attributes, boolean isStyle)
throws SAXException {
String use = attributes.getValue("use");
- Area style = null;
+ AreaStyle style = null;
if (use != null) {
- style = (Area) mStyles.get(AREA_STYLE + use);
+ style = (AreaStyle) mStyles.get(AREA_STYLE + use);
if (style == null) {
log.debug("missing area style 'use': " + use);
return;
}
}
- Area area = createArea(style, localName, attributes, mLevel);
- mLevel += 2;
+ AreaStyle area = createArea(style, localName, attributes, mLevels);
+ mLevels += 2;
if (isStyle) {
mStyles.put(AREA_STYLE + area.style, area);
} else {
- mCurrentRule.addRenderingInstruction(area);
+ mCurrentRule.addStyle(area);
}
}
/**
- * @param elementName
- * the name of the XML element.
- * @param attributes
- * the attributes of the XML element.
- * @param level
- * the drawing level of this instruction.
* @return a new Area with the given rendering attributes.
*/
- private static Area createArea(Area area, String elementName, Attributes attributes, int level) {
+ private AreaStyle createArea(AreaStyle area, String elementName, Attributes attributes,
+ int level) {
+ AreaBuilder b = mAreaBuilder.set(area);
+ b.level(level);
+
String src = null;
- int fill = Color.BLACK;
- int stroke = Color.TRANSPARENT;
- float strokeWidth = 1;
- int fade = -1;
- int blend = -1;
- int blendFill = Color.TRANSPARENT;
- String style = null;
-
- TextureItem texture = null;
-
- if (area != null) {
- fill = area.color;
- blend = area.blend;
- blendFill = area.blendColor;
- fade = area.fade;
- // TODO texture = area.texture
-
- if (area.outline != null) {
- stroke = area.outline.color;
- strokeWidth = area.outline.width;
- }
- }
for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
if ("id".equals(name))
- style = value;
+ b.style = value;
else if ("use".equals(name))
;// ignore
@@ -510,47 +452,46 @@ public class RenderThemeHandler extends DefaultHandler {
src = value;
else if ("fill".equals(name))
- fill = Color.parseColor(value);
+ b.color(value);
else if ("stroke".equals(name))
- stroke = Color.parseColor(value);
+ b.outlineColor(value);
- else if ("stroke-width".equals(name))
- strokeWidth = Float.parseFloat(value);
+ else if ("stroke-width".equals(name)) {
+ float strokeWidth = Float.parseFloat(value);
+ validateNonNegative("stroke-width", strokeWidth);
+ b.outlineWidth = strokeWidth;
- else if ("fade".equals(name))
- fade = Integer.parseInt(value);
+ } else if ("fade".equals(name))
+ b.fadeScale = Integer.parseInt(value);
else if ("blend".equals(name))
- blend = Integer.parseInt(value);
+ b.blendScale = Integer.parseInt(value);
else if ("blend-fill".equals(name))
- blendFill = Color.parseColor(value);
+ b.blendColor(value);
else
logUnknownAttribute(elementName, name, value, i);
}
- validateLine(strokeWidth);
-
if (src != null) {
try {
- Bitmap b = CanvasAdapter.g.loadBitmapAsset(src);
- if (b != null)
- texture = new TextureItem(b, true);
+ Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(src);
+ if (bitmap != null)
+ b.texture = new TextureItem(bitmap, true);
} catch (Exception e) {
log.debug(e.getMessage());
}
}
- return new Area(style, fill, stroke, strokeWidth, fade, level, blend,
- blendFill, texture);
+ return b.build();
}
private void addOutline(String style) {
if (style != null) {
- Line line = (Line) mStyles.get(OUTLINE_STYLE + style);
+ LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);
if (line != null && line.outline)
- mCurrentRule.addRenderingInstruction(line);
+ mCurrentRule.addStyle(line);
else
log.debug("BUG not an outline style: " + style);
}
@@ -566,11 +507,10 @@ public class RenderThemeHandler extends DefaultHandler {
if ("img".equals(name)) {
img = value;
} else {
- RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
+ XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
}
}
- if (img == null)
- throw new ThemeException("missing attribute 'img' for element: " + elementName);
+ validateExists("img", img, elementName);
Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(IMG_PATH + img);
mTextureAtlas = new TextureAtlas(bitmap);
@@ -595,12 +535,11 @@ public class RenderThemeHandler extends DefaultHandler {
Integer.parseInt(pos[3]));
}
} else {
- RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
+ XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
}
}
- if (regionName == null || r == null)
- throw new ThemeException("missing attribute 'id' or 'rect' for element: "
- + elementName);
+ validateExists("id", regionName, elementName);
+ validateExists("pos", r, elementName);
mTextureAtlas.addTextureRegion(regionName.intern(), r);
}
@@ -652,7 +591,7 @@ public class RenderThemeHandler extends DefaultHandler {
mElementStack.push(element);
}
- static RenderTheme createRenderTheme(String elementName, Attributes attributes) {
+ private void createRenderTheme(String elementName, Attributes attributes) {
Integer version = null;
int mapBackground = Color.WHITE;
float baseStrokeWidth = 1;
@@ -678,115 +617,91 @@ public class RenderThemeHandler extends DefaultHandler {
baseTextSize = Float.parseFloat(value);
else
- RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
+ XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
}
- if (version == null)
- throw new ThemeException("missing attribute version for element:" + elementName);
- else if (version.intValue() != RENDER_THEME_VERSION)
- throw new ThemeException("invalid render theme version:" + version);
- else if (baseStrokeWidth < 0)
- throw new ThemeException("base-stroke-width must not be negative: " + baseStrokeWidth);
- else if (baseTextSize < 0)
- throw new ThemeException("base-text-size must not be negative: " + baseTextSize);
+ validateExists("version", version, elementName);
- return new RenderTheme(mapBackground, baseStrokeWidth, baseTextSize);
+ if (version.intValue() != RENDER_THEME_VERSION)
+ throw new ThemeException("invalid render theme version:"
+ + version);
+
+ validateNonNegative("base-stroke-width", baseStrokeWidth);
+ validateNonNegative("base-test-size", baseTextSize);
+
+ mMapBackground = mapBackground;
+ mBaseTextSize = baseTextSize;
}
/**
- * @param elementName
- * the name of the XML element.
- * @param attributes
- * the attributes of the XML element.
* @param caption
* ...
* @return a new Text with the given rendering attributes.
*/
- private Text createText(String elementName, Attributes attributes, boolean caption) {
- String textKey = null;
- FontFamily fontFamily = FontFamily.DEFAULT;
- FontStyle fontStyle = FontStyle.NORMAL;
- float fontSize = 0;
- int fill = Color.BLACK;
- int stroke = Color.BLACK;
- float strokeWidth = 0;
- String style = null;
- float dy = 0;
- int priority = Integer.MAX_VALUE;
- TextureRegion symbol = null;
+ private TextStyle createText(String elementName, Attributes attributes, boolean caption) {
+ TextBuilder b = mTextBuilder.reset();
+
+ b.caption = caption;
for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
if ("id".equals(name))
- style = value;
+ b.style = value;
else if ("k".equals(name))
- textKey = value.intern();
+ b.textKey = value.intern();
else if ("font-family".equals(name))
- fontFamily = FontFamily.valueOf(value.toUpperCase());
+ b.fontFamily = FontFamily.valueOf(value.toUpperCase());
else if ("style".equals(name))
- fontStyle = FontStyle.valueOf(value.toUpperCase());
+ b.fontStyle = FontStyle.valueOf(value.toUpperCase());
else if ("size".equals(name))
- fontSize = Float.parseFloat(value);
+ b.fontSize = Float.parseFloat(value);
else if ("fill".equals(name))
- fill = Color.parseColor(value);
+ b.color = Color.parseColor(value);
else if ("stroke".equals(name))
- stroke = Color.parseColor(value);
+ b.stroke = Color.parseColor(value);
else if ("stroke-width".equals(name))
- strokeWidth = Float.parseFloat(value);
+ b.strokeWidth = Float.parseFloat(value);
else if ("caption".equals(name))
- caption = Boolean.parseBoolean(value);
+ b.caption = Boolean.parseBoolean(value);
else if ("priority".equals(name))
- priority = Integer.parseInt(value);
+ b.priority = Integer.parseInt(value);
else if ("dy".equals(name))
- dy = Float.parseFloat(value);
+ // NB: minus..
+ b.dy = -Float.parseFloat(value);
else if ("symbol".equals(name))
- symbol = getAtlasRegion(value);
+ b.texture = getAtlasRegion(value);
else
logUnknownAttribute(elementName, name, value, i);
-
}
- validateText(elementName, textKey, fontSize, strokeWidth);
+ validateExists("k", b.textKey, elementName);
+ validateNonNegative("size", b.fontSize);
+ validateNonNegative("stroke-width", b.strokeWidth);
- return new Text(style, textKey, fontFamily, fontStyle, fontSize, fill, stroke, strokeWidth,
- dy, caption, symbol, priority);
- }
-
- private static void validateText(String elementName, String textKey, float fontSize,
- float strokeWidth) {
- if (textKey == null)
- throw new ThemeException("missing attribute k for element: " + elementName);
- else if (fontSize < 0)
- throw new ThemeException("font-size must not be negative: " + fontSize);
- else if (strokeWidth < 0)
- throw new ThemeException("stroke-width must not be negative: " + strokeWidth);
+ return b.buildInternal();
}
/**
- * @param elementName
- * the name of the XML element.
- * @param attributes
- * the attributes of the XML element.
* @param level
* the drawing level of this instruction.
* @return a new Circle with the given rendering attributes.
*/
- private static Circle createCircle(String elementName, Attributes attributes, int level) {
+ private static CircleStyle createCircle(String elementName, Attributes attributes, int level) {
Float radius = null;
boolean scaleRadius = false;
int fill = Color.TRANSPARENT;
@@ -816,60 +731,17 @@ public class RenderThemeHandler extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i);
}
- validateCircle(elementName, radius, strokeWidth);
- return new Circle(radius, scaleRadius, fill, stroke, strokeWidth, level);
- }
+ validateExists("r", radius, elementName);
+ validateNonNegative("radius", radius);
+ validateNonNegative("stroke-width", strokeWidth);
- private static void validateCircle(String elementName, Float radius, float strokeWidth) {
- if (radius == null)
- throw new ThemeException("missing attribute r for element: " + elementName);
- else if (radius.floatValue() < 0)
- throw new ThemeException("radius must not be negative: " + radius);
- else if (strokeWidth < 0)
- throw new ThemeException("stroke-width must not be negative: " + strokeWidth);
+ return new CircleStyle(radius, scaleRadius, fill, stroke, strokeWidth, level);
}
/**
- * @param elementName
- * the name of the XML element.
- * @param attributes
- * the attributes of the XML element.
- * @return a new LineSymbol with the given rendering attributes.
- */
- private static LineSymbol createLineSymbol(String elementName, Attributes attributes) {
- String src = null;
- boolean alignCenter = false;
- boolean repeat = false;
-
- for (int i = 0; i < attributes.getLength(); ++i) {
- String name = attributes.getLocalName(i);
- String value = attributes.getValue(i);
-
- if ("src".equals(name))
- src = value;
-
- else if ("align-center".equals(name))
- alignCenter = Boolean.parseBoolean(value);
-
- else if ("repeat".equals(name))
- repeat = Boolean.parseBoolean(value);
-
- else
- logUnknownAttribute(elementName, name, value, i);
- }
-
- validateSymbol(elementName, src);
- return new LineSymbol(src, alignCenter, repeat);
- }
-
- /**
- * @param elementName
- * the name of the XML element.
- * @param attributes
- * the attributes of the XML element.
* @return a new Symbol with the given rendering attributes.
*/
- private Symbol createSymbol(String elementName, Attributes attributes) {
+ private SymbolStyle createSymbol(String elementName, Attributes attributes) {
String src = null;
for (int i = 0; i < attributes.getLength(); ++i) {
@@ -882,17 +754,12 @@ public class RenderThemeHandler extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i);
}
- validateSymbol(elementName, src);
+ validateExists("src", src, elementName);
- return new Symbol(getAtlasRegion(src));
+ return new SymbolStyle(getAtlasRegion(src));
}
- private static void validateSymbol(String elementName, String src) {
- if (src == null)
- throw new ThemeException("missing attribute src for element: " + elementName);
- }
-
- private Extrusion createExtrusion(String elementName, Attributes attributes, int level) {
+ private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) {
int colorSide = 0;
int colorTop = 0;
int colorLine = 0;
@@ -918,6 +785,18 @@ public class RenderThemeHandler extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i);
}
- return new Extrusion(level, colorSide, colorTop, colorLine, defaultHeight);
+ return new ExtrusionStyle(level, colorSide, colorTop, colorLine, defaultHeight);
+ }
+
+ public static void validateNonNegative(String name, float value) {
+ if (value < 0)
+ throw new ThemeException(name + " must not be negative: "
+ + value);
+ }
+
+ public static void validateExists(String name, Object obj, String elementName) {
+ if (obj == null)
+ throw new ThemeException("missing attribute " + name
+ + " for element: " + elementName);
}
}
diff --git a/vtm/src/org/oscim/theme/rule/Element.java b/vtm/src/org/oscim/theme/rule/Element.java
index 5b961953..2a91a24d 100644
--- a/vtm/src/org/oscim/theme/rule/Element.java
+++ b/vtm/src/org/oscim/theme/rule/Element.java
@@ -1,6 +1,4 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
+/* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
diff --git a/vtm/src/org/oscim/theme/rule/NegativeRule.java b/vtm/src/org/oscim/theme/rule/NegativeRule.java
index 054575ef..ce750aaa 100644
--- a/vtm/src/org/oscim/theme/rule/NegativeRule.java
+++ b/vtm/src/org/oscim/theme/rule/NegativeRule.java
@@ -18,12 +18,14 @@
package org.oscim.theme.rule;
import org.oscim.core.Tag;
+import org.oscim.theme.styles.RenderStyle;
class NegativeRule extends Rule {
final AttributeMatcher mAttributeMatcher;
- NegativeRule(int element, int zoom, boolean matchFirst, AttributeMatcher attributeMatcher) {
- super(element, zoom, matchFirst);
+ NegativeRule(int element, int zoom, int selector, AttributeMatcher attributeMatcher,
+ Rule[] subRules, RenderStyle[] styles) {
+ super(element, zoom, selector, subRules, styles);
mAttributeMatcher = attributeMatcher;
}
diff --git a/vtm/src/org/oscim/theme/rule/PositiveRule.java b/vtm/src/org/oscim/theme/rule/PositiveRule.java
index fb6b15ff..370bcb24 100644
--- a/vtm/src/org/oscim/theme/rule/PositiveRule.java
+++ b/vtm/src/org/oscim/theme/rule/PositiveRule.java
@@ -18,14 +18,15 @@
package org.oscim.theme.rule;
import org.oscim.core.Tag;
+import org.oscim.theme.styles.RenderStyle;
class PositiveRule extends Rule {
final AttributeMatcher mKeyMatcher;
final AttributeMatcher mValueMatcher;
- PositiveRule(int element, int zoom, boolean matchFirst, AttributeMatcher keyMatcher,
- AttributeMatcher valueMatcher) {
- super(element, zoom, matchFirst);
+ PositiveRule(int element, int zoom, int selector, AttributeMatcher keyMatcher,
+ AttributeMatcher valueMatcher, Rule[] subRules, RenderStyle[] styles) {
+ super(element, zoom, selector, subRules, styles);
if (keyMatcher instanceof AnyMatcher)
mKeyMatcher = null;
diff --git a/vtm/src/org/oscim/theme/rule/Rule.java b/vtm/src/org/oscim/theme/rule/Rule.java
index 16902973..31756ca2 100644
--- a/vtm/src/org/oscim/theme/rule/Rule.java
+++ b/vtm/src/org/oscim/theme/rule/Rule.java
@@ -1,5 +1,4 @@
/*
- * Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@@ -17,305 +16,138 @@
*/
package org.oscim.theme.rule;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Stack;
import org.oscim.core.Tag;
-import org.oscim.theme.IRenderTheme.ThemeException;
-import org.oscim.theme.RenderThemeHandler;
import org.oscim.theme.styles.RenderStyle;
-import org.xml.sax.Attributes;
public abstract class Rule {
- private static final Map, AttributeMatcher> MATCHERS_CACHE_KEY =
- new HashMap, AttributeMatcher>();
- private static final Map, AttributeMatcher> MATCHERS_CACHE_VALUE =
- new HashMap, AttributeMatcher>();
+ public final static RenderStyle[] EMPTY_STYLE = new RenderStyle[0];
+ public final static Rule[] EMPTY_RULES = new Rule[0];
- private static final String STRING_NEGATION = "~";
- private static final String STRING_EXCLUSIVE = "-";
- private static final String STRING_WILDCARD = "*";
+ private final Rule[] subRules;
+ public final RenderStyle[] styles;
- private static Rule createRule(Stack ruleStack, int element, String keys,
- String values, byte zoomMin, byte zoomMax, boolean matchFirst) {
+ private final int zoom;
+ private final int element;
+ private final boolean selectFirstMatch;
+ private final boolean selectWhenMatched;
- // zoom-level bitmask
- int zoom = 0;
- for (int z = zoomMin; z <= zoomMax && z < 32; z++)
- zoom |= (1 << z);
+ Rule(int element, int zoom, int selector, Rule[] subRules, RenderStyle[] styles) {
+ this.element = element;
+ this.zoom = zoom;
- List keyList = null, valueList = null;
- boolean negativeRule = false;
- boolean exclusionRule = false;
+ this.subRules = (subRules == null) ? EMPTY_RULES : subRules;
+ this.styles = (styles == null) ? EMPTY_STYLE : styles;
- AttributeMatcher keyMatcher, valueMatcher = null;
-
- if (values == null) {
- valueMatcher = AnyMatcher.getInstance();
- } else {
- valueList = new ArrayList(Arrays.asList(values.split("\\|")));
- if (valueList.remove(STRING_NEGATION))
- negativeRule = true;
- else if (valueList.remove(STRING_EXCLUSIVE))
- exclusionRule = true;
- else {
- valueMatcher = getValueMatcher(valueList);
- valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
- }
- }
-
- if (keys == null) {
- if (negativeRule || exclusionRule) {
- throw new ThemeException("negative rule requires key");
- }
- keyMatcher = AnyMatcher.getInstance();
- } else {
- keyList = new ArrayList(Arrays.asList(keys.split("\\|")));
- keyMatcher = getKeyMatcher(keyList);
-
- if ((keyMatcher instanceof AnyMatcher) && (negativeRule || exclusionRule)) {
- throw new ThemeException("negative rule requires key");
- }
-
- if (negativeRule) {
- AttributeMatcher m = new NegativeMatcher(keyList, valueList, false);
- return new NegativeRule(element, zoom, matchFirst, m);
- } else if (exclusionRule) {
- AttributeMatcher m = new NegativeMatcher(keyList, valueList, true);
- return new NegativeRule(element, zoom, matchFirst, m);
- }
-
- keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
- }
-
- return new PositiveRule(element, zoom, matchFirst, keyMatcher, valueMatcher);
- }
-
- private static AttributeMatcher getKeyMatcher(List keyList) {
- if (STRING_WILDCARD.equals(keyList.get(0))) {
- return AnyMatcher.getInstance();
- }
-
- AttributeMatcher attributeMatcher = MATCHERS_CACHE_KEY.get(keyList);
- if (attributeMatcher == null) {
- if (keyList.size() == 1) {
- attributeMatcher = new SingleKeyMatcher(keyList.get(0));
- } else {
- attributeMatcher = new MultiKeyMatcher(keyList);
- }
- MATCHERS_CACHE_KEY.put(keyList, attributeMatcher);
- }
- return attributeMatcher;
- }
-
- private static AttributeMatcher getValueMatcher(List valueList) {
- if (STRING_WILDCARD.equals(valueList.get(0))) {
- return AnyMatcher.getInstance();
- }
-
- AttributeMatcher attributeMatcher = MATCHERS_CACHE_VALUE.get(valueList);
- if (attributeMatcher == null) {
- if (valueList.size() == 1) {
- attributeMatcher = new SingleValueMatcher(valueList.get(0));
- } else {
- attributeMatcher = new MultiValueMatcher(valueList);
- }
- MATCHERS_CACHE_VALUE.put(valueList, attributeMatcher);
- }
- return attributeMatcher;
- }
-
- private static void validate(byte zoomMin, byte zoomMax) {
- if (zoomMin < 0)
- throw new ThemeException("zoom-min must not be negative: " + zoomMin);
- else if (zoomMax < 0)
- throw new ThemeException("zoom-max must not be negative: " + zoomMax);
- else if (zoomMin > zoomMax)
- throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
- }
-
- public static Rule create(String elementName, Attributes attributes, Stack ruleStack) {
- int element = Element.ANY;
- int closed = Closed.ANY;
- String keys = null;
- String values = null;
- byte zoomMin = 0;
- byte zoomMax = Byte.MAX_VALUE;
- boolean matchFirst = false;
-
- for (int i = 0; i < attributes.getLength(); ++i) {
- String name = attributes.getLocalName(i);
- String value = attributes.getValue(i);
-
- if ("e".equals(name)) {
- String val = value.toUpperCase();
- if ("WAY".equals(val))
- element = Element.WAY;
- else if ("NODE".equals(val))
- element = Element.NODE;
- } else if ("k".equals(name)) {
- keys = value;
- } else if ("v".equals(name)) {
- values = value;
- } else if ("closed".equals(name)) {
- String val = value.toUpperCase();
- if ("YES".equals(val))
- closed = Closed.YES;
- else if ("NO".equals(val))
- closed = Closed.NO;
- } else if ("zoom-min".equals(name)) {
- zoomMin = Byte.parseByte(value);
- } else if ("zoom-max".equals(name)) {
- zoomMax = Byte.parseByte(value);
- } else if ("select".equals(name)) {
- matchFirst = "first".equals(value);
- } else {
- RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
- }
- }
-
- if (closed == Closed.YES)
- element = Element.POLY;
- else if (closed == Closed.NO)
- element = Element.LINE;
-
- validate(zoomMin, zoomMax);
-
- return createRule(ruleStack, element, keys, values, zoomMin, zoomMax, matchFirst);
- }
-
- private Rule[] mSubRules;
- private RenderStyle[] mRenderInstructions;
-
- final int mZoom;
- final int mElement;
- final boolean mMatchFirst;
-
- static class Builder {
- ArrayList renderInstructions = new ArrayList(4);
- ArrayList subRules = new ArrayList(4);
-
- public void clear() {
- renderInstructions.clear();
- renderInstructions = null;
- subRules.clear();
- subRules = null;
- }
- }
-
- private Builder builder;
-
- Rule(int type, int zoom, boolean matchFirst) {
- builder = new Builder();
- mElement = type;
- mZoom = zoom;
- mMatchFirst = matchFirst;
- }
-
- public void addRenderingInstruction(RenderStyle renderInstruction) {
- builder.renderInstructions.add(renderInstruction);
- }
-
- public void addSubRule(Rule rule) {
- builder.subRules.add(rule);
+ selectFirstMatch = (selector & Selector.FIRST) != 0;
+ selectWhenMatched = (selector & Selector.WHEN_MATCHED) != 0;
}
abstract boolean matchesTags(Tag[] tags);
- public boolean matchElement(int type, Tag[] tags, int zoomLevel,
- List matchingList) {
-
- if (((mElement & type) != 0) && ((mZoom & zoomLevel) != 0) && (matchesTags(tags))) {
+ public boolean matchElement(int type, Tag[] tags, int zoomLevel, List result) {
+ if (((element & type) != 0) && ((zoom & zoomLevel) != 0) && (matchesTags(tags))) {
boolean matched = false;
- // check subrules
- for (Rule subRule : mSubRules) {
- if (subRule.matchElement(type, tags, zoomLevel, matchingList) && mMatchFirst) {
- matched = true;
- break;
+ if (subRules != EMPTY_RULES) {
+ if (selectFirstMatch) {
+ /* only add first matching rule and when-matched rules iff a
+ * previous rule matched */
+ for (Rule r : subRules) {
+ /* continue if matched xor selectWhenMatch */
+ if (matched ^ r.selectWhenMatched)
+ continue;
+
+ if (r.matchElement(type, tags, zoomLevel, result))
+ matched = true;
+ }
+ } else {
+ /* add all rules and when-matched rules iff a previous rule
+ * matched */
+ for (Rule r : subRules) {
+ if (r.selectWhenMatched && !matched)
+ continue;
+
+ if (r.matchElement(type, tags, zoomLevel, result))
+ matched = true;
+ }
}
}
- if (!mMatchFirst || matched) {
- // add instructions for this rule
- for (RenderStyle ri : mRenderInstructions)
- matchingList.add(ri);
- }
+ if (styles == EMPTY_STYLE)
+ /* matched if styles where added */
+ return matched;
- // this rule did match
+ /* add instructions for this rule */
+ for (RenderStyle ri : styles)
+ result.add(ri);
+
+ /* this rule did not match */
return true;
}
- // this rule did not match
+ /* this rule did not match */
return false;
}
- public void onComplete() {
- MATCHERS_CACHE_KEY.clear();
- MATCHERS_CACHE_VALUE.clear();
+ public void dispose() {
+ for (RenderStyle ri : styles)
+ ri.dispose();
- mRenderInstructions = new RenderStyle[builder.renderInstructions.size()];
- builder.renderInstructions.toArray(mRenderInstructions);
-
- mSubRules = new Rule[builder.subRules.size()];
- builder.subRules.toArray(mSubRules);
-
- builder.clear();
- builder = null;
-
- for (Rule subRule : mSubRules)
- subRule.onComplete();
- }
-
- public void onDestroy() {
- for (RenderStyle ri : mRenderInstructions)
- ri.destroy();
-
- for (Rule subRule : mSubRules)
- subRule.onDestroy();
+ for (Rule subRule : subRules)
+ subRule.dispose();
}
public void scaleTextSize(float scaleFactor) {
- for (RenderStyle ri : mRenderInstructions)
+ for (RenderStyle ri : styles)
ri.scaleTextSize(scaleFactor);
- for (Rule subRule : mSubRules)
+
+ for (Rule subRule : subRules)
subRule.scaleTextSize(scaleFactor);
}
- public void updateInstructions() {
- for (RenderStyle ri : mRenderInstructions)
+ public void updateStyles() {
+ for (RenderStyle ri : styles)
ri.update();
- for (Rule subRule : mSubRules)
- subRule.updateInstructions();
+
+ for (Rule subRule : subRules)
+ subRule.updateStyles();
}
public static class RuleVisitor {
- boolean apply(Rule r) {
-
- for (Rule subRule : r.mSubRules)
+ public void apply(Rule r) {
+ for (Rule subRule : r.subRules)
this.apply(subRule);
+ }
+ }
- return true;
+ public static class TextSizeVisitor extends RuleVisitor {
+ float scaleFactor = 1;
+
+ public void setScaleFactor(float scaleFactor) {
+ this.scaleFactor = scaleFactor;
+ }
+
+ @Override
+ public void apply(Rule r) {
+ for (RenderStyle ri : r.styles)
+ ri.scaleTextSize(scaleFactor);
+ super.apply(r);
}
}
public static class UpdateVisitor extends RuleVisitor {
@Override
- boolean apply(Rule r) {
- for (RenderStyle ri : r.mRenderInstructions)
+ public void apply(Rule r) {
+ for (RenderStyle ri : r.styles)
ri.update();
-
- return super.apply(r);
+ super.apply(r);
}
}
- public boolean apply(RuleVisitor v) {
-
- return v.apply(this);
+ public void apply(RuleVisitor v) {
+ v.apply(this);
}
}
diff --git a/vtm/src/org/oscim/theme/rule/RuleBuilder.java b/vtm/src/org/oscim/theme/rule/RuleBuilder.java
new file mode 100644
index 00000000..00c3cca0
--- /dev/null
+++ b/vtm/src/org/oscim/theme/rule/RuleBuilder.java
@@ -0,0 +1,271 @@
+package org.oscim.theme.rule;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.oscim.theme.IRenderTheme.ThemeException;
+import org.oscim.theme.XmlThemeBuilder;
+import org.oscim.theme.styles.RenderStyle;
+import org.xml.sax.Attributes;
+
+public class RuleBuilder {
+ boolean positiveRule;
+
+ int zoom;
+ int element;
+ int selector;
+
+ AttributeMatcher keyMatcher;
+ AttributeMatcher valueMatcher;
+
+ ArrayList renderStyles = new ArrayList(4);
+ ArrayList subRules = new ArrayList(4);
+
+ private static final Map, AttributeMatcher> MATCHERS_CACHE_KEY =
+ new HashMap, AttributeMatcher>();
+ private static final Map, AttributeMatcher> MATCHERS_CACHE_VALUE =
+ new HashMap, AttributeMatcher>();
+
+ private static final String STRING_NEGATION = "~";
+ private static final String STRING_EXCLUSIVE = "-";
+ private static final String STRING_WILDCARD = "*";
+
+ private static final int SELECT_FIRST = 1 << 0;
+ private static final int SELECT_WHEN_MATCHED = 1 << 1;
+
+ public RuleBuilder(boolean positive, int element, int zoom, int selector,
+ AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
+ this.positiveRule = positive;
+ this.element = element;
+ this.zoom = zoom;
+ this.selector = selector;
+ this.keyMatcher = keyMatcher;
+ this.valueMatcher = valueMatcher;
+ }
+
+ public RuleBuilder(boolean positive, AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
+ this.positiveRule = positive;
+ this.keyMatcher = keyMatcher;
+ this.valueMatcher = valueMatcher;
+ }
+
+ public static RuleBuilder create(Stack ruleStack, String keys, String values) {
+
+ List keyList = null, valueList = null;
+ boolean negativeRule = false;
+ boolean exclusionRule = false;
+
+ AttributeMatcher keyMatcher, valueMatcher = null;
+
+ if (values == null) {
+ valueMatcher = AnyMatcher.getInstance();
+ } else {
+ valueList = new ArrayList(Arrays.asList(values.split("\\|")));
+ if (valueList.remove(STRING_NEGATION))
+ negativeRule = true;
+ else if (valueList.remove(STRING_EXCLUSIVE))
+ exclusionRule = true;
+ else {
+ valueMatcher = getValueMatcher(valueList);
+ valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
+ }
+ }
+
+ if (keys == null) {
+ if (negativeRule || exclusionRule) {
+ throw new ThemeException("negative rule requires key");
+ }
+ keyMatcher = AnyMatcher.getInstance();
+ } else {
+ keyList = new ArrayList(Arrays.asList(keys.split("\\|")));
+ keyMatcher = getKeyMatcher(keyList);
+
+ if ((keyMatcher instanceof AnyMatcher) && (negativeRule || exclusionRule)) {
+ throw new ThemeException("negative rule requires key");
+ }
+
+ if (negativeRule) {
+ AttributeMatcher m = new NegativeMatcher(keyList, valueList, false);
+ return new RuleBuilder(false, m, null);
+ } else if (exclusionRule) {
+ AttributeMatcher m = new NegativeMatcher(keyList, valueList, true);
+ return new RuleBuilder(false, m, null);
+ }
+
+ keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
+ }
+
+ return new RuleBuilder(true, keyMatcher, valueMatcher);
+ }
+
+ private static AttributeMatcher getKeyMatcher(List keyList) {
+ if (STRING_WILDCARD.equals(keyList.get(0))) {
+ return AnyMatcher.getInstance();
+ }
+
+ AttributeMatcher attributeMatcher = MATCHERS_CACHE_KEY.get(keyList);
+ if (attributeMatcher == null) {
+ if (keyList.size() == 1) {
+ attributeMatcher = new SingleKeyMatcher(keyList.get(0));
+ } else {
+ attributeMatcher = new MultiKeyMatcher(keyList);
+ }
+ MATCHERS_CACHE_KEY.put(keyList, attributeMatcher);
+ }
+ return attributeMatcher;
+ }
+
+ private static AttributeMatcher getValueMatcher(List valueList) {
+ if (STRING_WILDCARD.equals(valueList.get(0))) {
+ return AnyMatcher.getInstance();
+ }
+
+ AttributeMatcher attributeMatcher = MATCHERS_CACHE_VALUE.get(valueList);
+ if (attributeMatcher == null) {
+ if (valueList.size() == 1) {
+ attributeMatcher = new SingleValueMatcher(valueList.get(0));
+ } else {
+ attributeMatcher = new MultiValueMatcher(valueList);
+ }
+ MATCHERS_CACHE_VALUE.put(valueList, attributeMatcher);
+ }
+ return attributeMatcher;
+ }
+
+ private static void validate(byte zoomMin, byte zoomMax) {
+ XmlThemeBuilder.validateNonNegative("zoom-min", zoomMin);
+ XmlThemeBuilder.validateNonNegative("zoom-max", zoomMax);
+ if (zoomMin > zoomMax)
+ throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
+ }
+
+ public static RuleBuilder create(String elementName, Attributes attributes,
+ Stack ruleStack) {
+ int element = Element.ANY;
+ int closed = Closed.ANY;
+ String keys = null;
+ String values = null;
+ byte zoomMin = 0;
+ byte zoomMax = Byte.MAX_VALUE;
+ int selector = 0;
+
+ for (int i = 0; i < attributes.getLength(); ++i) {
+ String name = attributes.getLocalName(i);
+ String value = attributes.getValue(i);
+
+ if ("e".equals(name)) {
+ String val = value.toUpperCase();
+ if ("WAY".equals(val))
+ element = Element.WAY;
+ else if ("NODE".equals(val))
+ element = Element.NODE;
+ } else if ("k".equals(name)) {
+ keys = value;
+ } else if ("v".equals(name)) {
+ values = value;
+ } else if ("closed".equals(name)) {
+ String val = value.toUpperCase();
+ if ("YES".equals(val))
+ closed = Closed.YES;
+ else if ("NO".equals(val))
+ closed = Closed.NO;
+ } else if ("zoom-min".equals(name)) {
+ zoomMin = Byte.parseByte(value);
+ } else if ("zoom-max".equals(name)) {
+ zoomMax = Byte.parseByte(value);
+ } else if ("select".equals(name)) {
+ if ("first".equals(value))
+ selector |= SELECT_FIRST;
+ if ("when-matched".equals(value))
+ selector |= SELECT_WHEN_MATCHED;
+ } else {
+ XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ }
+ }
+
+ if (closed == Closed.YES)
+ element = Element.POLY;
+ else if (closed == Closed.NO)
+ element = Element.LINE;
+
+ validate(zoomMin, zoomMax);
+
+ RuleBuilder b = create(ruleStack, keys, values);
+ b.setZoom(zoomMin, zoomMax);
+ b.element = element;
+ b.selector = selector;
+ return b;
+ }
+
+ public RuleBuilder setZoom(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() {
+ MATCHERS_CACHE_KEY.clear();
+ MATCHERS_CACHE_VALUE.clear();
+
+ RenderStyle[] styles = null;
+ Rule[] rules = null;
+
+ 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();
+ }
+
+ if (positiveRule)
+ return new PositiveRule(element, zoom, selector, keyMatcher,
+ valueMatcher, rules, styles);
+ else
+ return new NegativeRule(element, zoom, selector, keyMatcher,
+ rules, styles);
+ }
+
+ public void addStyle(RenderStyle style) {
+ renderStyles.add(style);
+ }
+
+ public void addSubRule(RuleBuilder rule) {
+ subRules.add(rule);
+ }
+
+ RuleBuilder(boolean positive) {
+ this.positiveRule = positive;
+ this.element = Element.ANY;
+ this.zoom = ~0;
+ }
+
+ public static RuleBuilder get() {
+ return new RuleBuilder(true);
+ }
+
+ 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;
+ }
+}
diff --git a/vtm/src/org/oscim/theme/rule/RuleOptimizer.java b/vtm/src/org/oscim/theme/rule/RuleOptimizer.java
index e6bae924..5b74f873 100644
--- a/vtm/src/org/oscim/theme/rule/RuleOptimizer.java
+++ b/vtm/src/org/oscim/theme/rule/RuleOptimizer.java
@@ -22,12 +22,13 @@ import java.util.Stack;
final class RuleOptimizer {
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
- Stack ruleStack) {
+ Stack ruleStack) {
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
- if (ruleStack.get(i) instanceof PositiveRule) {
- PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
- if (positiveRule.mKeyMatcher != null
- && positiveRule.mKeyMatcher.isCoveredBy(attributeMatcher)) {
+ if (ruleStack.get(i).positiveRule) {
+ RuleBuilder positiveRule = ruleStack.get(i);
+
+ if (positiveRule.keyMatcher != null
+ && positiveRule.keyMatcher.isCoveredBy(attributeMatcher)) {
return null;
}
}
@@ -37,13 +38,13 @@ final class RuleOptimizer {
}
private static AttributeMatcher optimizeValueMatcher(
- AttributeMatcher attributeMatcher, Stack ruleStack) {
+ AttributeMatcher attributeMatcher, Stack ruleStack) {
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
- if (ruleStack.get(i) instanceof PositiveRule) {
- PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
+ if (ruleStack.get(i).positiveRule) {
+ RuleBuilder positiveRule = ruleStack.get(i);
- if (positiveRule.mValueMatcher != null
- && positiveRule.mValueMatcher.isCoveredBy(attributeMatcher)) {
+ if (positiveRule.valueMatcher != null
+ && positiveRule.valueMatcher.isCoveredBy(attributeMatcher)) {
return null;
}
}
@@ -53,7 +54,7 @@ final class RuleOptimizer {
}
static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
- Stack ruleStack) {
+ Stack ruleStack) {
if (attributeMatcher instanceof AnyMatcher)
return attributeMatcher;// return null;
else if (attributeMatcher instanceof NegativeMatcher) {
diff --git a/vtm/src/org/oscim/theme/rule/Selector.java b/vtm/src/org/oscim/theme/rule/Selector.java
new file mode 100644
index 00000000..9ba12caf
--- /dev/null
+++ b/vtm/src/org/oscim/theme/rule/Selector.java
@@ -0,0 +1,8 @@
+package org.oscim.theme.rule;
+
+public class Selector {
+
+ public static final int ANY = 0;
+ public static final int FIRST = 1 << 0;
+ public static final int WHEN_MATCHED = 1 << 1;
+}
diff --git a/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java b/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java
index 12eda8a5..90b26088 100644
--- a/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java
+++ b/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java
@@ -19,10 +19,10 @@ package org.oscim.theme.rule;
import org.oscim.core.Tag;
-class SingleKeyMatcher implements AttributeMatcher {
+public class SingleKeyMatcher implements AttributeMatcher {
private final String mKey;
- SingleKeyMatcher(String key) {
+ public SingleKeyMatcher(String key) {
mKey = key.intern();
}
diff --git a/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java b/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java
index 5327bf56..8dc3ef7b 100644
--- a/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java
+++ b/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java
@@ -19,10 +19,10 @@ package org.oscim.theme.rule;
import org.oscim.core.Tag;
-class SingleValueMatcher implements AttributeMatcher {
+public class SingleValueMatcher implements AttributeMatcher {
private final String mValue;
- SingleValueMatcher(String value) {
+ public SingleValueMatcher(String value) {
mValue = value.intern();
}
diff --git a/vtm/src/org/oscim/theme/styles/Area.java b/vtm/src/org/oscim/theme/styles/Area.java
deleted file mode 100644
index aaaa704c..00000000
--- a/vtm/src/org/oscim/theme/styles/Area.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * 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.styles;
-
-import org.oscim.backend.canvas.Color;
-import org.oscim.renderer.elements.TextureItem;
-import org.oscim.theme.IRenderTheme.Callback;
-
-/**
- * Represents a closed polygon on the map.
- */
-public final class Area extends RenderStyle {
-
- public Area(int fill) {
- this(0, fill);
- }
-
- public Area(int level, int fill) {
- this.level = level;
- this.style = "";
- this.fade = -1;
- this.blendColor = 0;
- this.blend = -1;
- this.color = fill;
- this.texture = null;
- this.outline = null;
- }
-
- public Area(String style, int fill, int stroke, float strokeWidth,
- int fade, int level, int blend, int blendFill, TextureItem texture) {
-
- this.style = style;
- this.color = fill;
- this.blendColor = blendFill;
- this.blend = blend;
- this.fade = fade;
- this.level = level;
- this.texture = texture;
-
- if (stroke == Color.TRANSPARENT) {
- this.outline = null;
- return;
- }
-
- this.outline = new Line(level + 1, stroke, strokeWidth);
- }
-
- @Override
- public void renderWay(Callback renderCallback) {
- renderCallback.renderArea(this, level);
-
- if (outline != null)
- renderCallback.renderWay(outline, level + 1);
- }
-
- private final int level;
- public String style;
- public final Line outline;
- public final int color;
- public final int fade;
- public final int blendColor;
- public final int blend;
- public final TextureItem texture;
-}
diff --git a/vtm/src/org/oscim/theme/styles/AreaLevel.java b/vtm/src/org/oscim/theme/styles/AreaLevel.java
deleted file mode 100644
index 31ab5809..00000000
--- a/vtm/src/org/oscim/theme/styles/AreaLevel.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2013 Hannes Janetzek
- *
- * 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.styles;
-
-import org.oscim.theme.IRenderTheme.Callback;
-
-public class AreaLevel extends RenderStyle {
- private final Area area;
- private final int level;
-
- public AreaLevel(Area area, int level) {
- this.area = area;
- this.level = level;
- }
-
- @Override
- public void renderWay(Callback renderCallback) {
- renderCallback.renderArea(this.area, level);
- if (this.area.outline != null)
- renderCallback.renderWay(this.area.outline, level + 1);
- }
-}
diff --git a/vtm/src/org/oscim/theme/styles/AreaStyle.java b/vtm/src/org/oscim/theme/styles/AreaStyle.java
new file mode 100644
index 00000000..84e22611
--- /dev/null
+++ b/vtm/src/org/oscim/theme/styles/AreaStyle.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2013 Hannes Janetzek
+ *
+ * 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.styles;
+
+import static org.oscim.backend.canvas.Color.parseColor;
+
+import org.oscim.backend.canvas.Color;
+import org.oscim.renderer.elements.TextureItem;
+import org.oscim.theme.IRenderTheme.Callback;
+
+public class AreaStyle extends RenderStyle {
+
+ /** Drawing order level */
+ private final int level;
+
+ /** Style name */
+ public final String style;
+
+ /** Fill color */
+ public final int color;
+
+ /** Fade-out zoom-level */
+ public final int fadeScale;
+
+ /** Fade to blendColor zoom-level */
+ public final int blendColor;
+
+ /** Blend fill color */
+ public final int blendScale;
+
+ /** Pattern texture */
+ public final TextureItem texture;
+
+ /** Outline */
+ public final LineStyle outline;
+
+ public AreaStyle(int color) {
+ this(0, color);
+ }
+
+ public AreaStyle(int level, int color) {
+ this.level = level;
+ this.style = "";
+ this.fadeScale = -1;
+ this.blendColor = 0;
+ this.blendScale = -1;
+ this.color = color;
+ this.texture = null;
+ this.outline = null;
+ }
+
+ public AreaStyle(AreaBuilder b) {
+ this.level = b.level;
+ this.style = b.style;
+ this.fadeScale = b.fadeScale;
+ this.blendColor = b.blendColor;
+ this.blendScale = b.blendScale;
+ this.color = b.color;
+ this.texture = b.texture;
+
+ if (b.outline != null &&
+ b.outlineColor == b.outline.color &&
+ b.outlineWidth == b.outline.width) {
+ this.outline = b.outline;
+ } else if (b.outlineColor != Color.TRANSPARENT) {
+ this.outline = new LineStyle(-1, b.outlineColor, b.outlineWidth);
+ } else {
+ this.outline = null;
+ }
+ }
+
+ @Override
+ public void update() {
+ super.update();
+
+ if (outline != null)
+ outline.update();
+ }
+
+ public AreaStyle current() {
+ return (AreaStyle) (mCurrent == null ? this : mCurrent);
+ }
+
+ @Override
+ public void renderWay(Callback renderCallback) {
+ renderCallback.renderArea(this, level);
+
+ if (outline != null)
+ renderCallback.renderWay(outline, level + 1);
+ }
+
+ public static class AreaBuilder {
+ public int level;
+ public String style;
+ public LineStyle outline;
+ public int color;
+ public int fadeScale;
+ public int blendColor;
+ public int blendScale;
+
+ public int outlineColor;
+ public float outlineWidth;
+
+ public TextureItem texture;
+
+ public AreaBuilder set(AreaStyle area) {
+ if (area == null)
+ return reset();
+
+ this.level = area.level;
+ this.style = area.style;
+ this.fadeScale = area.fadeScale;
+ this.blendColor = area.blendColor;
+ this.blendScale = area.blendScale;
+ this.color = area.color;
+ this.texture = area.texture;
+ this.outline = area.outline;
+ if (area.outline != null) {
+ this.outlineColor = outline.color;
+ this.outlineWidth = outline.width;
+ } else {
+ outlineColor = Color.TRANSPARENT;
+ outlineWidth = 1;
+ }
+
+ return this;
+ }
+
+ public AreaBuilder style(String name) {
+ this.style = name;
+ return this;
+ }
+
+ public AreaBuilder level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ public AreaBuilder outline(int color, float width) {
+ this.outlineColor = color;
+ this.outlineWidth = width;
+ return this;
+ }
+
+ public AreaBuilder outlineColor(int color) {
+ this.outlineColor = color;
+ return this;
+ }
+
+ public AreaBuilder outlineColor(String color) {
+ this.outlineColor = parseColor(color);
+ return this;
+ }
+
+ public AreaBuilder outlineWidth(float width) {
+ this.outlineWidth = width;
+ return this;
+ }
+
+ public AreaBuilder color(int color) {
+ this.color = color;
+ return this;
+ }
+
+ public AreaBuilder color(String color) {
+ this.color = parseColor(color);
+ return this;
+ }
+
+ public AreaBuilder blendScale(int zoom) {
+ this.blendScale = zoom;
+ return this;
+ }
+
+ public AreaBuilder blendColor(int color) {
+ this.blendColor = color;
+ return this;
+ }
+
+ public AreaBuilder blendColor(String color) {
+ this.blendColor = parseColor(color);
+ return this;
+ }
+
+ public AreaBuilder texture(TextureItem texture) {
+ this.texture = texture;
+ return this;
+ }
+
+ public AreaBuilder fadeScale(int zoom) {
+ this.fadeScale = zoom;
+ return this;
+ }
+
+ public AreaBuilder reset() {
+ color = Color.BLACK;
+
+ outlineColor = Color.TRANSPARENT;
+ outlineWidth = 1;
+
+ fadeScale = -1;
+ blendScale = -1;
+ blendColor = Color.TRANSPARENT;
+ style = null;
+ texture = null;
+ return this;
+ }
+
+ public AreaStyle build() {
+ return new AreaStyle(this);
+ }
+ }
+}
diff --git a/vtm/src/org/oscim/theme/styles/Circle.java b/vtm/src/org/oscim/theme/styles/CircleStyle.java
similarity index 92%
rename from vtm/src/org/oscim/theme/styles/Circle.java
rename to vtm/src/org/oscim/theme/styles/CircleStyle.java
index c8129219..c11eff9e 100644
--- a/vtm/src/org/oscim/theme/styles/Circle.java
+++ b/vtm/src/org/oscim/theme/styles/CircleStyle.java
@@ -22,7 +22,7 @@ import org.oscim.theme.IRenderTheme.Callback;
/**
* Represents a round area on the map.
*/
-public final class Circle extends RenderStyle {
+public final class CircleStyle extends RenderStyle {
public final int level;
@@ -33,7 +33,7 @@ public final class Circle extends RenderStyle {
public final boolean scaleRadius;
public final float strokeWidth;
- public Circle(Float radius, boolean scaleRadius, int fill, int stroke,
+ public CircleStyle(Float radius, boolean scaleRadius, int fill, int stroke,
float strokeWidth, int level) {
super();
diff --git a/vtm/src/org/oscim/theme/styles/Extrusion.java b/vtm/src/org/oscim/theme/styles/ExtrusionStyle.java
similarity index 93%
rename from vtm/src/org/oscim/theme/styles/Extrusion.java
rename to vtm/src/org/oscim/theme/styles/ExtrusionStyle.java
index a4827347..d96b2d7a 100644
--- a/vtm/src/org/oscim/theme/styles/Extrusion.java
+++ b/vtm/src/org/oscim/theme/styles/ExtrusionStyle.java
@@ -19,9 +19,9 @@ package org.oscim.theme.styles;
import org.oscim.backend.canvas.Color;
import org.oscim.theme.IRenderTheme.Callback;
-public class Extrusion extends RenderStyle {
+public class ExtrusionStyle extends RenderStyle {
- public Extrusion(int level, int colorSides, int colorTop, int colorLine, int defaultHeight) {
+ public ExtrusionStyle(int level, int colorSides, int colorTop, int colorLine, int defaultHeight) {
this.colors = new float[16];
fillColors(colorSides, colorTop, colorLine, colors);
diff --git a/vtm/src/org/oscim/theme/styles/Line.java b/vtm/src/org/oscim/theme/styles/Line.java
deleted file mode 100644
index 15160302..00000000
--- a/vtm/src/org/oscim/theme/styles/Line.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * 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.styles;
-
-import org.oscim.backend.canvas.Paint.Cap;
-import org.oscim.theme.IRenderTheme.Callback;
-
-/**
- * Represents a polyline on the map.
- */
-public final class Line extends RenderStyle {
-
- private final int level;
-
- public final String style;
- public final float width;
- public final int color;
- public final Cap cap;
- public final boolean outline;
- public final boolean fixed;
- public final int fade;
- public final float blur;
-
- public final int stipple;
- public final int stippleColor;
- public final float stippleWidth;
-
- public Line(int level, String style, int color, float width,
- Cap cap, boolean fixed,
- int stipple, int stippleColor, float stippleWidth,
- int fade, float blur, boolean isOutline) {
-
- this.level = level;
- this.style = style;
- this.outline = isOutline;
-
- // paint = new Paint(Paint.ANTI_ALIAS_FLAG);
- //
- // if (src != null) {
- // Shader shader = BitmapUtils.createBitmapShader(src);
- // paint.setShader(shader);
- // }
- //
- // paint.setStyle(Style.STROKE);
- // paint.setColor(stroke);
- // if (strokeDasharray != null) {
- // paint.setPathEffect(new DashPathEffect(strokeDasharray, 0));
- // }
-
- //GlUtils.changeSaturation(color, 1.02f);
-
- this.cap = cap;
- this.color = color;
- this.width = width;
- this.fixed = fixed;
-
- this.stipple = stipple;
- this.stippleColor = stippleColor;
- this.stippleWidth = stippleWidth;
-
- this.blur = blur;
- this.fade = fade;
- }
-
- public Line(int stroke, float width) {
- this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false);
- }
-
- public Line(int level, int stroke, float width) {
- this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false);
- }
-
- public Line(int stroke, float width, Cap cap) {
- this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false);
- }
-
- @Override
- public void renderWay(Callback renderCallback) {
- renderCallback.renderWay(this, level);
- }
-}
diff --git a/vtm/src/org/oscim/theme/styles/LineStyle.java b/vtm/src/org/oscim/theme/styles/LineStyle.java
new file mode 100644
index 00000000..e9924f5f
--- /dev/null
+++ b/vtm/src/org/oscim/theme/styles/LineStyle.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2010, 2011, 2012 mapsforge.org
+ * Copyright 2013 Hannes Janetzek
+ *
+ * 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.styles;
+
+import static org.oscim.backend.canvas.Color.parseColor;
+
+import org.oscim.backend.canvas.Color;
+import org.oscim.backend.canvas.Paint.Cap;
+import org.oscim.theme.IRenderTheme.Callback;
+
+public final class LineStyle extends RenderStyle {
+
+ final int level;
+ public final String style;
+ public final float width;
+ public final int color;
+ public final Cap cap;
+ public final boolean outline;
+ public final boolean fixed;
+ public final int fadeScale;
+ public final float blur;
+
+ public final int stipple;
+ public final int stippleColor;
+ public final float stippleWidth;
+
+ private LineStyle(LineBuilder builer) {
+ this.level = builer.level;
+ this.style = builer.style;
+ this.width = builer.width;
+ this.color = builer.color;
+ this.cap = builer.cap;
+ this.outline = builer.outline;
+ this.fixed = builer.fixed;
+ this.fadeScale = builer.fadeScale;
+ this.blur = builer.blur;
+ this.stipple = builer.stipple;
+ this.stippleColor = builer.stippleColor;
+ this.stippleWidth = builer.stippleWidth;
+ }
+
+ public LineStyle(int level, String style, int color, float width,
+ Cap cap, boolean fixed,
+ int stipple, int stippleColor, float stippleWidth,
+ int fadeScale, float blur, boolean isOutline) {
+
+ this.level = level;
+ this.style = style;
+ this.outline = isOutline;
+
+ this.cap = cap;
+ this.color = color;
+ this.width = width;
+ this.fixed = fixed;
+
+ this.stipple = stipple;
+ this.stippleColor = stippleColor;
+ this.stippleWidth = stippleWidth;
+
+ this.blur = blur;
+ this.fadeScale = fadeScale;
+ }
+
+ public LineStyle(int stroke, float width) {
+ this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false);
+ }
+
+ public LineStyle(int level, int stroke, float width) {
+ this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false);
+ }
+
+ public LineStyle(int stroke, float width, Cap cap) {
+ this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false);
+ }
+
+ @Override
+ public void renderWay(Callback renderCallback) {
+ renderCallback.renderWay(this, level);
+ }
+
+ public final static class LineBuilder {
+ public int level;
+
+ public String style;
+ public float width;
+ public int color;
+ public Cap cap;
+ public boolean outline;
+ public boolean fixed;
+ public int fadeScale;
+ public float blur;
+
+ public int stipple;
+ public int stippleColor;
+ public float stippleWidth;
+
+ public LineBuilder set(LineStyle line) {
+ if (line == null)
+ return reset();
+ this.level = line.level;
+ this.style = line.style;
+ this.width = line.width;
+ this.color = line.color;
+ this.cap = line.cap;
+ this.outline = line.outline;
+ this.fixed = line.fixed;
+ this.fadeScale = line.fadeScale;
+ this.blur = line.blur;
+ this.stipple = line.stipple;
+ this.stippleColor = line.stippleColor;
+ this.stippleWidth = line.stippleWidth;
+ return this;
+ }
+
+ public LineBuilder reset() {
+ level = -1;
+ style = null;
+ color = Color.BLACK;
+ cap = Cap.ROUND;
+ width = 1;
+ fixed = false;
+
+ fadeScale = -1;
+ blur = 0;
+
+ stipple = 0;
+ stippleWidth = 1;
+ stippleColor = Color.BLACK;
+
+ return this;
+ }
+
+ public LineBuilder style(String name) {
+ this.style = name;
+ return this;
+ }
+
+ public LineBuilder level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ public LineBuilder color(int color) {
+ this.color = color;
+ return this;
+ }
+
+ public LineBuilder width(float width) {
+ this.width = width;
+ return this;
+ }
+
+ public LineBuilder blur(float blur) {
+ this.blur = blur;
+ return this;
+ }
+
+ public LineBuilder fadeScale(int zoom) {
+ this.fadeScale = zoom;
+ return this;
+ }
+
+ public LineBuilder stippleColor(int color) {
+ this.stippleColor = color;
+ return this;
+ }
+
+ public LineBuilder color(String color) {
+ this.color = parseColor(color);
+ return this;
+ }
+
+ public LineBuilder stippleColor(String color) {
+ this.stippleColor = parseColor(color);
+ return this;
+ }
+
+ public LineBuilder isOutline(boolean outline) {
+ this.outline = outline;
+ return this;
+ }
+
+ public LineStyle build() {
+ return new LineStyle(this);
+ }
+ }
+}
diff --git a/vtm/src/org/oscim/theme/styles/LineSymbol.java b/vtm/src/org/oscim/theme/styles/LineSymbol.java
deleted file mode 100644
index 2c042740..00000000
--- a/vtm/src/org/oscim/theme/styles/LineSymbol.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * 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.styles;
-
-import org.oscim.theme.IRenderTheme.Callback;
-
-/**
- * Represents an icon along a polyline on the map.
- */
-public final class LineSymbol extends RenderStyle {
-
- public final boolean alignCenter;
- // public final Bitmap bitmap;
- public final boolean repeat;
- public final String bitmap;
-
- public LineSymbol(String src, boolean alignCenter, boolean repeat) {
- super();
-
- this.bitmap = src;
- // this.bitmap = BitmapUtils.createBitmap(src);
- this.alignCenter = alignCenter;
- this.repeat = repeat;
- }
-
- @Override
- public void renderWay(Callback renderCallback) {
- renderCallback.renderWaySymbol(this);
- }
-}
diff --git a/vtm/src/org/oscim/theme/styles/RenderStyle.java b/vtm/src/org/oscim/theme/styles/RenderStyle.java
index 2158d35f..21f4a2a3 100644
--- a/vtm/src/org/oscim/theme/styles/RenderStyle.java
+++ b/vtm/src/org/oscim/theme/styles/RenderStyle.java
@@ -41,7 +41,7 @@ public abstract class RenderStyle {
/**
* Destroys this RenderInstruction and cleans up all its internal resources.
*/
- public void destroy() {
+ public void dispose() {
}
/**
diff --git a/vtm/src/org/oscim/theme/styles/Symbol.java b/vtm/src/org/oscim/theme/styles/SymbolStyle.java
similarity index 91%
rename from vtm/src/org/oscim/theme/styles/Symbol.java
rename to vtm/src/org/oscim/theme/styles/SymbolStyle.java
index f9e79215..28000b6f 100644
--- a/vtm/src/org/oscim/theme/styles/Symbol.java
+++ b/vtm/src/org/oscim/theme/styles/SymbolStyle.java
@@ -23,16 +23,16 @@ import org.oscim.theme.IRenderTheme.Callback;
/**
* Represents an icon on the map.
*/
-public final class Symbol extends RenderStyle {
+public final class SymbolStyle extends RenderStyle {
public final TextureRegion texture;
- public Symbol(TextureRegion symbol) {
+ public SymbolStyle(TextureRegion symbol) {
this.texture = symbol;
}
@Override
- public void destroy() {
+ public void dispose() {
}
@Override
diff --git a/vtm/src/org/oscim/theme/styles/Text.java b/vtm/src/org/oscim/theme/styles/Text.java
deleted file mode 100644
index 063b5c4c..00000000
--- a/vtm/src/org/oscim/theme/styles/Text.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * 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.styles;
-
-import org.oscim.backend.CanvasAdapter;
-import org.oscim.backend.canvas.Paint;
-import org.oscim.backend.canvas.Paint.Align;
-import org.oscim.backend.canvas.Paint.FontFamily;
-import org.oscim.backend.canvas.Paint.FontStyle;
-import org.oscim.renderer.atlas.TextureRegion;
-import org.oscim.theme.IRenderTheme.Callback;
-
-/**
- * Represents a text along a polyline on the map.
- */
-public final class Text extends RenderStyle {
-
- public final String style;
-
- public final float fontSize;
- public final Paint paint;
- public final Paint stroke;
- public final String textKey;
-
- public final boolean caption;
- public final float dy;
- public final int priority;
-
- public float fontHeight;
- public float fontDescent;
-
- public final TextureRegion texture;
-
- public static Text createText(float fontSize, float strokeWidth, int fill, int outline,
- boolean billboard) {
-
- return createText("", fontSize, strokeWidth, fill, outline, billboard);
- }
-
- public static Text createText(String textKey, float fontSize, float strokeWidth, int fill,
- int outline,
- boolean billboard) {
-
- Text t = new Text("",
- textKey,
- FontFamily.DEFAULT,
- FontStyle.NORMAL,
- fontSize,
- fill,
- outline,
- strokeWidth,
- 0,
- billboard,
- null,
- Integer.MAX_VALUE);
-
- t.fontHeight = t.paint.getFontHeight();
- t.fontDescent = t.paint.getFontDescent();
-
- return t;
- }
-
- public Text(String style, String textKey, FontFamily fontFamily, FontStyle fontStyle,
- float fontSize, int fill, int outline, float strokeWidth, float dy, boolean caption,
- TextureRegion symbol, int priority) {
-
- this.style = style;
- this.textKey = textKey;
- this.caption = caption;
- this.dy = -dy;
- this.priority = priority;
- this.texture = symbol;
-
- paint = CanvasAdapter.g.getPaint();
- paint.setTextAlign(Align.CENTER);
- paint.setTypeface(fontFamily, fontStyle);
-
- paint.setColor(fill);
- paint.setTextSize(fontSize);
-
- if (strokeWidth > 0) {
- stroke = CanvasAdapter.g.getPaint();
- stroke.setStyle(Paint.Style.STROKE);
- stroke.setTextAlign(Align.CENTER);
- stroke.setTypeface(fontFamily, fontStyle);
- stroke.setColor(outline);
- stroke.setStrokeWidth(strokeWidth);
- stroke.setTextSize(fontSize);
- } else
- stroke = null;
-
- this.fontSize = fontSize;
-
- //fontHeight = paint.getFontHeight();
- //fontDescent = paint.getFontDescent();
- }
-
- @Override
- public void renderNode(Callback renderCallback) {
- if (caption)
- renderCallback.renderPointText(this);
- }
-
- @Override
- public void renderWay(Callback renderCallback) {
- if (caption)
- renderCallback.renderAreaText(this);
- else
- renderCallback.renderWayText(this);
- }
-
- @Override
- public void scaleTextSize(float scaleFactor) {
- paint.setTextSize(fontSize * scaleFactor);
- if (stroke != null)
- stroke.setTextSize(fontSize * scaleFactor);
-
- fontHeight = paint.getFontHeight();
- fontDescent = paint.getFontDescent();
- }
-}
diff --git a/vtm/src/org/oscim/theme/styles/TextStyle.java b/vtm/src/org/oscim/theme/styles/TextStyle.java
new file mode 100644
index 00000000..6bb9a2bf
--- /dev/null
+++ b/vtm/src/org/oscim/theme/styles/TextStyle.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2013 Hannes Janetzek
+ *
+ * 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.styles;
+
+import org.oscim.backend.CanvasAdapter;
+import org.oscim.backend.canvas.Color;
+import org.oscim.backend.canvas.Paint;
+import org.oscim.backend.canvas.Paint.Align;
+import org.oscim.backend.canvas.Paint.FontFamily;
+import org.oscim.backend.canvas.Paint.FontStyle;
+import org.oscim.renderer.atlas.TextureRegion;
+import org.oscim.theme.IRenderTheme.Callback;
+
+public final class TextStyle extends RenderStyle {
+
+ public static class TextBuilder {
+
+ public String style;
+ public float fontSize;
+
+ public String textKey;
+ public boolean caption;
+ public float dy;
+ public int priority;
+ public TextureRegion texture;
+ public FontFamily fontFamily;
+ public FontStyle fontStyle;
+
+ public int color;
+ public int stroke;
+ public float strokeWidth;
+
+ public TextBuilder reset() {
+ fontFamily = FontFamily.DEFAULT;
+ fontStyle = FontStyle.NORMAL;
+ style = null;
+ textKey = null;
+ fontSize = 0;
+ caption = false;
+ priority = Integer.MAX_VALUE;
+ texture = null;
+ color = Color.BLACK;
+ stroke = Color.BLACK;
+ strokeWidth = 0;
+ dy = 0;
+ return this;
+ }
+
+ public TextBuilder() {
+ reset();
+ }
+
+ public TextStyle build() {
+ TextStyle t = new TextStyle(this);
+ t.fontHeight = t.paint.getFontHeight();
+ t.fontDescent = t.paint.getFontDescent();
+ return t;
+ }
+
+ public TextStyle buildInternal() {
+ return new TextStyle(this);
+ }
+
+ public TextBuilder setStyle(String style) {
+ this.style = style;
+ return this;
+ }
+
+ public TextBuilder setFontSize(float fontSize) {
+ this.fontSize = fontSize;
+ return this;
+ }
+
+ public TextBuilder setTextKey(String textKey) {
+ this.textKey = textKey;
+ return this;
+ }
+
+ public TextBuilder setCaption(boolean caption) {
+ this.caption = caption;
+ return this;
+ }
+
+ public TextBuilder setOffsetY(float dy) {
+ this.dy = dy;
+ return this;
+ }
+
+ public TextBuilder setPriority(int priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ public TextBuilder setTexture(TextureRegion texture) {
+ this.texture = texture;
+ return this;
+ }
+
+ public TextBuilder setFontFamily(FontFamily fontFamily) {
+ this.fontFamily = fontFamily;
+ return this;
+ }
+
+ public TextBuilder setFontStyle(FontStyle fontStyle) {
+ this.fontStyle = fontStyle;
+ return this;
+ }
+
+ public TextBuilder setColor(int color) {
+ this.color = color;
+ return this;
+ }
+
+ public TextBuilder setStroke(int stroke) {
+ this.stroke = stroke;
+ return this;
+ }
+
+ public TextBuilder setStrokeWidth(float strokeWidth) {
+ this.strokeWidth = strokeWidth;
+ return this;
+ }
+ }
+
+ TextStyle(TextBuilder tb) {
+ this.style = tb.style;
+ this.textKey = tb.textKey;
+ this.caption = tb.caption;
+ this.dy = tb.dy;
+ this.priority = tb.priority;
+ this.texture = tb.texture;
+
+ paint = CanvasAdapter.g.getPaint();
+ paint.setTextAlign(Align.CENTER);
+ paint.setTypeface(tb.fontFamily, tb.fontStyle);
+
+ paint.setColor(tb.color);
+ paint.setTextSize(tb.fontSize);
+
+ if (tb.strokeWidth > 0) {
+ stroke = CanvasAdapter.g.getPaint();
+ stroke.setStyle(Paint.Style.STROKE);
+ stroke.setTextAlign(Align.CENTER);
+ stroke.setTypeface(tb.fontFamily, tb.fontStyle);
+ stroke.setColor(tb.stroke);
+ stroke.setStrokeWidth(tb.strokeWidth);
+ stroke.setTextSize(tb.fontSize);
+ } else
+ stroke = null;
+
+ this.fontSize = tb.fontSize;
+ }
+
+ public final String style;
+
+ public final float fontSize;
+ public final Paint paint;
+ public final Paint stroke;
+ public final String textKey;
+
+ public final boolean caption;
+ public final float dy;
+ public final int priority;
+
+ public float fontHeight;
+ public float fontDescent;
+
+ public final TextureRegion texture;
+
+ @Override
+ public void renderNode(Callback renderCallback) {
+ if (caption)
+ renderCallback.renderPointText(this);
+ }
+
+ @Override
+ public void renderWay(Callback renderCallback) {
+ if (caption)
+ renderCallback.renderAreaText(this);
+ else
+ renderCallback.renderWayText(this);
+ }
+
+ @Override
+ public void scaleTextSize(float scaleFactor) {
+ paint.setTextSize(fontSize * scaleFactor);
+ if (stroke != null)
+ stroke.setTextSize(fontSize * scaleFactor);
+
+ fontHeight = paint.getFontHeight();
+ fontDescent = paint.getFontDescent();
+ }
+}