make render-styles overrideable

This commit is contained in:
Hannes Janetzek 2014-02-16 06:48:36 +01:00
parent 8428f438db
commit e947248ea4
15 changed files with 160 additions and 95 deletions

View File

@ -244,48 +244,43 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
return;
}
LineLayer lineLayer = mTile.layers.getLineLayer(numLayer);
LineLayer ll = mTile.layers.getLineLayer(numLayer);
if (lineLayer == null)
if (ll == null)
return;
if (lineLayer.line == null) {
lineLayer.line = line;
float w = line.width;
if (!line.fixed)
w *= mLineScale;
lineLayer.width = w;
if (ll.line == null) {
ll.line = line;
ll.scale = line.fixed ? 1 : mLineScale;
}
if (line.outline) {
lineLayer.addOutline(mCurLineLayer);
ll.addOutline(mCurLineLayer);
return;
}
lineLayer.addLine(mElement);
ll.addLine(mElement);
// keep reference for outline layer
mCurLineLayer = lineLayer;
mCurLineLayer = ll;
} else {
LineTexLayer lineLayer = mTile.layers.getLineTexLayer(numLayer);
LineTexLayer ll = mTile.layers.getLineTexLayer(numLayer);
if (lineLayer == null)
if (ll == null)
return;
if (lineLayer.line == null) {
lineLayer.line = line;
if (ll.line == null) {
ll.line = line;
float w = line.width;
if (!line.fixed)
w *= mLineScale;
lineLayer.width = w;
ll.width = w;
}
lineLayer.addLine(mElement);
ll.addLine(mElement);
}
}
@ -391,13 +386,21 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
if (l == null) {
double lat = MercatorProjection.toLatitude(mTile.y);
float groundScale = (float) (Math.cos(lat * (Math.PI / 180))
* MercatorProjection.EARTH_CIRCUMFERENCE
/ ((long) Tile.SIZE << mTile.zoomLevel));
// float groundScale = (float) (Math.cos(lat * (Math.PI / 180))
// * MercatorProjection.EARTH_CIRCUMFERENCE
// / ((long) Tile.SIZE << mTile.zoomLevel));
float groundScale = (float) MercatorProjection
.groundResolution(lat, 1 << mTile.zoomLevel);
l = new ExtrusionLayer(0, groundScale, extrusion.colors);
mTile.layers.setExtrusionLayers(l);
}
/* 12m default */
if (height == 0)
height = 12 * 100;
l.add(mElement, height, minHeight);
}

View File

@ -299,7 +299,7 @@ public class PathLayer extends Layer {
LineLayer ll = layers.getLineLayer(0);
ll.line = mLineStyle;
ll.width = ll.line.width;
ll.scale = ll.line.width;
mMap.getMapPosition(task.pos);

View File

@ -61,7 +61,7 @@ public class TestTileLayer extends TileLayer {
LineLayer ll = tile.layers.getLineLayer(0);
ll.line = mLineStyle;
ll.width = 2;
ll.scale = 2;
int m = 20;
int s = Tile.SIZE - m * 2;

View File

@ -27,7 +27,6 @@ import org.oscim.core.MercatorProjection;
import org.oscim.core.PointF;
import org.oscim.core.Tag;
import org.oscim.core.TagSet;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
@ -247,6 +246,8 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
public void renderWay(Line line, int level) {
int numLayer = mCurLayer + level;
// line = line.getCurrent();
if (line.stipple == 0) {
if (line.outline && mCurLineLayer == null) {
log.debug("missing line for outline! " + mElement.tags
@ -254,42 +255,37 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
return;
}
LineLayer l = mTile.layers.getLineLayer(numLayer);
LineLayer ll = mTile.layers.getLineLayer(numLayer);
if (l.line == null) {
l.line = line;
float w = line.width;
if (!line.fixed)
w *= mLineScale;
l.width = w;
if (ll.line == null) {
ll.line = line;
ll.scale = line.fixed ? 1 : mLineScale;
}
if (line.outline) {
l.addOutline(mCurLineLayer);
ll.addOutline(mCurLineLayer);
return;
}
l.addLine(mElement);
ll.addLine(mElement);
// NB: keep reference for outline layer(s)
mCurLineLayer = l;
mCurLineLayer = ll;
} else {
LineTexLayer l = mTile.layers.getLineTexLayer(numLayer);
LineTexLayer ll = mTile.layers.getLineTexLayer(numLayer);
if (l.line == null) {
l.line = line;
if (ll.line == null) {
ll.line = line;
float w = line.width;
if (!line.fixed)
w *= mLineScale;
l.width = w;
ll.width = w;
}
l.addLine(mElement);
ll.addLine(mElement);
}
}
@ -406,9 +402,8 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
if (l == null) {
double lat = MercatorProjection.toLatitude(mTile.y);
float groundScale = (float) (Math.cos(lat * (Math.PI / 180))
* MercatorProjection.EARTH_CIRCUMFERENCE
/ ((long) Tile.SIZE << mTile.zoomLevel));
float groundScale = (float) MercatorProjection
.groundResolution(lat, 1 << mTile.zoomLevel);
l = new ExtrusionLayer(0, groundScale, extrusion.colors);
mTile.layers.setExtrusionLayers(l);

View File

@ -87,7 +87,8 @@ public class ElementLayers {
LineLayer l = (LineLayer) getLayer(level, LINE);
if (l == null)
return null;
l.width = style.width;
// FIXME l.scale = style.width;
l.scale = 1;
l.line = style;
return l;
}

View File

@ -54,7 +54,7 @@ public final class LineLayer extends RenderElement {
/* lines referenced by this outline layer */
public LineLayer outlines;
public Line line;
public float width;
public float scale = 1;
public boolean roundCap;
private float mMinDist = 1 / 8f;
@ -700,7 +700,7 @@ public final class LineLayer extends RenderElement {
RenderElement l = curLayer;
for (; l != null && l.type == RenderElement.LINE; l = l.next) {
LineLayer ll = (LineLayer) l;
Line line = ll.line;
Line line = (Line) ll.line.getCurrent();
if (ll.heightOffset != heightOffset) {
heightOffset = ll.heightOffset;
@ -725,10 +725,13 @@ public final class LineLayer extends RenderElement {
// draw LineLayer
if (!line.outline) {
// invert scaling of extrusion vectors so that line
// width stays the same.
width = ll.width / (line.fixed ? scale : variableScale);
if (line.fixed) {
// invert scaling of extrusion vectors so that line
// width stays the same. 'max'?
width = Math.max(line.width, 1) / scale;
} else {
width = ll.scale * line.width / variableScale;
}
GL.glUniform1f(uLineWidth,
(float) (width * COORD_SCALE_BY_DIR_SCALE));
@ -743,7 +746,7 @@ public final class LineLayer extends RenderElement {
}
// Cap mode
if (ll.width < 1.5 /* || ll.line.fixed */) {
if (ll.scale < 1.5 /* || ll.line.fixed */) {
if (capMode != CAP_THIN) {
capMode = CAP_THIN;
GL.glUniform1f(uLineMode, capMode);
@ -765,12 +768,21 @@ public final class LineLayer extends RenderElement {
}
// draw LineLayers references by this outline
for (LineLayer o = ll.outlines; o != null; o = o.outlines) {
for (LineLayer ref = ll.outlines; ref != null; ref = ref.outlines) {
Line core = (Line) ref.line.getCurrent();
if (o.line.fixed)
width = (ll.width + o.width) / scale;
else
width = ll.width / scale + o.width / variableScale;
// core width
if (core.fixed) {
width = Math.max(core.width, 1) / scale;
} else {
width = ref.scale * core.width / variableScale;
}
// add outline width
if (line.fixed) {
width += line.width / scale;
} else {
width += ll.scale * line.width / variableScale;
}
GL.glUniform1f(uLineWidth,
(float) (width * COORD_SCALE_BY_DIR_SCALE));
@ -784,7 +796,7 @@ public final class LineLayer extends RenderElement {
}
// Cap mode
if (o.roundCap) {
if (ref.roundCap) {
if (capMode != CAP_ROUND) {
capMode = CAP_ROUND;
GL.glUniform1f(uLineMode, capMode);
@ -795,7 +807,7 @@ public final class LineLayer extends RenderElement {
}
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP,
o.offset, o.numVertices);
ref.offset, ref.numVertices);
}
}
@ -896,5 +908,4 @@ public final class LineLayer extends RenderElement {
+ "}";
}
}

View File

@ -181,7 +181,7 @@ public final class PolygonLayer extends RenderElement {
int shader = polyShader;
for (int c = start; c < end; c++) {
Area a = mFillPolys[c].area;
Area a = (Area) mFillPolys[c].area.getCurrent();
if (enableTexture && a.texture != null) {
shader = texShader;

View File

@ -43,15 +43,15 @@ public class AtlasRenderLayer extends ElementRenderer {
LineLayer ll = layers.getLineLayer(0);
ll.line = new Line(Color.BLUE, 3, Cap.BUTT);
ll.width = 1f;
ll.scale = 1f;
LineLayer ll2 = layers.getLineLayer(1);
ll2.line = new Line(Color.RED, 3, Cap.BUTT);
ll2.width = 1f;
ll2.scale = 1f;
LineLayer ll3 = layers.getLineLayer(2);
ll3.line = new Line(Color.GREEN, 3, Cap.BUTT);
ll3.width = 1f;
ll3.scale = 1f;
TextLayer tl = new TextLayer();
Text t = Text.createText(20, 0, Color.BLACK, 0, false);

View File

@ -29,4 +29,9 @@ public class DebugTheme implements IRenderTheme {
public void scaleTextSize(float scaleFactor) {
}
@Override
public void updateInstructions() {
}
}

View File

@ -56,6 +56,8 @@ public interface IRenderTheme {
*/
public abstract int getMapBackground();
public void updateInstructions();
/**
* Scales the text size of this RenderTheme by the given factor.
*

View File

@ -193,8 +193,8 @@ public class RenderTheme implements IRenderTheme {
continue;
int i = 0;
for (RenderStyle style : ri.list) {
if (style != matches.get(i))
for (RenderStyle r : ri.list) {
if (r != matches.get(i))
break;
i++;
}
@ -257,4 +257,10 @@ public class RenderTheme implements IRenderTheme {
for (int i = 0, n = mRules.length; i < n; i++)
mRules[i].scaleTextSize(scaleFactor * mBaseTextSize);
}
@Override
public void updateInstructions() {
for (int i = 0, n = mRules.length; i < n; i++)
mRules[i].updateInstructions();
}
}

View File

@ -51,9 +51,6 @@ import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* SAX2 handler to parse XML render theme files.
*/
public class RenderThemeHandler extends DefaultHandler {
static final Logger log = LoggerFactory.getLogger(RenderThemeHandler.class);
@ -345,7 +342,6 @@ public class RenderThemeHandler extends DefaultHandler {
int fade = -1;
boolean fixed = false;
float blur = 0;
float min = 0;
// Stipple
int stipple = 0;
@ -360,7 +356,6 @@ public class RenderThemeHandler extends DefaultHandler {
fade = line.fade;
cap = line.cap;
blur = line.blur;
min = line.min;
stipple = line.stipple;
stippleColor = line.stippleColor;
stippleWidth = line.stippleWidth;
@ -407,7 +402,7 @@ public class RenderThemeHandler extends DefaultHandler {
fade = Integer.parseInt(value);
else if ("min".equals(name))
min = Float.parseFloat(value);
; //min = Float.parseFloat(value);
else if ("blur".equals(name))
blur = Float.parseFloat(value);
@ -435,7 +430,7 @@ public class RenderThemeHandler extends DefaultHandler {
return new Line(level, style, color, width, cap, fixed,
stipple, stippleColor, stippleWidth,
fade, blur, isOutline, min);
fade, blur, isOutline);
}
private static void validateLine(float strokeWidth) {

View File

@ -243,8 +243,8 @@ public abstract class Rule {
if (!mMatchFirst || matched) {
// add instructions for this rule
for (RenderStyle style : mRenderInstructions)
matchingList.add(style);
for (RenderStyle ri : mRenderInstructions)
matchingList.add(ri);
}
// this rule did match
@ -273,17 +273,49 @@ public abstract class Rule {
}
public void onDestroy() {
for (RenderStyle style : mRenderInstructions)
style.destroy();
for (RenderStyle ri : mRenderInstructions)
ri.destroy();
for (Rule subRule : mSubRules)
subRule.onDestroy();
}
public void scaleTextSize(float scaleFactor) {
for (RenderStyle style : mRenderInstructions)
style.scaleTextSize(scaleFactor);
for (RenderStyle ri : mRenderInstructions)
ri.scaleTextSize(scaleFactor);
for (Rule subRule : mSubRules)
subRule.scaleTextSize(scaleFactor);
}
public void updateInstructions() {
for (RenderStyle ri : mRenderInstructions)
ri.update();
for (Rule subRule : mSubRules)
subRule.updateInstructions();
}
public static class RuleVisitor {
boolean apply(Rule r) {
for (Rule subRule : r.mSubRules)
this.apply(subRule);
return true;
}
}
public static class UpdateVisitor extends RuleVisitor {
@Override
boolean apply(Rule r) {
for (RenderStyle ri : r.mRenderInstructions)
ri.update();
return super.apply(r);
}
}
public boolean apply(RuleVisitor v) {
return v.apply(this);
}
}

View File

@ -25,15 +25,6 @@ import org.oscim.theme.IRenderTheme.Callback;
*/
public final class Line extends RenderStyle {
// static float[] parseFloatArray(String dashString) {
// String[] dashEntries = SPLIT_PATTERN.split(dashString);
// float[] dashIntervals = new float[dashEntries.length];
// for (int i = 0; i < dashEntries.length; ++i) {
// dashIntervals[i] = Float.parseFloat(dashEntries[i]);
// }
// return dashIntervals;
// }
private final int level;
public final String style;
@ -44,7 +35,6 @@ public final class Line extends RenderStyle {
public final boolean fixed;
public final int fade;
public final float blur;
public final float min;
public final int stipple;
public final int stippleColor;
@ -53,7 +43,7 @@ public final class Line extends RenderStyle {
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, float min) {
int fade, float blur, boolean isOutline) {
this.level = level;
this.style = style;
@ -85,19 +75,18 @@ public final class Line extends RenderStyle {
this.blur = blur;
this.fade = fade;
this.min = min;
}
public Line(int stroke, float width) {
this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, 0);
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, 0);
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, 0);
this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false);
}
@Override

View File

@ -23,6 +23,21 @@ import org.oscim.theme.IRenderTheme.Callback;
* A RenderInstruction is a basic graphical primitive to draw a map.
*/
public abstract class RenderStyle {
RenderStyle mCurrent;
RenderStyle mNext;
boolean update;
public void set(RenderStyle next) {
update = true;
mNext = next;
}
public void unsetOverride() {
update = true;
mNext = null;
}
/**
* Destroys this RenderInstruction and cleans up all its internal resources.
*/
@ -51,4 +66,15 @@ public abstract class RenderStyle {
*/
public void scaleTextSize(float scaleFactor) {
}
public void update() {
if (update) {
update = false;
mCurrent = mNext;
}
}
public RenderStyle getCurrent() {
return mCurrent == null ? this : mCurrent;
}
}