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.ParserConfigurationException;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
||||||
import org.oscim.theme.RenderThemeHandler;
|
import org.oscim.theme.XmlThemeBuilder;
|
||||||
import org.oscim.tiling.TileSource.OpenResult;
|
import org.oscim.tiling.TileSource.OpenResult;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
@ -40,7 +40,7 @@ public final class ValidRenderTheme implements ValidFileFilter {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
inputStream = new FileInputStream(file);
|
inputStream = new FileInputStream(file);
|
||||||
RenderThemeHandler renderThemeHandler = new RenderThemeHandler();
|
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder();
|
||||||
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
||||||
xmlReader.setContentHandler(renderThemeHandler);
|
xmlReader.setContentHandler(renderThemeHandler);
|
||||||
xmlReader.parse(new InputSource(inputStream));
|
xmlReader.parse(new InputSource(inputStream));
|
||||||
|
@ -15,8 +15,8 @@ import org.oscim.jeo.JeoUtils;
|
|||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.elements.LineLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.elements.MeshLayer;
|
import org.oscim.renderer.elements.MeshLayer;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ public class JeoVectorLayer extends JtsLayer {
|
|||||||
if (ll.line == null) {
|
if (ll.line == null) {
|
||||||
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
|
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
|
||||||
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
|
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);
|
ll.setDropDistance(0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,14 +131,14 @@ public class JeoVectorLayer extends JtsLayer {
|
|||||||
if (ll.line == null) {
|
if (ll.line == null) {
|
||||||
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
|
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
|
||||||
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
|
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);
|
ll.setDropDistance(0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshLayer mesh = t.layers.getMeshLayer(0);
|
MeshLayer mesh = t.layers.getMeshLayer(0);
|
||||||
if (mesh.area == null) {
|
if (mesh.area == null) {
|
||||||
int color = JeoUtils.color(rule.color(f, CartoCSS.POLYGON_FILL, RGB.red));
|
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);
|
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.MeshLayer;
|
||||||
import org.oscim.renderer.elements.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.elements.TextLayer;
|
import org.oscim.renderer.elements.TextLayer;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
|
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
||||||
|
|
||||||
import com.vividsolutions.jts.geom.Envelope;
|
import com.vividsolutions.jts.geom.Envelope;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
@ -26,7 +27,10 @@ import com.vividsolutions.jts.geom.LineString;
|
|||||||
public class OSMIndoorLayer extends JeoVectorLayer {
|
public class OSMIndoorLayer extends JeoVectorLayer {
|
||||||
|
|
||||||
protected TextLayer mTextLayer;
|
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) {
|
public OSMIndoorLayer(Map map, VectorDataset data, Style style) {
|
||||||
super(map, data, style);
|
super(map, data, style);
|
||||||
@ -58,7 +62,7 @@ public class OSMIndoorLayer extends JeoVectorLayer {
|
|||||||
if (ll.line == null) {
|
if (ll.line == null) {
|
||||||
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
|
RGB color = rule.color(f, CartoCSS.LINE_COLOR, RGB.black);
|
||||||
float width = rule.number(f, CartoCSS.LINE_WIDTH, 1.2f);
|
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.heightOffset = level * 4;
|
||||||
ll.setDropDistance(0);
|
ll.setDropDistance(0);
|
||||||
}
|
}
|
||||||
@ -80,7 +84,7 @@ public class OSMIndoorLayer extends JeoVectorLayer {
|
|||||||
if (level > -2 && !active)
|
if (level > -2 && !active)
|
||||||
color = Color.fade(color, 0.1f);
|
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.heightOffset = level * 4;
|
||||||
ll.setDropDistance(0);
|
ll.setDropDistance(0);
|
||||||
}
|
}
|
||||||
@ -91,7 +95,7 @@ public class OSMIndoorLayer extends JeoVectorLayer {
|
|||||||
if (level > -2 && !active)
|
if (level > -2 && !active)
|
||||||
color = Color.fade(color, 0.1f);
|
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.area = new Area(Color.fade(Color.DKGRAY, 0.1f));
|
||||||
mesh.heightOffset = level * 4f;
|
mesh.heightOffset = level * 4f;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ import org.oscim.core.MapElement;
|
|||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
public class RenderTheme implements IRenderTheme {
|
public class RenderTheme implements IRenderTheme {
|
||||||
@ -147,11 +147,11 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
s.ri[0] = new Area(mCurLevel++, color(p));
|
s.ri[0] = new AreaStyle(mCurLevel++, color(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l != null) {
|
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) {
|
if (p != null || l != null) {
|
||||||
@ -198,7 +198,7 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
RGB c = r.color(f, CartoCSS.POLYGON_FILL, RGB.black);
|
RGB c = r.color(f, CartoCSS.POLYGON_FILL, RGB.black);
|
||||||
out.println(z + " " + c);
|
out.println(z + " " + c);
|
||||||
return new RenderStyle[] {
|
return new RenderStyle[] {
|
||||||
new Area(z, color(c))
|
new AreaStyle(z, color(c))
|
||||||
};
|
};
|
||||||
|
|
||||||
} else if (type == GeometryType.LINE) {
|
} else if (type == GeometryType.LINE) {
|
||||||
@ -207,7 +207,7 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
//out.println(z + " " + c);
|
//out.println(z + " " + c);
|
||||||
|
|
||||||
return new RenderStyle[] {
|
return new RenderStyle[] {
|
||||||
new Line(100 + z, color(c), width)
|
new LineStyle(100 + z, color(c), width)
|
||||||
};
|
};
|
||||||
|
|
||||||
} else if (type == GeometryType.POINT) {
|
} else if (type == GeometryType.POINT) {
|
||||||
@ -258,7 +258,7 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
stipple-stroke="#be6253" />
|
stipple-stroke="#be6253" />
|
||||||
<style-line id="water:outline" stroke="#a4bbcc" width="1.0" fix="true" cap="butt" />
|
<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-line id="river" use="water" stroke="#a4bbcc" fix="false" />
|
||||||
|
|
||||||
<!--<style-area id="water" fill="#97b7e5" afc5e3 /> -->
|
<!--<style-area id="water" fill="#97b7e5" afc5e3 /> -->
|
||||||
@ -143,7 +143,7 @@
|
|||||||
</atlas>
|
</atlas>
|
||||||
|
|
||||||
<!-- all closed ways that are not 'highway' or 'building'-->
|
<!-- all closed ways that are not 'highway' or 'building'-->
|
||||||
|
|
||||||
<m e="way" k="highway|building" v="~" closed="yes">
|
<m e="way" k="highway|building" v="~" closed="yes">
|
||||||
|
|
||||||
<!-- landuse base -->
|
<!-- landuse base -->
|
||||||
@ -151,11 +151,11 @@
|
|||||||
<m v="urban">
|
<m v="urban">
|
||||||
<area fill="#f4f3f0" />
|
<area fill="#f4f3f0" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m v="meadow|conservation">
|
<m v="meadow|conservation">
|
||||||
<area use="greens" fade="11" />
|
<area use="greens" fade="11" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m v="residential|commercial|retail|farmyard">
|
<m v="residential|commercial|retail|farmyard">
|
||||||
<area use="residential" />
|
<area use="residential" />
|
||||||
</m>
|
</m>
|
||||||
@ -1064,7 +1064,10 @@
|
|||||||
<m k="amenity" v="cinema">
|
<m k="amenity" v="cinema">
|
||||||
<symbol src="cinema" />
|
<symbol src="cinema" />
|
||||||
</m>
|
</m>
|
||||||
<text use="poi" />
|
|
||||||
|
<m select="when-matched">
|
||||||
|
<text use="poi" />
|
||||||
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m zoom-min="16" select="first">
|
<m zoom-min="16" select="first">
|
||||||
@ -1089,7 +1092,9 @@
|
|||||||
<m k="amenity" v="bus_station">
|
<m k="amenity" v="bus_station">
|
||||||
<symbol src="bus_station" />
|
<symbol src="bus_station" />
|
||||||
</m>
|
</m>
|
||||||
<text use="poi" />
|
<m select="when-matched">
|
||||||
|
<text use="poi" />
|
||||||
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m zoom-min="17" select="first">
|
<m zoom-min="17" select="first">
|
||||||
@ -1152,7 +1157,9 @@
|
|||||||
<m k="amenity" v="theatre">
|
<m k="amenity" v="theatre">
|
||||||
<symbol src="theatre" />
|
<symbol src="theatre" />
|
||||||
</m>
|
</m>
|
||||||
<text use="poi" />
|
<m select="when-matched">
|
||||||
|
<text use="poi" />
|
||||||
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m zoom-min="17">
|
<m zoom-min="17">
|
||||||
@ -1176,17 +1183,18 @@
|
|||||||
<m v="supermarket|organic">
|
<m v="supermarket|organic">
|
||||||
<symbol src="shop_supermarket" />
|
<symbol src="shop_supermarket" />
|
||||||
</m>
|
</m>
|
||||||
<m>
|
|
||||||
|
<m zoom-min="17">
|
||||||
<symbol src="city" />
|
<symbol src="city" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
|
||||||
<m zoom-min="17">
|
<m select="when-matched" zoom-min="17">
|
||||||
<text use="poi" />
|
<text use="poi" />
|
||||||
|
</m>
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m k="tourism">
|
<m k="tourism">
|
||||||
|
|
||||||
<m zoom-min="15" select="first">
|
<m zoom-min="15" select="first">
|
||||||
<m v="alpine_hut">
|
<m v="alpine_hut">
|
||||||
<symbol src="triangle-stroked" />
|
<symbol src="triangle-stroked" />
|
||||||
@ -1200,7 +1208,10 @@
|
|||||||
<m v="hotel">
|
<m v="hotel">
|
||||||
<symbol src="hotel" />
|
<symbol src="hotel" />
|
||||||
</m>
|
</m>
|
||||||
<text use="poi" />
|
|
||||||
|
<m select="when-matched">
|
||||||
|
<text use="poi" />
|
||||||
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m zoom-min="16" select="first">
|
<m zoom-min="16" select="first">
|
||||||
|
@ -779,19 +779,19 @@
|
|||||||
<m k="bridge" v="yes|true">
|
<m k="bridge" v="yes|true">
|
||||||
<m select="first">
|
<m select="first">
|
||||||
<m v="service">
|
<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">
|
<m zoom-min="15">
|
||||||
<text k="name" style="bold" size="10" stroke="#ffffff" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#ffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="construction">
|
<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">
|
<m zoom-min="15">
|
||||||
<text k="name" style="bold" size="10" stroke="#d0d0d0" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#d0d0d0" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="road">
|
<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">
|
<m zoom-min="15">
|
||||||
<text k="name" style="bold" size="10" stroke="#d0d0d0" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#d0d0d0" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
@ -803,69 +803,69 @@
|
|||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="unclassified|residential|living_street">
|
<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">
|
<m zoom-min="15">
|
||||||
<text k="name" style="bold" size="10" stroke="#ffffff" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#ffffff" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="byway">
|
<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">
|
<m zoom-min="15">
|
||||||
<text k="name" style="bold" size="10" stroke="#efadaa" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#efadaa" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="tertiary|tertiary_link">
|
<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">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#ffff90" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#ffff90" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="secondary_link">
|
<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">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#fdbf6f" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#fdbf6f" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="primary_link">
|
<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">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#e46d71" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#e46d71" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="trunk_link">
|
<m v="trunk_link">
|
||||||
<line use="trunk" cap="square" outline="casing-bridge"/>
|
<line use="trunk" cap="square" outline="casing-bridge" />
|
||||||
<m zoom-min="14">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#7fc97f" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#7fc97f" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="motorway_link">
|
<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">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#809bc0" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#809bc0" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="secondary">
|
<m v="secondary">
|
||||||
<line use="secondary" cap="square" outline="casing-bridge"/>
|
<line use="secondary" cap="square" outline="casing-bridge" />
|
||||||
<m zoom-min="14">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#fdbf6f" stroke-width="2.0" />
|
<text k="name" style="bold" size="10" stroke="#fdbf6f" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="primary">
|
<m v="primary">
|
||||||
<line use="primary" cap="square" outline="casing-bridge"/>
|
<line use="primary" cap="square" outline="casing-bridge" />
|
||||||
<m zoom-min="14">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#e46d71" stroke-width="2.0" />
|
<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" />
|
<text k="ref" style="bold" size="12" stroke="#ffffff" fill="#606060" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="trunk">
|
<m v="trunk">
|
||||||
<line use="trunk" outline="casing-bridge"/>
|
<line use="trunk" outline="casing-bridge" />
|
||||||
<m zoom-min="14">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#7fc97f" stroke-width="2.0" />
|
<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" />
|
<text k="ref" style="bold" size="12" stroke="#ffffff" fill="#606060" stroke-width="2.0" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
<m v="motorway">
|
<m v="motorway">
|
||||||
<line use="motorway" cap="square" outline="casing-bridge"/>
|
<line use="motorway" cap="square" outline="casing-bridge" />
|
||||||
<m zoom-min="14">
|
<m zoom-min="14">
|
||||||
<text k="name" style="bold" size="10" stroke="#809bc0" stroke-width="2.0" />
|
<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" />
|
<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"
|
<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">
|
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="airport" pos="226 38 24 24" />
|
||||||
<rect id="alpine_hut" pos="198 41 26 21" />
|
<rect id="alpine_hut" pos="198 41 26 21" />
|
||||||
<rect id="atm" pos="279 2 14 16" />
|
<rect id="atm" pos="279 2 14 16" />
|
||||||
@ -62,10 +62,10 @@
|
|||||||
<rect id="vulcan" pos="315 25 9 8" />
|
<rect id="vulcan" pos="315 25 9 8" />
|
||||||
<rect id="windmill" pos="310 2 13 19" />
|
<rect id="windmill" pos="310 2 13 19" />
|
||||||
</atlas>
|
</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" />
|
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="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" />
|
<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>
|
||||||
|
|
||||||
|
|
||||||
<m k="tourism">
|
<m k="tourism" select="first">
|
||||||
<m v="alpine_hut" zoom-min="16">
|
<m v="alpine_hut" zoom-min="16">
|
||||||
<symbol src="alpine_hut" />
|
<symbol src="alpine_hut" />
|
||||||
</m>
|
</m>
|
||||||
@ -1332,7 +1332,7 @@
|
|||||||
<symbol src="viewpoint" />
|
<symbol src="viewpoint" />
|
||||||
</m>
|
</m>
|
||||||
|
|
||||||
<m zoom-min="17">
|
<m select="when-matched" zoom-min="17">
|
||||||
<text use="caption-small-blue" />
|
<text use="caption-small-blue" />
|
||||||
</m>
|
</m>
|
||||||
</m>
|
</m>
|
||||||
|
@ -32,7 +32,7 @@ import org.oscim.renderer.ElementRenderer;
|
|||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.elements.ElementLayers;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.elements.LineLayer;
|
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.FastMath;
|
||||||
import org.oscim.utils.async.SimpleWorker;
|
import org.oscim.utils.async.SimpleWorker;
|
||||||
import org.oscim.utils.geom.LineClipper;
|
import org.oscim.utils.geom.LineClipper;
|
||||||
@ -45,14 +45,14 @@ public class PathLayer extends Layer {
|
|||||||
protected boolean mUpdatePoints;
|
protected boolean mUpdatePoints;
|
||||||
|
|
||||||
/** Line style */
|
/** Line style */
|
||||||
Line mLineStyle;
|
LineStyle mLineStyle;
|
||||||
|
|
||||||
final Worker mWorker;
|
final Worker mWorker;
|
||||||
|
|
||||||
public PathLayer(Map map, int lineColor, float lineWidth) {
|
public PathLayer(Map map, int lineColor, float lineWidth) {
|
||||||
super(map);
|
super(map);
|
||||||
mWorker = new Worker(map);
|
mWorker = new Worker(map);
|
||||||
mLineStyle = new Line(lineColor, lineWidth, Cap.BUTT);
|
mLineStyle = new LineStyle(lineColor, lineWidth, Cap.BUTT);
|
||||||
mRenderer = new RenderPath();
|
mRenderer = new RenderPath();
|
||||||
mPoints = new ArrayList<GeoPoint>();
|
mPoints = new ArrayList<GeoPoint>();
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package org.oscim.layers;
|
|||||||
import org.oscim.backend.canvas.Paint.Cap;
|
import org.oscim.backend.canvas.Paint.Cap;
|
||||||
import org.oscim.map.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.GridRenderer;
|
import org.oscim.renderer.GridRenderer;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
|
|
||||||
public class TileGridLayer extends GenericLayer {
|
public class TileGridLayer extends GenericLayer {
|
||||||
|
|
||||||
@ -13,10 +13,10 @@ public class TileGridLayer extends GenericLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TileGridLayer(Map map, int color, float width, int repeat) {
|
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) {
|
public TileGridLayer(Map map, int color, float width, TextStyle text, int repeat) {
|
||||||
super(map, new GridRenderer(repeat, new Line(color, width, Cap.BUTT), text));
|
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.map.Map;
|
||||||
import org.oscim.renderer.elements.ElementLayers;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.elements.LineLayer;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ public class TestTileLayer extends TileLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GeometryBuffer mGeom = new GeometryBuffer(128, 16);
|
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
|
@Override
|
||||||
public boolean loadTile(MapTile tile) {
|
public boolean loadTile(MapTile tile) {
|
||||||
|
@ -40,14 +40,13 @@ import org.oscim.renderer.elements.SymbolItem;
|
|||||||
import org.oscim.renderer.elements.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.RenderTheme;
|
import org.oscim.theme.RenderTheme;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Circle;
|
import org.oscim.theme.styles.CircleStyle;
|
||||||
import org.oscim.theme.styles.Extrusion;
|
import org.oscim.theme.styles.ExtrusionStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.LineSymbol;
|
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.theme.styles.Symbol;
|
import org.oscim.theme.styles.SymbolStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
import org.oscim.tiling.ITileDataSource;
|
import org.oscim.tiling.ITileDataSource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -248,7 +247,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
|
|
||||||
/*** RenderThemeCallback ***/
|
/*** RenderThemeCallback ***/
|
||||||
@Override
|
@Override
|
||||||
public void renderWay(Line line, int level) {
|
public void renderWay(LineStyle line, int level) {
|
||||||
int numLayer = mCurLayer + level;
|
int numLayer = mCurLayer + level;
|
||||||
|
|
||||||
if (line.stipple == 0) {
|
if (line.stipple == 0) {
|
||||||
@ -297,7 +296,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
protected final static boolean USE_MESH_POLY = false;
|
protected final static boolean USE_MESH_POLY = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderArea(Area area, int level) {
|
public void renderArea(AreaStyle area, int level) {
|
||||||
int numLayer = mCurLayer + level;
|
int numLayer = mCurLayer + level;
|
||||||
if (USE_MESH_POLY) {
|
if (USE_MESH_POLY) {
|
||||||
MeshLayer l = mTile.layers.getMeshLayer(numLayer);
|
MeshLayer l = mTile.layers.getMeshLayer(numLayer);
|
||||||
@ -311,7 +310,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAreaText(Text text) {
|
public void renderAreaText(TextStyle text) {
|
||||||
// TODO place somewhere on polygon
|
// TODO place somewhere on polygon
|
||||||
String value = mElement.tags.getValue(text.textKey);
|
String value = mElement.tags.getValue(text.textKey);
|
||||||
if (value == null || value.length() == 0)
|
if (value == null || value.length() == 0)
|
||||||
@ -332,7 +331,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderPointText(Text text) {
|
public void renderPointText(TextStyle text) {
|
||||||
String value = mElement.tags.getValue(text.textKey);
|
String value = mElement.tags.getValue(text.textKey);
|
||||||
if (value == null || value.length() == 0)
|
if (value == null || value.length() == 0)
|
||||||
return;
|
return;
|
||||||
@ -344,7 +343,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWayText(Text text) {
|
public void renderWayText(TextStyle text) {
|
||||||
String value = mElement.tags.getValue(text.textKey);
|
String value = mElement.tags.getValue(text.textKey);
|
||||||
if (value == null || value.length() == 0)
|
if (value == null || value.length() == 0)
|
||||||
return;
|
return;
|
||||||
@ -362,11 +361,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderPointCircle(Circle circle, int level) {
|
public void renderPointCircle(CircleStyle circle, int level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderPointSymbol(Symbol symbol) {
|
public void renderPointSymbol(SymbolStyle symbol) {
|
||||||
if (symbol.texture == null)
|
if (symbol.texture == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -380,16 +379,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAreaSymbol(Symbol symbol) {
|
public void renderAreaSymbol(SymbolStyle symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWaySymbol(LineSymbol symbol) {
|
public void renderExtrusion(ExtrusionStyle extrusion, int level) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderExtrusion(Extrusion extrusion, int level) {
|
|
||||||
int height = 0;
|
int height = 0;
|
||||||
int minHeight = 0;
|
int minHeight = 0;
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ package org.oscim.layers.tile.vector;
|
|||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.MapTile;
|
||||||
import org.oscim.renderer.elements.TextItem;
|
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.GeometryUtils;
|
||||||
import org.oscim.utils.geom.LineClipper;
|
import org.oscim.utils.geom.LineClipper;
|
||||||
|
|
||||||
public final class WayDecorator {
|
public final class WayDecorator {
|
||||||
|
|
||||||
public static void renderText(LineClipper clipper, float[] coordinates, String string,
|
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 items = textItems;
|
||||||
TextItem t = null;
|
TextItem t = null;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import org.oscim.renderer.GLViewport;
|
|||||||
import org.oscim.renderer.elements.ElementLayers;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.elements.LineLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.elements.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
|
|
||||||
class Debug {
|
class Debug {
|
||||||
|
|
||||||
@ -71,12 +71,12 @@ class Debug {
|
|||||||
int alpha = 0xaaffffff;
|
int alpha = 0xaaffffff;
|
||||||
|
|
||||||
dbg.clear();
|
dbg.clear();
|
||||||
dbg.addLineLayer(0, new Line((Color.BLUE & alpha), 2));
|
dbg.addLineLayer(0, new LineStyle((Color.BLUE & alpha), 2));
|
||||||
dbg.addLineLayer(1, new Line((Color.RED & alpha), 2));
|
dbg.addLineLayer(1, new LineStyle((Color.RED & alpha), 2));
|
||||||
dbg.addLineLayer(3, new Line((Color.YELLOW & alpha), 2));
|
dbg.addLineLayer(3, new LineStyle((Color.YELLOW & alpha), 2));
|
||||||
dbg.addLineLayer(2, new Line((Color.GREEN & alpha), 2));
|
dbg.addLineLayer(2, new LineStyle((Color.GREEN & alpha), 2));
|
||||||
dbg.addLineLayer(4, new Line((Color.CYAN & alpha), 2));
|
dbg.addLineLayer(4, new LineStyle((Color.CYAN & alpha), 2));
|
||||||
dbg.addLineLayer(5, new Line((Color.MAGENTA & alpha), 2));
|
dbg.addLineLayer(5, new LineStyle((Color.MAGENTA & alpha), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void draw(MapPosition pos, GLViewport m, ElementLayers layers) {
|
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.LineLayer;
|
||||||
import org.oscim.renderer.elements.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.elements.TextLayer;
|
import org.oscim.renderer.elements.TextLayer;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
|
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
||||||
|
|
||||||
public class GridRenderer extends ElementRenderer {
|
public class GridRenderer extends ElementRenderer {
|
||||||
private final TextLayer mTextLayer;
|
private final TextLayer mTextLayer;
|
||||||
private final Text mText;
|
private final TextStyle mText;
|
||||||
private final LineLayer mLineLayer;
|
private final LineLayer mLineLayer;
|
||||||
private final GeometryBuffer mLines;
|
private final GeometryBuffer mLines;
|
||||||
private final StringBuffer mStringBuffer;
|
private final StringBuffer mStringBuffer;
|
||||||
@ -36,11 +37,11 @@ public class GridRenderer extends ElementRenderer {
|
|||||||
private int mCurX, mCurY, mCurZ;
|
private int mCurX, mCurY, mCurZ;
|
||||||
|
|
||||||
public GridRenderer() {
|
public GridRenderer() {
|
||||||
this(1, new Line(Color.LTGRAY, 1.2f, Cap.BUTT),
|
this(1, new LineStyle(Color.LTGRAY, 1.2f, Cap.BUTT),
|
||||||
Text.createText(22, 0, Color.RED, 0, false));
|
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;
|
int size = Tile.SIZE;
|
||||||
|
|
||||||
// not needed to set but we know:
|
// not needed to set but we know:
|
||||||
|
@ -25,8 +25,8 @@ import java.nio.ShortBuffer;
|
|||||||
|
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ public class ElementLayers {
|
|||||||
* add the LineLayer for a level with a given Line style. Levels are
|
* add the LineLayer for a level with a given Line style. Levels are
|
||||||
* ordered from bottom (0) to top
|
* 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);
|
LineLayer l = (LineLayer) getLayer(level, LINE);
|
||||||
if (l == null)
|
if (l == null)
|
||||||
return null;
|
return null;
|
||||||
@ -93,7 +93,7 @@ public class ElementLayers {
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PolygonLayer addPolygonLayer(int level, Area style) {
|
public PolygonLayer addPolygonLayer(int level, AreaStyle style) {
|
||||||
PolygonLayer l = (PolygonLayer) getLayer(level, POLYGON);
|
PolygonLayer l = (PolygonLayer) getLayer(level, POLYGON);
|
||||||
if (l == null)
|
if (l == null)
|
||||||
return null;
|
return null;
|
||||||
@ -101,7 +101,7 @@ public class ElementLayers {
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MeshLayer addMeshLayer(int level, Area style) {
|
public MeshLayer addMeshLayer(int level, AreaStyle style) {
|
||||||
MeshLayer l = (MeshLayer) getLayer(level, MESH);
|
MeshLayer l = (MeshLayer) getLayer(level, MESH);
|
||||||
if (l == null)
|
if (l == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -29,7 +29,7 @@ import org.oscim.renderer.GLState;
|
|||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
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.oscim.utils.pool.Inlist;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -64,7 +64,7 @@ public final class LineLayer extends RenderElement {
|
|||||||
|
|
||||||
/* lines referenced by this outline layer */
|
/* lines referenced by this outline layer */
|
||||||
public LineLayer outlines;
|
public LineLayer outlines;
|
||||||
public Line line;
|
public LineStyle line;
|
||||||
public float scale = 1;
|
public float scale = 1;
|
||||||
|
|
||||||
public boolean roundCap;
|
public boolean roundCap;
|
||||||
@ -749,7 +749,7 @@ public final class LineLayer extends RenderElement {
|
|||||||
RenderElement l = curLayer;
|
RenderElement l = curLayer;
|
||||||
for (; l != null && l.type == RenderElement.LINE; l = l.next) {
|
for (; l != null && l.type == RenderElement.LINE; l = l.next) {
|
||||||
LineLayer ll = (LineLayer) l;
|
LineLayer ll = (LineLayer) l;
|
||||||
Line line = (Line) ll.line.getCurrent();
|
LineStyle line = (LineStyle) ll.line.getCurrent();
|
||||||
|
|
||||||
if (ll.heightOffset != heightOffset) {
|
if (ll.heightOffset != heightOffset) {
|
||||||
heightOffset = ll.heightOffset;
|
heightOffset = ll.heightOffset;
|
||||||
@ -758,9 +758,9 @@ public final class LineLayer extends RenderElement {
|
|||||||
MercatorProjection.groundResolution(v.pos));
|
MercatorProjection.groundResolution(v.pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.fade < v.pos.zoomLevel) {
|
if (line.fadeScale < v.pos.zoomLevel) {
|
||||||
GLUtils.setColor(uLineColor, line.color, 1);
|
GLUtils.setColor(uLineColor, line.color, 1);
|
||||||
} else if (line.fade > v.pos.zoomLevel) {
|
} else if (line.fadeScale > v.pos.zoomLevel) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1;
|
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 */
|
/* draw LineLayers references by this outline */
|
||||||
|
|
||||||
for (LineLayer ref = ll.outlines; ref != null; ref = ref.outlines) {
|
for (LineLayer ref = ll.outlines; ref != null; ref = ref.outlines) {
|
||||||
Line core = (Line) ref.line.getCurrent();
|
LineStyle core = (LineStyle) ref.line.getCurrent();
|
||||||
|
|
||||||
// core width
|
// core width
|
||||||
if (core.fixed) {
|
if (core.fixed) {
|
||||||
|
@ -26,7 +26,7 @@ import org.oscim.renderer.GLState;
|
|||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
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.oscim.utils.pool.Inlist;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -86,7 +86,7 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
|
|
||||||
/* lines referenced by this outline layer */
|
/* lines referenced by this outline layer */
|
||||||
public LineLayer outlines;
|
public LineLayer outlines;
|
||||||
public Line line;
|
public LineStyle line;
|
||||||
public float width;
|
public float width;
|
||||||
|
|
||||||
//public boolean roundCap;
|
//public boolean roundCap;
|
||||||
@ -362,7 +362,7 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
RenderElement l = curLayer;
|
RenderElement l = curLayer;
|
||||||
for (; l != null && l.type == TEXLINE; l = l.next) {
|
for (; l != null && l.type == TEXLINE; l = l.next) {
|
||||||
LineTexLayer ll = (LineTexLayer) l;
|
LineTexLayer ll = (LineTexLayer) l;
|
||||||
Line line = ll.line;
|
LineStyle line = ll.line;
|
||||||
|
|
||||||
GLUtils.setColor(hTexColor, line.stippleColor, 1);
|
GLUtils.setColor(hTexColor, line.stippleColor, 1);
|
||||||
GLUtils.setColor(hBgColor, line.color, 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.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
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.Tessellator;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -41,7 +41,7 @@ public class MeshLayer extends RenderElement {
|
|||||||
int numIndices;
|
int numIndices;
|
||||||
|
|
||||||
VertexItem indiceItems;
|
VertexItem indiceItems;
|
||||||
public Area area;
|
public AreaStyle area;
|
||||||
public float heightOffset;
|
public float heightOffset;
|
||||||
|
|
||||||
public MeshLayer(int level) {
|
public MeshLayer(int level) {
|
||||||
|
@ -29,7 +29,7 @@ import org.oscim.renderer.GLState;
|
|||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
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.FastMath;
|
||||||
import org.oscim.utils.math.Interpolation;
|
import org.oscim.utils.math.Interpolation;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
@ -46,7 +46,7 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
private static final boolean enableTexture = true;
|
private static final boolean enableTexture = true;
|
||||||
|
|
||||||
public Area area;
|
public AreaStyle area;
|
||||||
|
|
||||||
PolygonLayer(int layer) {
|
PolygonLayer(int layer) {
|
||||||
super(RenderElement.POLYGON);
|
super(RenderElement.POLYGON);
|
||||||
@ -181,7 +181,7 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
int shader = polyShader;
|
int shader = polyShader;
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
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) {
|
if (enableTexture && a.texture != null) {
|
||||||
shader = texShader;
|
shader = texShader;
|
||||||
@ -194,10 +194,10 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
a.texture.bind();
|
a.texture.bind();
|
||||||
|
|
||||||
} else if (a.fade >= zoom) {
|
} else if (a.fadeScale >= zoom) {
|
||||||
float f = 1.0f;
|
float f = 1.0f;
|
||||||
/* fade in/out */
|
/* fade in/out */
|
||||||
if (a.fade >= zoom) {
|
if (a.fadeScale >= zoom) {
|
||||||
if (scale > FADE_START)
|
if (scale > FADE_START)
|
||||||
f = scale - 1;
|
f = scale - 1;
|
||||||
else
|
else
|
||||||
@ -207,11 +207,11 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
GLUtils.setColor(hPolygonColor[shader], a.color, f);
|
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) */
|
/* blend colors (not alpha) */
|
||||||
GLState.blend(false);
|
GLState.blend(false);
|
||||||
|
|
||||||
if (a.blend == zoom)
|
if (a.blendScale == zoom)
|
||||||
GLUtils.setColorBlend(hPolygonColor[shader],
|
GLUtils.setColorBlend(hPolygonColor[shader],
|
||||||
a.color, a.blendColor, scale - 1.0f);
|
a.color, a.blendColor, scale - 1.0f);
|
||||||
else
|
else
|
||||||
@ -301,7 +301,7 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
PolygonLayer pl = (PolygonLayer) l;
|
PolygonLayer pl = (PolygonLayer) l;
|
||||||
|
|
||||||
// fade out polygon layers (set in RenderTheme)
|
// 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;
|
continue;
|
||||||
|
|
||||||
if (cur == start) {
|
if (cur == start) {
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.renderer.elements;
|
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.Inlist;
|
||||||
import org.oscim.utils.pool.SyncPool;
|
import org.oscim.utils.pool.SyncPool;
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ public class TextItem extends Inlist<TextItem> {
|
|||||||
return ti;
|
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.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.string = string;
|
this.string = string;
|
||||||
@ -77,7 +77,7 @@ public class TextItem extends Inlist<TextItem> {
|
|||||||
public String string;
|
public String string;
|
||||||
|
|
||||||
// text style
|
// text style
|
||||||
public Text text;
|
public TextStyle text;
|
||||||
|
|
||||||
// label width
|
// label width
|
||||||
public float 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.LineLayer;
|
||||||
import org.oscim.renderer.elements.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.elements.TextLayer;
|
import org.oscim.renderer.elements.TextLayer;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
|
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -42,19 +43,19 @@ public class AtlasRenderLayer extends ElementRenderer {
|
|||||||
TextureAtlas mAtlas = TextureAtlas.create(2048, 2048, 1);
|
TextureAtlas mAtlas = TextureAtlas.create(2048, 2048, 1);
|
||||||
|
|
||||||
LineLayer ll = layers.getLineLayer(0);
|
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;
|
ll.scale = 1f;
|
||||||
|
|
||||||
LineLayer ll2 = layers.getLineLayer(1);
|
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;
|
ll2.scale = 1f;
|
||||||
|
|
||||||
LineLayer ll3 = layers.getLineLayer(2);
|
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;
|
ll3.scale = 1f;
|
||||||
|
|
||||||
TextLayer tl = new TextLayer();
|
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);
|
layers.setTextureLayers(tl);
|
||||||
|
|
||||||
float[] points = new float[10];
|
float[] points = new float[10];
|
||||||
|
@ -8,7 +8,7 @@ import org.oscim.core.Point;
|
|||||||
import org.oscim.renderer.ElementRenderer;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.elements.LineLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.utils.geom.BezierPath;
|
import org.oscim.utils.geom.BezierPath;
|
||||||
|
|
||||||
public class BezierPathLayer extends ElementRenderer {
|
public class BezierPathLayer extends ElementRenderer {
|
||||||
@ -27,7 +27,7 @@ public class BezierPathLayer extends ElementRenderer {
|
|||||||
// System.out.println(pts[i]);
|
// System.out.println(pts[i]);
|
||||||
g.addPoint(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);
|
ll.addLine(g);
|
||||||
|
|
||||||
List<Point> ctrl = BezierPath.cubicSplineControlPoints(pts, 0.1f);
|
List<Point> ctrl = BezierPath.cubicSplineControlPoints(pts, 0.1f);
|
||||||
@ -49,7 +49,7 @@ public class BezierPathLayer extends ElementRenderer {
|
|||||||
}
|
}
|
||||||
p0 = p3;
|
p0 = p3;
|
||||||
}
|
}
|
||||||
ll = layers.addLineLayer(1, new Line(Color.CYAN, 2f));
|
ll = layers.addLineLayer(1, new LineStyle(Color.CYAN, 2f));
|
||||||
ll.addLine(g);
|
ll.addLine(g);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@ package org.oscim.theme;
|
|||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
public class DebugTheme implements IRenderTheme {
|
public class DebugTheme implements IRenderTheme {
|
||||||
|
|
||||||
private final static Line[] line = { new Line(1, Color.MAGENTA, 2) };
|
private final static LineStyle[] line = { new LineStyle(1, Color.MAGENTA, 2) };
|
||||||
private final static Area[] area = { new Area(0, Color.CYAN) };
|
private final static AreaStyle[] area = { new AreaStyle(0, Color.CYAN) };
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RenderStyle[] matchElement(GeometryType type, TagSet tags, int zoomLevel) {
|
public RenderStyle[] matchElement(GeometryType type, TagSet tags, int zoomLevel) {
|
||||||
@ -41,7 +41,7 @@ public class DebugTheme implements IRenderTheme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.GeometryBuffer.GeometryType;
|
||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Circle;
|
import org.oscim.theme.styles.CircleStyle;
|
||||||
import org.oscim.theme.styles.Extrusion;
|
import org.oscim.theme.styles.ExtrusionStyle;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.LineStyle;
|
||||||
import org.oscim.theme.styles.LineSymbol;
|
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.theme.styles.Symbol;
|
import org.oscim.theme.styles.SymbolStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
|
|
||||||
public interface IRenderTheme {
|
public interface IRenderTheme {
|
||||||
|
|
||||||
@ -56,7 +55,7 @@ public interface IRenderTheme {
|
|||||||
*/
|
*/
|
||||||
public abstract int getMapBackground();
|
public abstract int getMapBackground();
|
||||||
|
|
||||||
public void updateInstructions();
|
public void updateStyles();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scales the text size of this RenderTheme by the given factor.
|
* Scales the text size of this RenderTheme by the given factor.
|
||||||
@ -76,7 +75,7 @@ public interface IRenderTheme {
|
|||||||
* @param area
|
* @param area
|
||||||
* @param level
|
* @param level
|
||||||
*/
|
*/
|
||||||
void renderArea(Area area, int level);
|
void renderArea(AreaStyle area, int level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders an extrusion with the given parameters.
|
* Renders an extrusion with the given parameters.
|
||||||
@ -84,7 +83,7 @@ public interface IRenderTheme {
|
|||||||
* @param extrusion
|
* @param extrusion
|
||||||
* @param level
|
* @param level
|
||||||
*/
|
*/
|
||||||
void renderExtrusion(Extrusion extrusion, int level);
|
void renderExtrusion(ExtrusionStyle extrusion, int level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders an area symbol with the given bitmap.
|
* Renders an area symbol with the given bitmap.
|
||||||
@ -92,7 +91,7 @@ public interface IRenderTheme {
|
|||||||
* @param symbol
|
* @param symbol
|
||||||
* the symbol to be rendered.
|
* the symbol to be rendered.
|
||||||
*/
|
*/
|
||||||
void renderAreaSymbol(Symbol symbol);
|
void renderAreaSymbol(SymbolStyle symbol);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders an area caption with the given text.
|
* Renders an area caption with the given text.
|
||||||
@ -100,7 +99,7 @@ public interface IRenderTheme {
|
|||||||
* @param text
|
* @param text
|
||||||
* the text to be rendered.
|
* the text to be rendered.
|
||||||
*/
|
*/
|
||||||
void renderAreaText(Text text);
|
void renderAreaText(TextStyle text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a point of interest circle with the given parameters.
|
* Renders a point of interest circle with the given parameters.
|
||||||
@ -110,7 +109,7 @@ public interface IRenderTheme {
|
|||||||
* @param level
|
* @param level
|
||||||
* the drawing level on which the circle should be rendered.
|
* 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.
|
* Renders a point of interest symbol with the given bitmap.
|
||||||
@ -118,7 +117,7 @@ public interface IRenderTheme {
|
|||||||
* @param symbol
|
* @param symbol
|
||||||
* the symbol to be rendered.
|
* the symbol to be rendered.
|
||||||
*/
|
*/
|
||||||
void renderPointSymbol(Symbol symbol);
|
void renderPointSymbol(SymbolStyle symbol);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a point of interest caption with the given text.
|
* Renders a point of interest caption with the given text.
|
||||||
@ -126,7 +125,7 @@ public interface IRenderTheme {
|
|||||||
* @param text
|
* @param text
|
||||||
* the text to be rendered.
|
* the text to be rendered.
|
||||||
*/
|
*/
|
||||||
void renderPointText(Text text);
|
void renderPointText(TextStyle text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a way with the given parameters.
|
* Renders a way with the given parameters.
|
||||||
@ -134,22 +133,14 @@ public interface IRenderTheme {
|
|||||||
* @param line
|
* @param line
|
||||||
* @param level
|
* @param level
|
||||||
*/
|
*/
|
||||||
void renderWay(Line line, int level);
|
void renderWay(LineStyle 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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a way with the given text along the way path.
|
* Renders a way with the given text along the way path.
|
||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
*/
|
*/
|
||||||
void renderWayText(Text text);
|
void renderWayText(TextStyle text);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2014 Hannes Janetzek
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* 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.core.TagSet;
|
||||||
import org.oscim.theme.rule.Element;
|
import org.oscim.theme.rule.Element;
|
||||||
import org.oscim.theme.rule.Rule;
|
import org.oscim.theme.rule.Rule;
|
||||||
|
import org.oscim.theme.rule.Rule.RuleVisitor;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.utils.LRUCache;
|
import org.oscim.utils.LRUCache;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
|
||||||
* A RenderTheme defines how map elements are drawn.
|
|
||||||
*/
|
|
||||||
public class RenderTheme implements IRenderTheme {
|
public class RenderTheme implements IRenderTheme {
|
||||||
static final Logger log = LoggerFactory.getLogger(RenderTheme.class);
|
static final Logger log = LoggerFactory.getLogger(RenderTheme.class);
|
||||||
|
|
||||||
@ -41,8 +38,8 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
private final float mBaseTextSize;
|
private final float mBaseTextSize;
|
||||||
private final int mMapBackground;
|
private final int mMapBackground;
|
||||||
|
|
||||||
private int mLevels;
|
private final int mLevels;
|
||||||
private Rule[] mRules;
|
private final Rule[] mRules;
|
||||||
|
|
||||||
class RenderStyleCache {
|
class RenderStyleCache {
|
||||||
final int matchType;
|
final int matchType;
|
||||||
@ -75,9 +72,14 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
|
|
||||||
private final RenderStyleCache[] mStyleCache;
|
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;
|
mMapBackground = mapBackground;
|
||||||
mBaseTextSize = baseTextSize;
|
mBaseTextSize = baseTextSize;
|
||||||
|
mLevels = levels;
|
||||||
|
mRules = rules;
|
||||||
|
|
||||||
mStyleCache = new RenderStyleCache[3];
|
mStyleCache = new RenderStyleCache[3];
|
||||||
mStyleCache[0] = new RenderStyleCache(Element.NODE);
|
mStyleCache[0] = new RenderStyleCache(Element.NODE);
|
||||||
@ -91,10 +93,8 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
mStyleCache[i].cache.clear();
|
mStyleCache[i].cache.clear();
|
||||||
|
|
||||||
if (mRules != null) {
|
for (Rule rule : mRules)
|
||||||
for (int i = 0, n = mRules.length; i < n; i++)
|
rule.dispose();
|
||||||
mRules[i].onDestroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -107,13 +107,17 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
return mMapBackground;
|
return mMapBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AtomicInteger hitCount = new AtomicInteger(0);
|
||||||
|
//AtomicInteger missCount = new AtomicInteger(0);
|
||||||
|
//AtomicInteger sameCount = new AtomicInteger(0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RenderStyle[] matchElement(GeometryType geometryType, TagSet tags, int zoomLevel) {
|
public RenderStyle[] matchElement(GeometryType geometryType, TagSet tags, int zoomLevel) {
|
||||||
|
|
||||||
// list of renderinsctruction items in cache
|
/* list of items in cache */
|
||||||
RenderStyleItem ris = null;
|
RenderStyleItem ris = null;
|
||||||
|
|
||||||
// the item matching tags and zoomlevel
|
/* the item matching tags and zoomlevel */
|
||||||
RenderStyleItem ri = null;
|
RenderStyleItem ri = null;
|
||||||
|
|
||||||
int type = geometryType.nativeInt;
|
int type = geometryType.nativeInt;
|
||||||
@ -124,35 +128,42 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
|
|
||||||
RenderStyleCache cache = mStyleCache[type - 1];
|
RenderStyleCache cache = mStyleCache[type - 1];
|
||||||
|
|
||||||
// NOTE: maximum zoom level supported is 32
|
/* NOTE: maximum zoom level supported is 32 */
|
||||||
int zoomMask = 1 << zoomLevel;
|
int zoomMask = 1 << zoomLevel;
|
||||||
|
|
||||||
synchronized (cache) {
|
synchronized (cache) {
|
||||||
|
|
||||||
if ((cache.prevItem == null) || (cache.prevItem.zoom & zoomMask) == 0) {
|
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);
|
cache.cacheKey.set(tags, null);
|
||||||
} else {
|
} else {
|
||||||
// compare if tags match previous instructions
|
/* compare if tags match previous instructions */
|
||||||
if (cache.cacheKey.set(tags, cache.prevItem.key)) {
|
if (cache.cacheKey.set(tags, cache.prevItem.key)) {
|
||||||
//log.debug("same as previous " + Arrays.deepToString(tags));
|
|
||||||
ri = cache.prevItem;
|
ri = cache.prevItem;
|
||||||
|
//log.debug(hitCount + "/" + sameCount.incrementAndGet()
|
||||||
|
// + "/" + missCount + "same hit " + tags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ri == null) {
|
if (ri == null) {
|
||||||
// get instruction for current cacheKey
|
/* get instruction for current cacheKey */
|
||||||
ris = cache.getRenderInstructions();
|
ris = cache.getRenderInstructions();
|
||||||
|
|
||||||
for (ri = ris; ri != null; ri = ri.next)
|
for (ri = ris; ri != null; ri = ri.next) {
|
||||||
if ((ri.zoom & zoomMask) != 0)
|
if ((ri.zoom & zoomMask) != 0) {
|
||||||
// cache hit
|
/* cache hit */
|
||||||
|
|
||||||
|
//log.debug(hitCount.incrementAndGet()
|
||||||
|
// + "/" + sameCount + "/" + missCount
|
||||||
|
// + " cache hit " + tags);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ri == null) {
|
if (ri == null) {
|
||||||
// cache miss
|
/* cache miss */
|
||||||
//log.debug(missCnt++ + " / " + hitCnt + " Cache Miss");
|
//missCount.incrementAndGet();
|
||||||
|
|
||||||
List<RenderStyle> matches = cache.instructionList;
|
List<RenderStyle> matches = cache.instructionList;
|
||||||
matches.clear();
|
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) {
|
for (ri = ris; ri != null; ri = ri.next) {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
if (ri.list != null)
|
if (ri.list != null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// both matchinglists are empty
|
/* both matchinglists are empty */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,13 +210,13 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i == size)
|
if (i == size)
|
||||||
// both matching lists contain the same items
|
/* both matching lists contain the same items */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ri != null) {
|
if (ri != null) {
|
||||||
// we found a same matchting list on another zoomlevel add
|
/* we found a same matchting list on another zoomlevel add
|
||||||
// this zoom level to the existing RenderInstructionItem.
|
* this zoom level to the existing RenderInstructionItem. */
|
||||||
ri.zoom |= zoomMask;
|
ri.zoom |= zoomMask;
|
||||||
|
|
||||||
//log.debug(zoomLevel + " same instructions " + size + " "
|
//log.debug(zoomLevel + " same instructions " + size + " "
|
||||||
@ -222,7 +233,7 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
matches.toArray(ri.list);
|
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) {
|
if (ris != null) {
|
||||||
ri.next = ris.next;
|
ri.next = ris.next;
|
||||||
ri.key = ris.key;
|
ri.key = ris.key;
|
||||||
@ -233,34 +244,26 @@ public class RenderTheme implements IRenderTheme {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.prevItem = ri;
|
cache.prevItem = ri;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ri.list;
|
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
|
@Override
|
||||||
public void scaleTextSize(float scaleFactor) {
|
public void scaleTextSize(float scaleFactor) {
|
||||||
|
for (Rule rule : mRules)
|
||||||
for (int i = 0, n = mRules.length; i < n; i++)
|
rule.scaleTextSize(scaleFactor * mBaseTextSize);
|
||||||
mRules[i].scaleTextSize(scaleFactor * mBaseTextSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
for (int i = 0, n = mRules.length; i < n; i++)
|
for (Rule rule : mRules)
|
||||||
mRules[i].updateInstructions();
|
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;
|
InputStream inputStream = null;
|
||||||
try {
|
try {
|
||||||
inputStream = theme.getRenderThemeAsStream();
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
IRenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
|
IRenderTheme t = XmlThemeBuilder.read(inputStream);
|
||||||
|
|
||||||
if (t != null)
|
if (t != null)
|
||||||
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f);
|
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f);
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.theme;
|
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.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -36,14 +40,17 @@ import org.oscim.renderer.atlas.TextureRegion;
|
|||||||
import org.oscim.renderer.elements.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.oscim.theme.rule.Rule;
|
import org.oscim.theme.rule.Rule;
|
||||||
import org.oscim.theme.styles.Area;
|
import org.oscim.theme.rule.RuleBuilder;
|
||||||
import org.oscim.theme.styles.Circle;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.theme.styles.Extrusion;
|
import org.oscim.theme.styles.AreaStyle.AreaBuilder;
|
||||||
import org.oscim.theme.styles.Line;
|
import org.oscim.theme.styles.CircleStyle;
|
||||||
import org.oscim.theme.styles.LineSymbol;
|
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.RenderStyle;
|
||||||
import org.oscim.theme.styles.Symbol;
|
import org.oscim.theme.styles.SymbolStyle;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.TextStyle;
|
||||||
|
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
@ -51,8 +58,8 @@ import org.xml.sax.SAXException;
|
|||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
public class RenderThemeHandler extends DefaultHandler {
|
public class XmlThemeBuilder extends DefaultHandler {
|
||||||
static final Logger log = LoggerFactory.getLogger(RenderThemeHandler.class);
|
static final Logger log = LoggerFactory.getLogger(XmlThemeBuilder.class);
|
||||||
|
|
||||||
private static final int RENDER_THEME_VERSION = 1;
|
private static final int RENDER_THEME_VERSION = 1;
|
||||||
|
|
||||||
@ -60,7 +67,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS;
|
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 ELEMENT_NAME_MATCH = "m";
|
||||||
private static final String UNEXPECTED_ELEMENT = "unexpected element: ";
|
private static final String UNEXPECTED_ELEMENT = "unexpected element: ";
|
||||||
|
|
||||||
@ -82,10 +89,10 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if an I/O error occurs while reading from the input stream.
|
* 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 {
|
throws SAXException, IOException {
|
||||||
|
|
||||||
RenderThemeHandler renderThemeHandler = new RenderThemeHandler();
|
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder();
|
||||||
|
|
||||||
new XMLReaderAdapter().parse(renderThemeHandler, inputStream);
|
new XMLReaderAdapter().parse(renderThemeHandler, inputStream);
|
||||||
|
|
||||||
@ -118,36 +125,39 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
log.debug(sb.toString());
|
log.debug(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Rule> mRulesList = new ArrayList<Rule>();
|
private final ArrayList<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>();
|
||||||
private Rule mCurrentRule;
|
private final Stack<Element> mElementStack = new Stack<Element>();
|
||||||
|
private final Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
|
||||||
private Stack<Element> mElementStack = new Stack<Element>();
|
private final HashMap<String, RenderStyle> mStyles =
|
||||||
private Stack<Rule> mRuleStack = new Stack<Rule>();
|
|
||||||
private HashMap<String, RenderStyle> mStyles =
|
|
||||||
new HashMap<String, RenderStyle>(10);
|
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 TextureAtlas mTextureAtlas;
|
||||||
|
|
||||||
private int mLevel;
|
private int mLevels = 0;
|
||||||
|
private int mMapBackground = 0xffffffff;
|
||||||
|
private float mBaseTextSize = 1;
|
||||||
|
|
||||||
private RenderTheme mRenderTheme;
|
private RenderTheme mRenderTheme;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endDocument() {
|
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();
|
mRulesList.clear();
|
||||||
mStyles.clear();
|
mStyles.clear();
|
||||||
mRuleStack.clear();
|
mRuleStack.clear();
|
||||||
mElementStack.clear();
|
mElementStack.clear();
|
||||||
|
|
||||||
mStyles = null;
|
|
||||||
mRuleStack = null;
|
|
||||||
mRulesList = null;
|
|
||||||
mElementStack = null;
|
|
||||||
mTextureAtlas = null;
|
mTextureAtlas = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,13 +189,13 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
public void startElement(String uri, String localName, String qName,
|
public void startElement(String uri, String localName, String qName,
|
||||||
Attributes attributes) throws SAXException {
|
Attributes attributes) throws SAXException {
|
||||||
try {
|
try {
|
||||||
if ("rendertheme".equals(localName)) {
|
if (ELEMENT_NAME_RENDER_THEME.equals(localName)) {
|
||||||
checkState(localName, Element.RENDER_THEME);
|
checkState(localName, Element.RENDER_THEME);
|
||||||
mRenderTheme = createRenderTheme(localName, attributes);
|
createRenderTheme(localName, attributes);
|
||||||
|
|
||||||
} else if (ELEMENT_NAME_MATCH.equals(localName)) {
|
} else if (ELEMENT_NAME_MATCH.equals(localName)) {
|
||||||
checkState(localName, Element.RULE);
|
checkState(localName, Element.RULE);
|
||||||
Rule rule = Rule.create(localName, attributes, mRuleStack);
|
RuleBuilder rule = RuleBuilder.create(localName, attributes, mRuleStack);
|
||||||
if (!mRuleStack.empty()) {
|
if (!mRuleStack.empty()) {
|
||||||
mCurrentRule.addSubRule(rule);
|
mCurrentRule.addSubRule(rule);
|
||||||
}
|
}
|
||||||
@ -194,7 +204,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
} else if ("style-text".equals(localName)) {
|
} else if ("style-text".equals(localName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(localName, Element.STYLE);
|
||||||
Text text = createText(localName, attributes, false);
|
TextStyle text = createText(localName, attributes, false);
|
||||||
mStyles.put(TEXT_STYLE + text.style, text);
|
mStyles.put(TEXT_STYLE + text.style, text);
|
||||||
|
|
||||||
} else if ("style-area".equals(localName)) {
|
} else if ("style-area".equals(localName)) {
|
||||||
@ -207,7 +217,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
} else if ("outline-layer".equals(localName)) {
|
} else if ("outline-layer".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
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);
|
mStyles.put(OUTLINE_STYLE + line.style, line);
|
||||||
|
|
||||||
} else if ("area".equals(localName)) {
|
} else if ("area".equals(localName)) {
|
||||||
@ -216,40 +226,35 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
} else if ("caption".equals(localName)) {
|
} else if ("caption".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Text text = createText(localName, attributes, true);
|
TextStyle text = createText(localName, attributes, true);
|
||||||
mCurrentRule.addRenderingInstruction(text);
|
mCurrentRule.addStyle(text);
|
||||||
} else if ("circle".equals(localName)) {
|
} else if ("circle".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Circle circle = createCircle(localName, attributes, mLevel++);
|
CircleStyle circle = createCircle(localName, attributes, mLevels++);
|
||||||
mCurrentRule.addRenderingInstruction(circle);
|
mCurrentRule.addStyle(circle);
|
||||||
|
|
||||||
} else if ("line".equals(localName)) {
|
} else if ("line".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
handleLineElement(localName, attributes, false);
|
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)) {
|
} else if ("text".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
String style = attributes.getValue("use");
|
String style = attributes.getValue("use");
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
Text text = createText(localName, attributes, false);
|
TextStyle text = createText(localName, attributes, false);
|
||||||
mCurrentRule.addRenderingInstruction(text);
|
mCurrentRule.addStyle(text);
|
||||||
} else {
|
} else {
|
||||||
Text pt = (Text) mStyles.get(TEXT_STYLE + style);
|
TextStyle pt = (TextStyle) mStyles.get(TEXT_STYLE + style);
|
||||||
if (pt != null)
|
if (pt != null)
|
||||||
mCurrentRule.addRenderingInstruction(pt);
|
mCurrentRule.addStyle(pt);
|
||||||
else
|
else
|
||||||
log.debug("BUG not a path text style: " + style);
|
log.debug("BUG not a path text style: " + style);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ("symbol".equals(localName)) {
|
} else if ("symbol".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Symbol symbol = createSymbol(localName, attributes);
|
SymbolStyle symbol = createSymbol(localName, attributes);
|
||||||
mCurrentRule.addRenderingInstruction(symbol);
|
mCurrentRule.addStyle(symbol);
|
||||||
|
|
||||||
} else if ("outline".equals(localName)) {
|
} else if ("outline".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
@ -257,8 +262,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
|
|
||||||
} else if ("extrusion".equals(localName)) {
|
} else if ("extrusion".equals(localName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(localName, Element.RENDERING_INSTRUCTION);
|
||||||
Extrusion extrusion = createExtrusion(localName, attributes, mLevel++);
|
ExtrusionStyle extrusion = createExtrusion(localName, attributes, mLevels++);
|
||||||
mCurrentRule.addRenderingInstruction(extrusion);
|
mCurrentRule.addStyle(extrusion);
|
||||||
|
|
||||||
} else if ("atlas".equals(localName)) {
|
} else if ("atlas".equals(localName)) {
|
||||||
checkState(localName, Element.ATLAS);
|
checkState(localName, Element.ATLAS);
|
||||||
@ -295,22 +300,22 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
throws SAXException {
|
throws SAXException {
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = attributes.getValue("use");
|
||||||
Line style = null;
|
LineStyle style = null;
|
||||||
|
|
||||||
if (use != null) {
|
if (use != null) {
|
||||||
style = (Line) mStyles.get(LINE_STYLE + use);
|
style = (LineStyle) mStyles.get(LINE_STYLE + use);
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
log.debug("missing line style 'use': " + use);
|
log.debug("missing line style 'use': " + use);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Line line = createLine(style, localName, attributes, mLevel++, false);
|
LineStyle line = createLine(style, localName, attributes, mLevels++, false);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(LINE_STYLE + line.style, line);
|
mStyles.put(LINE_STYLE + line.style, line);
|
||||||
} else {
|
} else {
|
||||||
mCurrentRule.addRenderingInstruction(line);
|
mCurrentRule.addStyle(line);
|
||||||
// Note 'outline' will not be inherited, it's just a
|
// Note 'outline' will not be inherited, it's just a
|
||||||
// shorcut to add the outline RenderInstruction.
|
// shorcut to add the outline RenderInstruction.
|
||||||
addOutline(attributes.getValue("outline"));
|
addOutline(attributes.getValue("outline"));
|
||||||
@ -320,53 +325,24 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* @param line
|
* @param line
|
||||||
* optional: line style defaults
|
* optional: line style defaults
|
||||||
* @param elementName
|
|
||||||
* the name of the XML element.
|
|
||||||
* @param attributes
|
|
||||||
* the attributes of the XML element.
|
|
||||||
* @param level
|
* @param level
|
||||||
* the drawing level of this instruction.
|
* the drawing level of this instruction.
|
||||||
* @param isOutline
|
* @param isOutline
|
||||||
* is outline layer
|
* is outline layer
|
||||||
* @return a new Line with the given rendering attributes.
|
* @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) {
|
int level, boolean isOutline) {
|
||||||
|
LineBuilder b = mLineBuilder.set(line);
|
||||||
// Style name
|
b.isOutline(isOutline);
|
||||||
String style = null;
|
b.level(level);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0; i < attributes.getLength(); ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = attributes.getLocalName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = attributes.getValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
style = value;
|
b.style = value;
|
||||||
|
|
||||||
else if ("src".equals(name))
|
else if ("src".equals(name))
|
||||||
;// src = value;
|
;// src = value;
|
||||||
@ -378,34 +354,43 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
;// ignore
|
;// ignore
|
||||||
|
|
||||||
else if ("stroke".equals(name))
|
else if ("stroke".equals(name))
|
||||||
color = Color.parseColor(value);
|
b.color(value);
|
||||||
|
|
||||||
else if ("width".equals(name) || "stroke-width".equals(name))
|
|
||||||
width = Float.parseFloat(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))
|
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))
|
else if ("fix".equals(name))
|
||||||
fixed = Boolean.parseBoolean(value);
|
b.fixed = parseBoolean(value);
|
||||||
|
|
||||||
else if ("stipple".equals(name))
|
else if ("stipple".equals(name))
|
||||||
stipple = Integer.parseInt(value);
|
b.stipple = parseInt(value);
|
||||||
|
|
||||||
else if ("stipple-stroke".equals(name))
|
else if ("stipple-stroke".equals(name))
|
||||||
stippleColor = Color.parseColor(value);
|
b.stippleColor(value);
|
||||||
|
|
||||||
else if ("stipple-width".equals(name))
|
else if ("stipple-width".equals(name))
|
||||||
stippleWidth = Float.parseFloat(value);
|
b.stippleWidth = parseFloat(value);
|
||||||
|
|
||||||
else if ("fade".equals(name))
|
else if ("fade".equals(name))
|
||||||
fade = Integer.parseInt(value);
|
b.fadeScale = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("min".equals(name))
|
else if ("min".equals(name))
|
||||||
; //min = Float.parseFloat(value);
|
; //min = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("blur".equals(name))
|
else if ("blur".equals(name))
|
||||||
blur = Float.parseFloat(value);
|
b.blur = parseFloat(value);
|
||||||
|
|
||||||
else if ("style".equals(name))
|
else if ("style".equals(name))
|
||||||
; // ignore
|
; // ignore
|
||||||
@ -416,92 +401,49 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
return b.build();
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAreaElement(String localName, Attributes attributes, boolean isStyle)
|
private void handleAreaElement(String localName, Attributes attributes, boolean isStyle)
|
||||||
throws SAXException {
|
throws SAXException {
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = attributes.getValue("use");
|
||||||
Area style = null;
|
AreaStyle style = null;
|
||||||
|
|
||||||
if (use != null) {
|
if (use != null) {
|
||||||
style = (Area) mStyles.get(AREA_STYLE + use);
|
style = (AreaStyle) mStyles.get(AREA_STYLE + use);
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
log.debug("missing area style 'use': " + use);
|
log.debug("missing area style 'use': " + use);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Area area = createArea(style, localName, attributes, mLevel);
|
AreaStyle area = createArea(style, localName, attributes, mLevels);
|
||||||
mLevel += 2;
|
mLevels += 2;
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(AREA_STYLE + area.style, area);
|
mStyles.put(AREA_STYLE + area.style, area);
|
||||||
} else {
|
} 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.
|
* @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;
|
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) {
|
for (int i = 0; i < attributes.getLength(); ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = attributes.getLocalName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = attributes.getValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
style = value;
|
b.style = value;
|
||||||
|
|
||||||
else if ("use".equals(name))
|
else if ("use".equals(name))
|
||||||
;// ignore
|
;// ignore
|
||||||
@ -510,47 +452,46 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
src = value;
|
src = value;
|
||||||
|
|
||||||
else if ("fill".equals(name))
|
else if ("fill".equals(name))
|
||||||
fill = Color.parseColor(value);
|
b.color(value);
|
||||||
|
|
||||||
else if ("stroke".equals(name))
|
else if ("stroke".equals(name))
|
||||||
stroke = Color.parseColor(value);
|
b.outlineColor(value);
|
||||||
|
|
||||||
else if ("stroke-width".equals(name))
|
else if ("stroke-width".equals(name)) {
|
||||||
strokeWidth = Float.parseFloat(value);
|
float strokeWidth = Float.parseFloat(value);
|
||||||
|
validateNonNegative("stroke-width", strokeWidth);
|
||||||
|
b.outlineWidth = strokeWidth;
|
||||||
|
|
||||||
else if ("fade".equals(name))
|
} else if ("fade".equals(name))
|
||||||
fade = Integer.parseInt(value);
|
b.fadeScale = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("blend".equals(name))
|
else if ("blend".equals(name))
|
||||||
blend = Integer.parseInt(value);
|
b.blendScale = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("blend-fill".equals(name))
|
else if ("blend-fill".equals(name))
|
||||||
blendFill = Color.parseColor(value);
|
b.blendColor(value);
|
||||||
|
|
||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateLine(strokeWidth);
|
|
||||||
|
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
try {
|
try {
|
||||||
Bitmap b = CanvasAdapter.g.loadBitmapAsset(src);
|
Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(src);
|
||||||
if (b != null)
|
if (bitmap != null)
|
||||||
texture = new TextureItem(b, true);
|
b.texture = new TextureItem(bitmap, true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug(e.getMessage());
|
log.debug(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new Area(style, fill, stroke, strokeWidth, fade, level, blend,
|
return b.build();
|
||||||
blendFill, texture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOutline(String style) {
|
private void addOutline(String style) {
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
Line line = (Line) mStyles.get(OUTLINE_STYLE + style);
|
LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);
|
||||||
if (line != null && line.outline)
|
if (line != null && line.outline)
|
||||||
mCurrentRule.addRenderingInstruction(line);
|
mCurrentRule.addStyle(line);
|
||||||
else
|
else
|
||||||
log.debug("BUG not an outline style: " + style);
|
log.debug("BUG not an outline style: " + style);
|
||||||
}
|
}
|
||||||
@ -566,11 +507,10 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
if ("img".equals(name)) {
|
if ("img".equals(name)) {
|
||||||
img = value;
|
img = value;
|
||||||
} else {
|
} else {
|
||||||
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
|
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (img == null)
|
validateExists("img", img, elementName);
|
||||||
throw new ThemeException("missing attribute 'img' for element: " + elementName);
|
|
||||||
|
|
||||||
Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(IMG_PATH + img);
|
Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(IMG_PATH + img);
|
||||||
mTextureAtlas = new TextureAtlas(bitmap);
|
mTextureAtlas = new TextureAtlas(bitmap);
|
||||||
@ -595,12 +535,11 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
Integer.parseInt(pos[3]));
|
Integer.parseInt(pos[3]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
|
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (regionName == null || r == null)
|
validateExists("id", regionName, elementName);
|
||||||
throw new ThemeException("missing attribute 'id' or 'rect' for element: "
|
validateExists("pos", r, elementName);
|
||||||
+ elementName);
|
|
||||||
|
|
||||||
mTextureAtlas.addTextureRegion(regionName.intern(), r);
|
mTextureAtlas.addTextureRegion(regionName.intern(), r);
|
||||||
}
|
}
|
||||||
@ -652,7 +591,7 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
mElementStack.push(element);
|
mElementStack.push(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RenderTheme createRenderTheme(String elementName, Attributes attributes) {
|
private void createRenderTheme(String elementName, Attributes attributes) {
|
||||||
Integer version = null;
|
Integer version = null;
|
||||||
int mapBackground = Color.WHITE;
|
int mapBackground = Color.WHITE;
|
||||||
float baseStrokeWidth = 1;
|
float baseStrokeWidth = 1;
|
||||||
@ -678,115 +617,91 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
baseTextSize = Float.parseFloat(value);
|
baseTextSize = Float.parseFloat(value);
|
||||||
|
|
||||||
else
|
else
|
||||||
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
|
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version == null)
|
validateExists("version", version, elementName);
|
||||||
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);
|
|
||||||
|
|
||||||
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
|
* @param caption
|
||||||
* ...
|
* ...
|
||||||
* @return a new Text with the given rendering attributes.
|
* @return a new Text with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private Text createText(String elementName, Attributes attributes, boolean caption) {
|
private TextStyle createText(String elementName, Attributes attributes, boolean caption) {
|
||||||
String textKey = null;
|
TextBuilder b = mTextBuilder.reset();
|
||||||
FontFamily fontFamily = FontFamily.DEFAULT;
|
|
||||||
FontStyle fontStyle = FontStyle.NORMAL;
|
b.caption = caption;
|
||||||
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;
|
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0; i < attributes.getLength(); ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = attributes.getLocalName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = attributes.getValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
style = value;
|
b.style = value;
|
||||||
|
|
||||||
else if ("k".equals(name))
|
else if ("k".equals(name))
|
||||||
textKey = value.intern();
|
b.textKey = value.intern();
|
||||||
|
|
||||||
else if ("font-family".equals(name))
|
else if ("font-family".equals(name))
|
||||||
fontFamily = FontFamily.valueOf(value.toUpperCase());
|
b.fontFamily = FontFamily.valueOf(value.toUpperCase());
|
||||||
|
|
||||||
else if ("style".equals(name))
|
else if ("style".equals(name))
|
||||||
fontStyle = FontStyle.valueOf(value.toUpperCase());
|
b.fontStyle = FontStyle.valueOf(value.toUpperCase());
|
||||||
|
|
||||||
else if ("size".equals(name))
|
else if ("size".equals(name))
|
||||||
fontSize = Float.parseFloat(value);
|
b.fontSize = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("fill".equals(name))
|
else if ("fill".equals(name))
|
||||||
fill = Color.parseColor(value);
|
b.color = Color.parseColor(value);
|
||||||
|
|
||||||
else if ("stroke".equals(name))
|
else if ("stroke".equals(name))
|
||||||
stroke = Color.parseColor(value);
|
b.stroke = Color.parseColor(value);
|
||||||
|
|
||||||
else if ("stroke-width".equals(name))
|
else if ("stroke-width".equals(name))
|
||||||
strokeWidth = Float.parseFloat(value);
|
b.strokeWidth = Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("caption".equals(name))
|
else if ("caption".equals(name))
|
||||||
caption = Boolean.parseBoolean(value);
|
b.caption = Boolean.parseBoolean(value);
|
||||||
|
|
||||||
else if ("priority".equals(name))
|
else if ("priority".equals(name))
|
||||||
priority = Integer.parseInt(value);
|
b.priority = Integer.parseInt(value);
|
||||||
|
|
||||||
else if ("dy".equals(name))
|
else if ("dy".equals(name))
|
||||||
dy = Float.parseFloat(value);
|
// NB: minus..
|
||||||
|
b.dy = -Float.parseFloat(value);
|
||||||
|
|
||||||
else if ("symbol".equals(name))
|
else if ("symbol".equals(name))
|
||||||
symbol = getAtlasRegion(value);
|
b.texture = getAtlasRegion(value);
|
||||||
|
|
||||||
else
|
else
|
||||||
logUnknownAttribute(elementName, name, value, i);
|
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,
|
return b.buildInternal();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param elementName
|
|
||||||
* the name of the XML element.
|
|
||||||
* @param attributes
|
|
||||||
* the attributes of the XML element.
|
|
||||||
* @param level
|
* @param level
|
||||||
* the drawing level of this instruction.
|
* the drawing level of this instruction.
|
||||||
* @return a new Circle with the given rendering attributes.
|
* @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;
|
Float radius = null;
|
||||||
boolean scaleRadius = false;
|
boolean scaleRadius = false;
|
||||||
int fill = Color.TRANSPARENT;
|
int fill = Color.TRANSPARENT;
|
||||||
@ -816,60 +731,17 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
logUnknownAttribute(elementName, name, value, i);
|
logUnknownAttribute(elementName, name, value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateCircle(elementName, radius, strokeWidth);
|
validateExists("r", radius, elementName);
|
||||||
return new Circle(radius, scaleRadius, fill, stroke, strokeWidth, level);
|
validateNonNegative("radius", radius);
|
||||||
}
|
validateNonNegative("stroke-width", strokeWidth);
|
||||||
|
|
||||||
private static void validateCircle(String elementName, Float radius, float strokeWidth) {
|
return new CircleStyle(radius, scaleRadius, fill, stroke, strokeWidth, level);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
* @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;
|
String src = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0; i < attributes.getLength(); ++i) {
|
||||||
@ -882,17 +754,12 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
logUnknownAttribute(elementName, name, value, i);
|
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) {
|
private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) {
|
||||||
if (src == null)
|
|
||||||
throw new ThemeException("missing attribute src for element: " + elementName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Extrusion createExtrusion(String elementName, Attributes attributes, int level) {
|
|
||||||
int colorSide = 0;
|
int colorSide = 0;
|
||||||
int colorTop = 0;
|
int colorTop = 0;
|
||||||
int colorLine = 0;
|
int colorLine = 0;
|
||||||
@ -918,6 +785,18 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
logUnknownAttribute(elementName, name, value, i);
|
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 2013 Hannes Janetzek
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
*
|
||||||
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
*
|
*
|
||||||
|
@ -18,12 +18,14 @@
|
|||||||
package org.oscim.theme.rule;
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
class NegativeRule extends Rule {
|
class NegativeRule extends Rule {
|
||||||
final AttributeMatcher mAttributeMatcher;
|
final AttributeMatcher mAttributeMatcher;
|
||||||
|
|
||||||
NegativeRule(int element, int zoom, boolean matchFirst, AttributeMatcher attributeMatcher) {
|
NegativeRule(int element, int zoom, int selector, AttributeMatcher attributeMatcher,
|
||||||
super(element, zoom, matchFirst);
|
Rule[] subRules, RenderStyle[] styles) {
|
||||||
|
super(element, zoom, selector, subRules, styles);
|
||||||
|
|
||||||
mAttributeMatcher = attributeMatcher;
|
mAttributeMatcher = attributeMatcher;
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,15 @@
|
|||||||
package org.oscim.theme.rule;
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
class PositiveRule extends Rule {
|
class PositiveRule extends Rule {
|
||||||
final AttributeMatcher mKeyMatcher;
|
final AttributeMatcher mKeyMatcher;
|
||||||
final AttributeMatcher mValueMatcher;
|
final AttributeMatcher mValueMatcher;
|
||||||
|
|
||||||
PositiveRule(int element, int zoom, boolean matchFirst, AttributeMatcher keyMatcher,
|
PositiveRule(int element, int zoom, int selector, AttributeMatcher keyMatcher,
|
||||||
AttributeMatcher valueMatcher) {
|
AttributeMatcher valueMatcher, Rule[] subRules, RenderStyle[] styles) {
|
||||||
super(element, zoom, matchFirst);
|
super(element, zoom, selector, subRules, styles);
|
||||||
|
|
||||||
if (keyMatcher instanceof AnyMatcher)
|
if (keyMatcher instanceof AnyMatcher)
|
||||||
mKeyMatcher = null;
|
mKeyMatcher = null;
|
||||||
|
@ -1,5 +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).
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
@ -17,305 +16,138 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.theme.rule;
|
package org.oscim.theme.rule;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
|
||||||
import org.oscim.theme.RenderThemeHandler;
|
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.xml.sax.Attributes;
|
|
||||||
|
|
||||||
public abstract class Rule {
|
public abstract class Rule {
|
||||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_KEY =
|
public final static RenderStyle[] EMPTY_STYLE = new RenderStyle[0];
|
||||||
new HashMap<List<String>, AttributeMatcher>();
|
public final static Rule[] EMPTY_RULES = new Rule[0];
|
||||||
private static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_VALUE =
|
|
||||||
new HashMap<List<String>, AttributeMatcher>();
|
|
||||||
|
|
||||||
private static final String STRING_NEGATION = "~";
|
private final Rule[] subRules;
|
||||||
private static final String STRING_EXCLUSIVE = "-";
|
public final RenderStyle[] styles;
|
||||||
private static final String STRING_WILDCARD = "*";
|
|
||||||
|
|
||||||
private static Rule createRule(Stack<Rule> ruleStack, int element, String keys,
|
private final int zoom;
|
||||||
String values, byte zoomMin, byte zoomMax, boolean matchFirst) {
|
private final int element;
|
||||||
|
private final boolean selectFirstMatch;
|
||||||
|
private final boolean selectWhenMatched;
|
||||||
|
|
||||||
// zoom-level bitmask
|
Rule(int element, int zoom, int selector, Rule[] subRules, RenderStyle[] styles) {
|
||||||
int zoom = 0;
|
this.element = element;
|
||||||
for (int z = zoomMin; z <= zoomMax && z < 32; z++)
|
this.zoom = zoom;
|
||||||
zoom |= (1 << z);
|
|
||||||
|
|
||||||
List<String> keyList = null, valueList = null;
|
this.subRules = (subRules == null) ? EMPTY_RULES : subRules;
|
||||||
boolean negativeRule = false;
|
this.styles = (styles == null) ? EMPTY_STYLE : styles;
|
||||||
boolean exclusionRule = false;
|
|
||||||
|
|
||||||
AttributeMatcher keyMatcher, valueMatcher = null;
|
selectFirstMatch = (selector & Selector.FIRST) != 0;
|
||||||
|
selectWhenMatched = (selector & Selector.WHEN_MATCHED) != 0;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract boolean matchesTags(Tag[] tags);
|
abstract boolean matchesTags(Tag[] tags);
|
||||||
|
|
||||||
public boolean matchElement(int type, Tag[] tags, int zoomLevel,
|
public boolean matchElement(int type, Tag[] tags, int zoomLevel, List<RenderStyle> result) {
|
||||||
List<RenderStyle> matchingList) {
|
|
||||||
|
|
||||||
if (((mElement & type) != 0) && ((mZoom & zoomLevel) != 0) && (matchesTags(tags))) {
|
|
||||||
|
|
||||||
|
if (((element & type) != 0) && ((zoom & zoomLevel) != 0) && (matchesTags(tags))) {
|
||||||
boolean matched = false;
|
boolean matched = false;
|
||||||
|
|
||||||
// check subrules
|
if (subRules != EMPTY_RULES) {
|
||||||
for (Rule subRule : mSubRules) {
|
if (selectFirstMatch) {
|
||||||
if (subRule.matchElement(type, tags, zoomLevel, matchingList) && mMatchFirst) {
|
/* only add first matching rule and when-matched rules iff a
|
||||||
matched = true;
|
* previous rule matched */
|
||||||
break;
|
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) {
|
if (styles == EMPTY_STYLE)
|
||||||
// add instructions for this rule
|
/* matched if styles where added */
|
||||||
for (RenderStyle ri : mRenderInstructions)
|
return matched;
|
||||||
matchingList.add(ri);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this rule did match
|
/* add instructions for this rule */
|
||||||
|
for (RenderStyle ri : styles)
|
||||||
|
result.add(ri);
|
||||||
|
|
||||||
|
/* this rule did not match */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this rule did not match
|
/* this rule did not match */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onComplete() {
|
public void dispose() {
|
||||||
MATCHERS_CACHE_KEY.clear();
|
for (RenderStyle ri : styles)
|
||||||
MATCHERS_CACHE_VALUE.clear();
|
ri.dispose();
|
||||||
|
|
||||||
mRenderInstructions = new RenderStyle[builder.renderInstructions.size()];
|
for (Rule subRule : subRules)
|
||||||
builder.renderInstructions.toArray(mRenderInstructions);
|
subRule.dispose();
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scaleTextSize(float scaleFactor) {
|
public void scaleTextSize(float scaleFactor) {
|
||||||
for (RenderStyle ri : mRenderInstructions)
|
for (RenderStyle ri : styles)
|
||||||
ri.scaleTextSize(scaleFactor);
|
ri.scaleTextSize(scaleFactor);
|
||||||
for (Rule subRule : mSubRules)
|
|
||||||
|
for (Rule subRule : subRules)
|
||||||
subRule.scaleTextSize(scaleFactor);
|
subRule.scaleTextSize(scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateInstructions() {
|
public void updateStyles() {
|
||||||
for (RenderStyle ri : mRenderInstructions)
|
for (RenderStyle ri : styles)
|
||||||
ri.update();
|
ri.update();
|
||||||
for (Rule subRule : mSubRules)
|
|
||||||
subRule.updateInstructions();
|
for (Rule subRule : subRules)
|
||||||
|
subRule.updateStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RuleVisitor {
|
public static class RuleVisitor {
|
||||||
boolean apply(Rule r) {
|
public void apply(Rule r) {
|
||||||
|
for (Rule subRule : r.subRules)
|
||||||
for (Rule subRule : r.mSubRules)
|
|
||||||
this.apply(subRule);
|
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 {
|
public static class UpdateVisitor extends RuleVisitor {
|
||||||
@Override
|
@Override
|
||||||
boolean apply(Rule r) {
|
public void apply(Rule r) {
|
||||||
for (RenderStyle ri : r.mRenderInstructions)
|
for (RenderStyle ri : r.styles)
|
||||||
ri.update();
|
ri.update();
|
||||||
|
super.apply(r);
|
||||||
return super.apply(r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean apply(RuleVisitor v) {
|
public void apply(RuleVisitor v) {
|
||||||
|
v.apply(this);
|
||||||
return 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 {
|
final class RuleOptimizer {
|
||||||
|
|
||||||
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
|
private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
|
||||||
Stack<Rule> ruleStack) {
|
Stack<RuleBuilder> ruleStack) {
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
if (ruleStack.get(i) instanceof PositiveRule) {
|
if (ruleStack.get(i).positiveRule) {
|
||||||
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
RuleBuilder positiveRule = ruleStack.get(i);
|
||||||
if (positiveRule.mKeyMatcher != null
|
|
||||||
&& positiveRule.mKeyMatcher.isCoveredBy(attributeMatcher)) {
|
if (positiveRule.keyMatcher != null
|
||||||
|
&& positiveRule.keyMatcher.isCoveredBy(attributeMatcher)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,13 +38,13 @@ final class RuleOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static AttributeMatcher optimizeValueMatcher(
|
private static AttributeMatcher optimizeValueMatcher(
|
||||||
AttributeMatcher attributeMatcher, Stack<Rule> ruleStack) {
|
AttributeMatcher attributeMatcher, Stack<RuleBuilder> ruleStack) {
|
||||||
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
for (int i = 0, n = ruleStack.size(); i < n; ++i) {
|
||||||
if (ruleStack.get(i) instanceof PositiveRule) {
|
if (ruleStack.get(i).positiveRule) {
|
||||||
PositiveRule positiveRule = (PositiveRule) ruleStack.get(i);
|
RuleBuilder positiveRule = ruleStack.get(i);
|
||||||
|
|
||||||
if (positiveRule.mValueMatcher != null
|
if (positiveRule.valueMatcher != null
|
||||||
&& positiveRule.mValueMatcher.isCoveredBy(attributeMatcher)) {
|
&& positiveRule.valueMatcher.isCoveredBy(attributeMatcher)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +54,7 @@ final class RuleOptimizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
|
static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
|
||||||
Stack<Rule> ruleStack) {
|
Stack<RuleBuilder> ruleStack) {
|
||||||
if (attributeMatcher instanceof AnyMatcher)
|
if (attributeMatcher instanceof AnyMatcher)
|
||||||
return attributeMatcher;// return null;
|
return attributeMatcher;// return null;
|
||||||
else if (attributeMatcher instanceof NegativeMatcher) {
|
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;
|
import org.oscim.core.Tag;
|
||||||
|
|
||||||
class SingleKeyMatcher implements AttributeMatcher {
|
public class SingleKeyMatcher implements AttributeMatcher {
|
||||||
private final String mKey;
|
private final String mKey;
|
||||||
|
|
||||||
SingleKeyMatcher(String key) {
|
public SingleKeyMatcher(String key) {
|
||||||
mKey = key.intern();
|
mKey = key.intern();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@ package org.oscim.theme.rule;
|
|||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
|
||||||
class SingleValueMatcher implements AttributeMatcher {
|
public class SingleValueMatcher implements AttributeMatcher {
|
||||||
private final String mValue;
|
private final String mValue;
|
||||||
|
|
||||||
SingleValueMatcher(String value) {
|
public SingleValueMatcher(String value) {
|
||||||
mValue = value.intern();
|
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.
|
* Represents a round area on the map.
|
||||||
*/
|
*/
|
||||||
public final class Circle extends RenderStyle {
|
public final class CircleStyle extends RenderStyle {
|
||||||
|
|
||||||
public final int level;
|
public final int level;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public final class Circle extends RenderStyle {
|
|||||||
public final boolean scaleRadius;
|
public final boolean scaleRadius;
|
||||||
public final float strokeWidth;
|
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) {
|
float strokeWidth, int level) {
|
||||||
super();
|
super();
|
||||||
|
|
@ -19,9 +19,9 @@ package org.oscim.theme.styles;
|
|||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.theme.IRenderTheme.Callback;
|
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];
|
this.colors = new float[16];
|
||||||
fillColors(colorSides, colorTop, colorLine, colors);
|
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.
|
* 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.
|
* Represents an icon on the map.
|
||||||
*/
|
*/
|
||||||
public final class Symbol extends RenderStyle {
|
public final class SymbolStyle extends RenderStyle {
|
||||||
|
|
||||||
public final TextureRegion texture;
|
public final TextureRegion texture;
|
||||||
|
|
||||||
public Symbol(TextureRegion symbol) {
|
public SymbolStyle(TextureRegion symbol) {
|
||||||
this.texture = symbol;
|
this.texture = symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void dispose() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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