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; return;
} }
LineLayer lineLayer = mTile.layers.getLineLayer(numLayer); LineLayer ll = mTile.layers.getLineLayer(numLayer);
if (lineLayer == null) if (ll == null)
return; return;
if (lineLayer.line == null) { if (ll.line == null) {
lineLayer.line = line; ll.line = line;
ll.scale = line.fixed ? 1 : mLineScale;
float w = line.width;
if (!line.fixed)
w *= mLineScale;
lineLayer.width = w;
} }
if (line.outline) { if (line.outline) {
lineLayer.addOutline(mCurLineLayer); ll.addOutline(mCurLineLayer);
return; return;
} }
lineLayer.addLine(mElement); ll.addLine(mElement);
// keep reference for outline layer // keep reference for outline layer
mCurLineLayer = lineLayer; mCurLineLayer = ll;
} else { } else {
LineTexLayer lineLayer = mTile.layers.getLineTexLayer(numLayer); LineTexLayer ll = mTile.layers.getLineTexLayer(numLayer);
if (lineLayer == null) if (ll == null)
return; return;
if (lineLayer.line == null) { if (ll.line == null) {
lineLayer.line = line; ll.line = line;
float w = line.width; float w = line.width;
if (!line.fixed) if (!line.fixed)
w *= mLineScale; 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) { if (l == null) {
double lat = MercatorProjection.toLatitude(mTile.y); double lat = MercatorProjection.toLatitude(mTile.y);
float groundScale = (float) (Math.cos(lat * (Math.PI / 180)) // float groundScale = (float) (Math.cos(lat * (Math.PI / 180))
* MercatorProjection.EARTH_CIRCUMFERENCE // * MercatorProjection.EARTH_CIRCUMFERENCE
/ ((long) Tile.SIZE << mTile.zoomLevel)); // / ((long) Tile.SIZE << mTile.zoomLevel));
float groundScale = (float) MercatorProjection
.groundResolution(lat, 1 << mTile.zoomLevel);
l = new ExtrusionLayer(0, groundScale, extrusion.colors); l = new ExtrusionLayer(0, groundScale, extrusion.colors);
mTile.layers.setExtrusionLayers(l); mTile.layers.setExtrusionLayers(l);
} }
/* 12m default */
if (height == 0)
height = 12 * 100;
l.add(mElement, height, minHeight); l.add(mElement, height, minHeight);
} }

View File

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

View File

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

View File

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

View File

@ -54,7 +54,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 Line line;
public float width; public float scale = 1;
public boolean roundCap; public boolean roundCap;
private float mMinDist = 1 / 8f; private float mMinDist = 1 / 8f;
@ -700,7 +700,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 = ll.line; Line line = (Line) ll.line.getCurrent();
if (ll.heightOffset != heightOffset) { if (ll.heightOffset != heightOffset) {
heightOffset = ll.heightOffset; heightOffset = ll.heightOffset;
@ -725,10 +725,13 @@ public final class LineLayer extends RenderElement {
// draw LineLayer // draw LineLayer
if (!line.outline) { if (!line.outline) {
if (line.fixed) {
// invert scaling of extrusion vectors so that line // invert scaling of extrusion vectors so that line
// width stays the same. // width stays the same. 'max'?
width = ll.width / (line.fixed ? scale : variableScale); width = Math.max(line.width, 1) / scale;
} else {
width = ll.scale * line.width / variableScale;
}
GL.glUniform1f(uLineWidth, GL.glUniform1f(uLineWidth,
(float) (width * COORD_SCALE_BY_DIR_SCALE)); (float) (width * COORD_SCALE_BY_DIR_SCALE));
@ -743,7 +746,7 @@ public final class LineLayer extends RenderElement {
} }
// Cap mode // Cap mode
if (ll.width < 1.5 /* || ll.line.fixed */) { if (ll.scale < 1.5 /* || ll.line.fixed */) {
if (capMode != CAP_THIN) { if (capMode != CAP_THIN) {
capMode = CAP_THIN; capMode = CAP_THIN;
GL.glUniform1f(uLineMode, capMode); GL.glUniform1f(uLineMode, capMode);
@ -765,12 +768,21 @@ public final class LineLayer extends RenderElement {
} }
// draw LineLayers references by this outline // 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) // core width
width = (ll.width + o.width) / scale; if (core.fixed) {
else width = Math.max(core.width, 1) / scale;
width = ll.width / scale + o.width / variableScale; } 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, GL.glUniform1f(uLineWidth,
(float) (width * COORD_SCALE_BY_DIR_SCALE)); (float) (width * COORD_SCALE_BY_DIR_SCALE));
@ -784,7 +796,7 @@ public final class LineLayer extends RenderElement {
} }
// Cap mode // Cap mode
if (o.roundCap) { if (ref.roundCap) {
if (capMode != CAP_ROUND) { if (capMode != CAP_ROUND) {
capMode = CAP_ROUND; capMode = CAP_ROUND;
GL.glUniform1f(uLineMode, capMode); GL.glUniform1f(uLineMode, capMode);
@ -795,7 +807,7 @@ public final class LineLayer extends RenderElement {
} }
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 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; int shader = polyShader;
for (int c = start; c < end; c++) { for (int c = start; c < end; c++) {
Area a = mFillPolys[c].area; Area a = (Area) mFillPolys[c].area.getCurrent();
if (enableTexture && a.texture != null) { if (enableTexture && a.texture != null) {
shader = texShader; shader = texShader;

View File

@ -43,15 +43,15 @@ public class AtlasRenderLayer extends ElementRenderer {
LineLayer ll = layers.getLineLayer(0); LineLayer ll = layers.getLineLayer(0);
ll.line = new Line(Color.BLUE, 3, Cap.BUTT); ll.line = new Line(Color.BLUE, 3, Cap.BUTT);
ll.width = 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 Line(Color.RED, 3, Cap.BUTT);
ll2.width = 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 Line(Color.GREEN, 3, Cap.BUTT);
ll3.width = 1f; ll3.scale = 1f;
TextLayer tl = new TextLayer(); TextLayer tl = new TextLayer();
Text t = Text.createText(20, 0, Color.BLACK, 0, false); 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) { public void scaleTextSize(float scaleFactor) {
} }
@Override
public void updateInstructions() {
}
} }

View File

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

View File

@ -193,8 +193,8 @@ public class RenderTheme implements IRenderTheme {
continue; continue;
int i = 0; int i = 0;
for (RenderStyle style : ri.list) { for (RenderStyle r : ri.list) {
if (style != matches.get(i)) if (r != matches.get(i))
break; break;
i++; i++;
} }
@ -257,4 +257,10 @@ public class RenderTheme implements IRenderTheme {
for (int i = 0, n = mRules.length; i < n; i++) for (int i = 0, n = mRules.length; i < n; i++)
mRules[i].scaleTextSize(scaleFactor * mBaseTextSize); 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.SAXParseException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
/**
* SAX2 handler to parse XML render theme files.
*/
public class RenderThemeHandler extends DefaultHandler { public class RenderThemeHandler extends DefaultHandler {
static final Logger log = LoggerFactory.getLogger(RenderThemeHandler.class); static final Logger log = LoggerFactory.getLogger(RenderThemeHandler.class);
@ -345,7 +342,6 @@ public class RenderThemeHandler extends DefaultHandler {
int fade = -1; int fade = -1;
boolean fixed = false; boolean fixed = false;
float blur = 0; float blur = 0;
float min = 0;
// Stipple // Stipple
int stipple = 0; int stipple = 0;
@ -360,7 +356,6 @@ public class RenderThemeHandler extends DefaultHandler {
fade = line.fade; fade = line.fade;
cap = line.cap; cap = line.cap;
blur = line.blur; blur = line.blur;
min = line.min;
stipple = line.stipple; stipple = line.stipple;
stippleColor = line.stippleColor; stippleColor = line.stippleColor;
stippleWidth = line.stippleWidth; stippleWidth = line.stippleWidth;
@ -407,7 +402,7 @@ public class RenderThemeHandler extends DefaultHandler {
fade = Integer.parseInt(value); fade = 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); blur = Float.parseFloat(value);
@ -435,7 +430,7 @@ public class RenderThemeHandler extends DefaultHandler {
return new Line(level, style, color, width, cap, fixed, return new Line(level, style, color, width, cap, fixed,
stipple, stippleColor, stippleWidth, stipple, stippleColor, stippleWidth,
fade, blur, isOutline, min); fade, blur, isOutline);
} }
private static void validateLine(float strokeWidth) { private static void validateLine(float strokeWidth) {

View File

@ -243,8 +243,8 @@ public abstract class Rule {
if (!mMatchFirst || matched) { if (!mMatchFirst || matched) {
// add instructions for this rule // add instructions for this rule
for (RenderStyle style : mRenderInstructions) for (RenderStyle ri : mRenderInstructions)
matchingList.add(style); matchingList.add(ri);
} }
// this rule did match // this rule did match
@ -273,17 +273,49 @@ public abstract class Rule {
} }
public void onDestroy() { public void onDestroy() {
for (RenderStyle style : mRenderInstructions) for (RenderStyle ri : mRenderInstructions)
style.destroy(); ri.destroy();
for (Rule subRule : mSubRules) for (Rule subRule : mSubRules)
subRule.onDestroy(); subRule.onDestroy();
} }
public void scaleTextSize(float scaleFactor) { public void scaleTextSize(float scaleFactor) {
for (RenderStyle style : mRenderInstructions) for (RenderStyle ri : mRenderInstructions)
style.scaleTextSize(scaleFactor); ri.scaleTextSize(scaleFactor);
for (Rule subRule : mSubRules) for (Rule subRule : mSubRules)
subRule.scaleTextSize(scaleFactor); 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 { 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; private final int level;
public final String style; public final String style;
@ -44,7 +35,6 @@ public final class Line extends RenderStyle {
public final boolean fixed; public final boolean fixed;
public final int fade; public final int fade;
public final float blur; public final float blur;
public final float min;
public final int stipple; public final int stipple;
public final int stippleColor; public final int stippleColor;
@ -53,7 +43,7 @@ public final class Line extends RenderStyle {
public Line(int level, String style, int color, float width, public Line(int level, String style, int color, float width,
Cap cap, boolean fixed, Cap cap, boolean fixed,
int stipple, int stippleColor, float stippleWidth, int stipple, int stippleColor, float stippleWidth,
int fade, float blur, boolean isOutline, float min) { int fade, float blur, boolean isOutline) {
this.level = level; this.level = level;
this.style = style; this.style = style;
@ -85,19 +75,18 @@ public final class Line extends RenderStyle {
this.blur = blur; this.blur = blur;
this.fade = fade; this.fade = fade;
this.min = min;
} }
public Line(int stroke, float width) { 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) { 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) { 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 @Override

View File

@ -23,6 +23,21 @@ import org.oscim.theme.IRenderTheme.Callback;
* A RenderInstruction is a basic graphical primitive to draw a map. * A RenderInstruction is a basic graphical primitive to draw a map.
*/ */
public abstract class RenderStyle { 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. * 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 scaleTextSize(float scaleFactor) {
} }
public void update() {
if (update) {
update = false;
mCurrent = mNext;
}
}
public RenderStyle getCurrent() {
return mCurrent == null ? this : mCurrent;
}
} }