Merge branch 'theme_refactor'
This commit is contained in:
commit
604c1449e4
@ -1 +1 @@
|
||||
Subproject commit 43a6277c1aa089f778f10ec1f2fd9b7034e63f0a
|
||||
Subproject commit 7449e47e8ec147c816eb3b8b77d07109035fab4d
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -79,7 +79,7 @@
|
||||
stipple-stroke="#be6253" />
|
||||
<style-line id="water:outline" stroke="#a4bbcc" width="1.0" fix="true" cap="butt" />
|
||||
|
||||
<style-line id="water" stroke="#a4bbcc" width="1.0" cap="butt" fix="true"/>
|
||||
<style-line id="water" stroke="#a4bbcc" width="1.0" cap="butt" fix="true" />
|
||||
<style-line id="river" use="water" stroke="#a4bbcc" fix="false" />
|
||||
|
||||
<!--<style-area id="water" fill="#97b7e5" afc5e3 /> -->
|
||||
@ -143,7 +143,7 @@
|
||||
</atlas>
|
||||
|
||||
<!-- all closed ways that are not 'highway' or 'building'-->
|
||||
|
||||
|
||||
<m e="way" k="highway|building" v="~" closed="yes">
|
||||
|
||||
<!-- landuse base -->
|
||||
@ -151,11 +151,11 @@
|
||||
<m v="urban">
|
||||
<area fill="#f4f3f0" />
|
||||
</m>
|
||||
|
||||
|
||||
<m v="meadow|conservation">
|
||||
<area use="greens" fade="11" />
|
||||
</m>
|
||||
|
||||
|
||||
<m v="residential|commercial|retail|farmyard">
|
||||
<area use="residential" />
|
||||
</m>
|
||||
@ -1064,7 +1064,10 @@
|
||||
<m k="amenity" v="cinema">
|
||||
<symbol src="cinema" />
|
||||
</m>
|
||||
<text use="poi" />
|
||||
|
||||
<m select="when-matched">
|
||||
<text use="poi" />
|
||||
</m>
|
||||
</m>
|
||||
|
||||
<m zoom-min="16" select="first">
|
||||
@ -1089,7 +1092,9 @@
|
||||
<m k="amenity" v="bus_station">
|
||||
<symbol src="bus_station" />
|
||||
</m>
|
||||
<text use="poi" />
|
||||
<m select="when-matched">
|
||||
<text use="poi" />
|
||||
</m>
|
||||
</m>
|
||||
|
||||
<m zoom-min="17" select="first">
|
||||
@ -1152,7 +1157,9 @@
|
||||
<m k="amenity" v="theatre">
|
||||
<symbol src="theatre" />
|
||||
</m>
|
||||
<text use="poi" />
|
||||
<m select="when-matched">
|
||||
<text use="poi" />
|
||||
</m>
|
||||
</m>
|
||||
|
||||
<m zoom-min="17">
|
||||
@ -1176,17 +1183,18 @@
|
||||
<m v="supermarket|organic">
|
||||
<symbol src="shop_supermarket" />
|
||||
</m>
|
||||
<m>
|
||||
|
||||
<m zoom-min="17">
|
||||
<symbol src="city" />
|
||||
</m>
|
||||
</m>
|
||||
<m zoom-min="17">
|
||||
<text use="poi" />
|
||||
|
||||
<m select="when-matched" zoom-min="17">
|
||||
<text use="poi" />
|
||||
</m>
|
||||
</m>
|
||||
</m>
|
||||
|
||||
<m k="tourism">
|
||||
|
||||
<m zoom-min="15" select="first">
|
||||
<m v="alpine_hut">
|
||||
<symbol src="triangle-stroked" />
|
||||
@ -1200,7 +1208,10 @@
|
||||
<m v="hotel">
|
||||
<symbol src="hotel" />
|
||||
</m>
|
||||
<text use="poi" />
|
||||
|
||||
<m select="when-matched">
|
||||
<text use="poi" />
|
||||
</m>
|
||||
</m>
|
||||
|
||||
<m zoom-min="16" select="first">
|
||||
|
@ -779,19 +779,19 @@
|
||||
<m k="bridge" v="yes|true">
|
||||
<m select="first">
|
||||
<m v="service">
|
||||
<line stroke="#ffffff" width="0.85" outline="casing-bridge"/>
|
||||
<line stroke="#ffffff" width="0.85" outline="casing-bridge" />
|
||||
<m zoom-min="15">
|
||||
<text k="name" style="bold" size="10" stroke="#ffffff" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="construction">
|
||||
<line stroke="#d0d0d0" width="1.0" outline="casing-bridge"/>
|
||||
<line stroke="#d0d0d0" width="1.0" outline="casing-bridge" />
|
||||
<m zoom-min="15">
|
||||
<text k="name" style="bold" size="10" stroke="#d0d0d0" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="road">
|
||||
<line stroke="#d0d0d0" width="1.25" outline="casing-bridge"/>
|
||||
<line stroke="#d0d0d0" width="1.25" outline="casing-bridge" />
|
||||
<m zoom-min="15">
|
||||
<text k="name" style="bold" size="10" stroke="#d0d0d0" stroke-width="2.0" />
|
||||
</m>
|
||||
@ -803,69 +803,69 @@
|
||||
</m>
|
||||
</m>
|
||||
<m v="unclassified|residential|living_street">
|
||||
<line stroke="#ffffff" width="1.25" outline="casing-bridge"/>
|
||||
<line stroke="#ffffff" width="1.25" outline="casing-bridge" />
|
||||
<m zoom-min="15">
|
||||
<text k="name" style="bold" size="10" stroke="#ffffff" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="byway">
|
||||
<line stroke="#efadaa" width="1.15" outline="casing-bridge"/>
|
||||
<line stroke="#efadaa" width="1.15" outline="casing-bridge" />
|
||||
<m zoom-min="15">
|
||||
<text k="name" style="bold" size="10" stroke="#efadaa" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="tertiary|tertiary_link">
|
||||
<line use="tertiary" cap="square" outline="casing-bridge"/>
|
||||
<line use="tertiary" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#ffff90" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="secondary_link">
|
||||
<line use="secondary" width="-0.1" cap="square" outline="casing-bridge"/>
|
||||
<line use="secondary" width="-0.1" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#fdbf6f" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="primary_link">
|
||||
<line use="primary" width="-0.1" cap="square" outline="casing-bridge"/>
|
||||
<line use="primary" width="-0.1" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#e46d71" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="trunk_link">
|
||||
<line use="trunk" cap="square" outline="casing-bridge"/>
|
||||
<line use="trunk" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#7fc97f" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="motorway_link">
|
||||
<line use="motorway" width="-0.2" cap="square" outline="casing-bridge"/>
|
||||
<line use="motorway" width="-0.2" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#809bc0" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="secondary">
|
||||
<line use="secondary" cap="square" outline="casing-bridge"/>
|
||||
<line use="secondary" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#fdbf6f" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="primary">
|
||||
<line use="primary" cap="square" outline="casing-bridge"/>
|
||||
<line use="primary" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#e46d71" stroke-width="2.0" />
|
||||
<text k="ref" style="bold" size="12" stroke="#ffffff" fill="#606060" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="trunk">
|
||||
<line use="trunk" outline="casing-bridge"/>
|
||||
<line use="trunk" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#7fc97f" stroke-width="2.0" />
|
||||
<text k="ref" style="bold" size="12" stroke="#ffffff" fill="#606060" stroke-width="2.0" />
|
||||
</m>
|
||||
</m>
|
||||
<m v="motorway">
|
||||
<line use="motorway" cap="square" outline="casing-bridge"/>
|
||||
<line use="motorway" cap="square" outline="casing-bridge" />
|
||||
<m zoom-min="14">
|
||||
<text k="name" style="bold" size="10" stroke="#809bc0" stroke-width="2.0" />
|
||||
<text k="ref" style="bold" size="12" stroke="#ffffff" fill="#606060" stroke-width="2.0" />
|
||||
|
@ -2,7 +2,7 @@
|
||||
<rendertheme xmlns="http://opensciencemap.org/rendertheme" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://opensciencemap.org/rendertheme ../../rendertheme.xsd" version="1" map-background="#050508">
|
||||
|
||||
<atlas img="styles/osmarender.png">
|
||||
<atlas img="styles/osmarender.png">
|
||||
<rect id="airport" pos="226 38 24 24" />
|
||||
<rect id="alpine_hut" pos="198 41 26 21" />
|
||||
<rect id="atm" pos="279 2 14 16" />
|
||||
@ -62,10 +62,10 @@
|
||||
<rect id="vulcan" pos="315 25 9 8" />
|
||||
<rect id="windmill" pos="310 2 13 19" />
|
||||
</atlas>
|
||||
|
||||
<style-text id="caption-small-blue" caption="true" dy="12" k="name" style="bold" size="16" fill="#4040ff"
|
||||
|
||||
<style-text id="caption-small-blue" caption="true" dy="12" k="name" style="bold" size="16" fill="#4040ff"
|
||||
stroke="#ffffff" stroke-width="2.0" />
|
||||
|
||||
|
||||
<style-text id="road" k="name" style="bold" size="18" stroke="#606050" fill="#eeffee" stroke-width="2.5" />
|
||||
<style-text id="major-road" k="name" style="bold" size="19" fill="#ffef7d" stroke="#624f00" stroke-width="2.5" />
|
||||
|
||||
@ -1312,7 +1312,7 @@
|
||||
</m>
|
||||
|
||||
|
||||
<m k="tourism">
|
||||
<m k="tourism" select="first">
|
||||
<m v="alpine_hut" zoom-min="16">
|
||||
<symbol src="alpine_hut" />
|
||||
</m>
|
||||
@ -1332,7 +1332,7 @@
|
||||
<symbol src="viewpoint" />
|
||||
</m>
|
||||
|
||||
<m zoom-min="17">
|
||||
<m select="when-matched" zoom-min="17">
|
||||
<text use="caption-small-blue" />
|
||||
</m>
|
||||
</m>
|
||||
|
@ -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<GeoPoint>();
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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<TextItem> {
|
||||
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<TextItem> {
|
||||
public String string;
|
||||
|
||||
// text style
|
||||
public Text text;
|
||||
public TextStyle text;
|
||||
|
||||
// label width
|
||||
public float width;
|
||||
|
@ -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];
|
||||
|
@ -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<Point> 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);
|
||||
|
||||
}
|
||||
|
@ -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() {
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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<RenderStyle> 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<Rule> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
125
vtm/src/org/oscim/theme/ThemeBuilder.java
Normal file
125
vtm/src/org/oscim/theme/ThemeBuilder.java
Normal file
@ -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<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>();
|
||||
protected final Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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<Rule> mRulesList = new ArrayList<Rule>();
|
||||
private Rule mCurrentRule;
|
||||
|
||||
private Stack<Element> mElementStack = new Stack<Element>();
|
||||
private Stack<Rule> mRuleStack = new Stack<Rule>();
|
||||
private HashMap<String, RenderStyle> mStyles =
|
||||
private final ArrayList<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>();
|
||||
private final Stack<Element> mElementStack = new Stack<Element>();
|
||||
private final Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
|
||||
private final HashMap<String, RenderStyle> mStyles =
|
||||
new HashMap<String, RenderStyle>(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);
|
||||
}
|
||||
}
|
@ -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).
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<List<String>, AttributeMatcher> MATCHERS_CACHE_KEY =
|
||||
new HashMap<List<String>, AttributeMatcher>();
|
||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_VALUE =
|
||||
new HashMap<List<String>, 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<Rule> 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<String> 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<String>(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<String>(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<String> 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<String> 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<Rule> 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<RenderStyle> renderInstructions = new ArrayList<RenderStyle>(4);
|
||||
ArrayList<Rule> subRules = new ArrayList<Rule>(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<RenderStyle> matchingList) {
|
||||
|
||||
if (((mElement & type) != 0) && ((mZoom & zoomLevel) != 0) && (matchesTags(tags))) {
|
||||
public boolean matchElement(int type, Tag[] tags, int zoomLevel, List<RenderStyle> 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);
|
||||
}
|
||||
}
|
||||
|
271
vtm/src/org/oscim/theme/rule/RuleBuilder.java
Normal file
271
vtm/src/org/oscim/theme/rule/RuleBuilder.java
Normal file
@ -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<RenderStyle> renderStyles = new ArrayList<RenderStyle>(4);
|
||||
ArrayList<RuleBuilder> subRules = new ArrayList<RuleBuilder>(4);
|
||||
|
||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_KEY =
|
||||
new HashMap<List<String>, AttributeMatcher>();
|
||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_VALUE =
|
||||
new HashMap<List<String>, 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<RuleBuilder> ruleStack, String keys, String values) {
|
||||
|
||||
List<String> keyList = null, valueList = null;
|
||||
boolean negativeRule = false;
|
||||
boolean exclusionRule = false;
|
||||
|
||||
AttributeMatcher keyMatcher, valueMatcher = null;
|
||||
|
||||
if (values == null) {
|
||||
valueMatcher = AnyMatcher.getInstance();
|
||||
} else {
|
||||
valueList = new ArrayList<String>(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<String>(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<String> 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<String> 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<RuleBuilder> 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;
|
||||
}
|
||||
}
|
@ -22,12 +22,13 @@ import java.util.Stack;
|
||||
final class RuleOptimizer {
|
||||
|
||||
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
|
||||
Stack<Rule> ruleStack) {
|
||||
Stack<RuleBuilder> 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<Rule> ruleStack) {
|
||||
AttributeMatcher attributeMatcher, Stack<RuleBuilder> 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<Rule> ruleStack) {
|
||||
Stack<RuleBuilder> ruleStack) {
|
||||
if (attributeMatcher instanceof AnyMatcher)
|
||||
return attributeMatcher;// return null;
|
||||
else if (attributeMatcher instanceof NegativeMatcher) {
|
||||
|
8
vtm/src/org/oscim/theme/rule/Selector.java
Normal file
8
vtm/src/org/oscim/theme/rule/Selector.java
Normal file
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
227
vtm/src/org/oscim/theme/styles/AreaStyle.java
Normal file
227
vtm/src/org/oscim/theme/styles/AreaStyle.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
202
vtm/src/org/oscim/theme/styles/LineStyle.java
Normal file
202
vtm/src/org/oscim/theme/styles/LineStyle.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ public abstract class RenderStyle {
|
||||
/**
|
||||
* Destroys this RenderInstruction and cleans up all its internal resources.
|
||||
*/
|
||||
public void destroy() {
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
207
vtm/src/org/oscim/theme/styles/TextStyle.java
Normal file
207
vtm/src/org/oscim/theme/styles/TextStyle.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user