Merge branch 'tile_load_hooks'

This commit is contained in:
Hannes Janetzek 2014-03-18 02:50:43 +01:00
commit 31e1b0ec99
24 changed files with 454 additions and 288 deletions

View File

@ -2,7 +2,6 @@ package org.oscim.layers;
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.bitmap.BitmapTileLayer; import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.tiling.source.bitmap.BitmapTileSource; import org.oscim.tiling.source.bitmap.BitmapTileSource;
@ -14,8 +13,8 @@ public class JeoTileLayer extends BitmapTileLayer {
} }
@Override @Override
protected TileLoader createLoader(TileManager tm) { protected TileLoader createLoader() {
return new TileLoader(tm) { return new TileLoader(this.getManager()) {
@Override @Override
public void cleanup() { public void cleanup() {

View File

@ -220,7 +220,7 @@ public class PathLayer extends Layer {
} }
} }
final class Task { final static class Task {
ElementLayers layer = new ElementLayers(); ElementLayers layer = new ElementLayers();
MapPosition pos = new MapPosition(); MapPosition pos = new MapPosition();
} }

View File

@ -17,17 +17,18 @@
package org.oscim.layers.tile; package org.oscim.layers.tile;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.layers.tile.vector.VectorTileLoader;
import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.SymbolItem; import org.oscim.utils.pool.Inlist;
import org.oscim.renderer.elements.TextItem;
import org.oscim.utils.pool.Inlist.List;
import org.oscim.utils.quadtree.Node; import org.oscim.utils.quadtree.Node;
import org.oscim.utils.quadtree.QuadTree;
/** /**
* Extends Tile class to hold state and data for concurrent use in * Extends Tile class to hold state and data.
* TileManager (Main Thread), *
* TileLoader (Worker Thread) and * Used concurrently in: TileManager (Main Thread), TileLoader (Worker Thread)
* TileRenderer (GL Thread). * and TileRenderer (GL Thread).
*/ */
public class MapTile extends Tile { public class MapTile extends Tile {
@ -63,6 +64,12 @@ public class MapTile extends Tile {
public final static byte CANCEL = 1 << 3; public final static byte CANCEL = 1 << 3;
} }
public static abstract class TileData extends Inlist<TileData> {
Object id;
protected abstract void dispose();
}
public MapTile(TileNode node, int tileX, int tileY, int zoomLevel) { public MapTile(TileNode node, int tileX, int tileY, int zoomLevel) {
super(tileX, tileY, (byte) zoomLevel); super(tileX, tileY, (byte) zoomLevel);
this.x = (double) tileX / (1 << zoomLevel); this.x = (double) tileX / (1 << zoomLevel);
@ -80,6 +87,13 @@ public class MapTile extends Tile {
return state; return state;
} }
/**
* List of TileData for rendering. ElementLayers is always at first
* position (for VectorTileLayer). TileLoaderHooks may add additional
* data. See e.g. {@link LabelTileLoaderHook}.
*/
public TileData data;
/** /**
* absolute tile coordinates: tileX,Y / Math.pow(2, zoomLevel) * absolute tile coordinates: tileX,Y / Math.pow(2, zoomLevel)
*/ */
@ -91,32 +105,27 @@ public class MapTile extends Tile {
*/ */
public float distance; public float distance;
/**
* FIXME move to VectorMapTile
* Tile data set by TileLoader.
*/
public final List<SymbolItem> symbols = new List<SymbolItem>();
public final List<TextItem> labels = new List<TextItem>();
public ElementLayers layers;
/** /**
* Tile is in view region. Set by TileRenderer. * Tile is in view region. Set by TileRenderer.
*/ */
public boolean isVisible; public boolean isVisible;
/**
* Used for fade-effects
*/
public long fadeTime; public long fadeTime;
/** /**
* Pointer to access relatives in QuadTree * Used to avoid drawing a tile twice per frame
*/ * TODO remove
public final TileNode node;
/**
* to avoid drawing a tile twice per frame
*/ */
int lastDraw = 0; int lastDraw = 0;
/**
* Pointer to access relatives in {@link QuadTree}
*/
public final TileNode node;
public final static int PROXY_CHILD1 = 1 << 0; public final static int PROXY_CHILD1 = 1 << 0;
public final static int PROXY_CHILD2 = 1 << 1; public final static int PROXY_CHILD2 = 1 << 1;
public final static int PROXY_CHILD3 = 1 << 2; public final static int PROXY_CHILD3 = 1 << 2;
@ -208,26 +217,53 @@ public class MapTile extends Tile {
} }
/** /**
* Test whether it is save to access a proxy item through * Test whether it is save to access a proxy item
* this.rel.* * through this.node.*
*/ */
public boolean hasProxy(int proxy) { public boolean hasProxy(int proxy) {
return (proxies & proxy) != 0; return (proxies & proxy) != 0;
} }
/** /**
* CAUTION: This function may only be called by {@link TileManager} * CAUTION: This function may only be called
* by {@link TileManager}
*/ */
protected void clear() { protected void clear() {
if (layers != null) { while (data != null) {
layers.clear(); data.dispose();
layers = null; data = data.next;
} }
TextItem.pool.releaseAll(labels.clear());
SymbolItem.pool.releaseAll(symbols.clear());
// still needed? // still needed?
state = State.NONE; state = State.NONE;
} }
/**
* Get the default ElementLayers which are added
* by {@link VectorTileLoader}
*/
public ElementLayers getLayers() {
if (!(data instanceof ElementLayers))
return null;
return (ElementLayers) data;
}
public TileData getData(Object id) {
for (TileData d = data; d != null; d = d.next)
if (d.id == id)
return d;
return null;
}
public void addData(Object id, TileData td) {
// keeping ElementLayers at position 0!
td.id = id;
if (data != null) {
td.next = data.next;
data.next = td;
} else {
data = td;
}
}
} }

View File

@ -45,7 +45,7 @@ public abstract class TileLayer extends Layer implements UpdateListener {
} }
abstract protected TileLoader createLoader(TileManager tm); abstract protected TileLoader createLoader();
public TileRenderer tileRenderer() { public TileRenderer tileRenderer() {
return (TileRenderer) mRenderer; return (TileRenderer) mRenderer;
@ -55,7 +55,7 @@ public abstract class TileLayer extends Layer implements UpdateListener {
mTileLoader = new TileLoader[numLoaders]; mTileLoader = new TileLoader[numLoaders];
for (int i = 0; i < numLoaders; i++) { for (int i = 0; i < numLoaders; i++) {
mTileLoader[i] = createLoader(mTileManager); mTileLoader[i] = createLoader();
mTileLoader[i].start(); mTileLoader[i].start();
} }
} }
@ -111,4 +111,8 @@ public abstract class TileLayer extends Layer implements UpdateListener {
for (TileLoader loader : mTileLoader) for (TileLoader loader : mTileLoader)
loader.proceed(); loader.proceed();
} }
public TileManager getManager() {
return mTileManager;
}
} }

View File

@ -26,6 +26,7 @@ import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLViewport; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.LayerRenderer; import org.oscim.renderer.LayerRenderer;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.utils.ScanBox; import org.oscim.utils.ScanBox;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -186,24 +187,25 @@ public abstract class TileRenderer extends LayerRenderer {
private static int uploadTileData(MapTile tile) { private static int uploadTileData(MapTile tile) {
tile.state = READY; tile.state = READY;
ElementLayers layers = tile.getLayers();
/* tile might contain extrusion or label layers */ /* tile might contain extrusion or label layers */
if (tile.layers == null) if (layers == null)
return 1; return 1;
int newSize = tile.layers.getSize(); int newSize = layers.getSize();
if (newSize <= 0) if (newSize <= 0)
return 1; return 1;
if (tile.layers.vbo == null) if (layers.vbo == null)
tile.layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize); layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
if (!ElementRenderer.uploadLayers(tile.layers, newSize, true)) { if (!ElementRenderer.uploadLayers(layers, newSize, true)) {
log.error("{} uploadTileData failed!", tile); log.error("{} uploadTileData failed!", tile);
layers.vbo = BufferObject.release(layers.vbo);
tile.layers.vbo = BufferObject.release(tile.layers.vbo); layers.clear();
tile.layers.clear(); /* throw Exception? */
tile.layers = null; //FIXME tile.layers = null;
return 0; return 0;
} }

View File

@ -16,6 +16,7 @@ import org.oscim.renderer.GLMatrix;
import org.oscim.renderer.GLViewport; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.elements.BitmapLayer; import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.LineTexLayer; import org.oscim.renderer.elements.LineTexLayer;
import org.oscim.renderer.elements.MeshLayer; import org.oscim.renderer.elements.MeshLayer;
@ -113,11 +114,13 @@ public class VectorTileRenderer extends TileRenderer {
/* use holder proxy when it is set */ /* use holder proxy when it is set */
MapTile t = tile.holder == null ? tile : tile.holder; MapTile t = tile.holder == null ? tile : tile.holder;
if (t.layers == null || t.layers.vbo == null) ElementLayers layers = t.getLayers();
if (layers == null || layers.vbo == null)
//throw new IllegalStateException(t + "no data " + (t.layers == null)); //throw new IllegalStateException(t + "no data " + (t.layers == null));
return; return;
t.layers.vbo.bind(); layers.vbo.bind();
MapPosition pos = v.pos; MapPosition pos = v.pos;
/* place tile relative to map position */ /* place tile relative to map position */
int z = tile.zoomLevel; int z = tile.zoomLevel;
@ -134,7 +137,8 @@ public class VectorTileRenderer extends TileRenderer {
boolean clipped = false; boolean clipped = false;
int mode = mClipMode; int mode = mClipMode;
RenderElement l = t.layers.getBaseLayers();
RenderElement l = layers.getBaseLayers();
while (l != null) { while (l != null) {
if (l.type == POLYGON) { if (l.type == POLYGON) {
@ -148,11 +152,11 @@ public class VectorTileRenderer extends TileRenderer {
clipped = true; clipped = true;
} }
if (l.type == LINE) { if (l.type == LINE) {
l = LineLayer.Renderer.draw(l, v, scale, t.layers); l = LineLayer.Renderer.draw(l, v, scale, layers);
continue; continue;
} }
if (l.type == TEXLINE) { if (l.type == TEXLINE) {
l = LineTexLayer.Renderer.draw(l, v, div, t.layers); l = LineTexLayer.Renderer.draw(l, v, div, layers);
continue; continue;
} }
if (l.type == MESH) { if (l.type == MESH) {
@ -163,7 +167,7 @@ public class VectorTileRenderer extends TileRenderer {
l = l.next; l = l.next;
} }
l = t.layers.getTextureLayers(); l = layers.getTextureLayers();
while (l != null) { while (l != null) {
if (!clipped) { if (!clipped) {
PolygonLayer.Renderer.draw(null, v, div, true, mode); PolygonLayer.Renderer.draw(null, v, div, true, mode);

View File

@ -99,7 +99,7 @@ public class BitmapTileLayer extends TileLayer {
} }
@Override @Override
protected TileLoader createLoader(TileManager tm) { protected TileLoader createLoader() {
return new BitmapTileLoader(tm, mTileSource); return new BitmapTileLoader(this, mTileSource);
} }
} }

View File

@ -23,8 +23,8 @@ import java.util.concurrent.CancellationException;
import org.oscim.backend.canvas.Bitmap; import org.oscim.backend.canvas.Bitmap;
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.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.elements.BitmapLayer; import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.ITileDataSource;
@ -38,8 +38,8 @@ public class BitmapTileLoader extends TileLoader {
private final ITileDataSource mTileDataSource; private final ITileDataSource mTileDataSource;
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) { public BitmapTileLoader(TileLayer tileLayer, TileSource tileSource) {
super(tileManager); super(tileLayer.getManager());
mTileDataSource = tileSource.getDataSource(); mTileDataSource = tileSource.getDataSource();
} }
@ -64,8 +64,9 @@ public class BitmapTileLoader extends TileLoader {
BitmapLayer l = new BitmapLayer(false); BitmapLayer l = new BitmapLayer(false);
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE); l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
mTile.layers = new ElementLayers(); ElementLayers layers = new ElementLayers();
mTile.layers.setTextureLayers(l); layers.setTextureLayers(l);
mTile.data = layers;
} }
@Override @Override

View File

@ -42,13 +42,14 @@ public class TestTileLayer extends TileLayer {
} }
@Override @Override
protected TestTileLoader createLoader(TileManager tm) { protected TestTileLoader createLoader() {
return new TestTileLoader(tm); return new TestTileLoader(this);
} }
static class TestTileLoader extends TileLoader { static class TestTileLoader extends TileLoader {
public TestTileLoader(TileManager tileManager) {
super(tileManager); public TestTileLoader(TileLayer tileLayer) {
super(tileLayer.getManager());
} }
GeometryBuffer mGeom = new GeometryBuffer(128, 16); GeometryBuffer mGeom = new GeometryBuffer(128, 16);
@ -57,9 +58,10 @@ public class TestTileLayer extends TileLayer {
@Override @Override
public boolean loadTile(MapTile tile) { public boolean loadTile(MapTile tile) {
log.debug("load tile " + tile); log.debug("load tile " + tile);
tile.layers = new ElementLayers(); ElementLayers layers = new ElementLayers();
tile.data = layers;
LineLayer ll = tile.layers.getLineLayer(0); LineLayer ll = layers.getLineLayer(0);
ll.line = mLineStyle; ll.line = mLineStyle;
ll.scale = 2; ll.scale = 2;

View File

@ -16,19 +16,30 @@
*/ */
package org.oscim.layers.tile.vector; package org.oscim.layers.tile.vector;
import org.oscim.core.MapElement;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tag;
import org.oscim.layers.Layer; import org.oscim.layers.Layer;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.vector.VectorTileLayer.TileLoaderThemeHook;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.renderer.ExtrusionRenderer; import org.oscim.renderer.ExtrusionRenderer;
import org.oscim.renderer.GLViewport; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.ExtrusionLayer;
import org.oscim.theme.styles.ExtrusionStyle;
import org.oscim.theme.styles.RenderStyle;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
public class BuildingLayer extends Layer { public class BuildingLayer extends Layer implements TileLoaderThemeHook {
//static final Logger log = LoggerFactory.getLogger(BuildingOverlay.class); //static final Logger log = LoggerFactory.getLogger(BuildingOverlay.class);
final ExtrusionRenderer mExtLayer; final ExtrusionRenderer mExtLayer;
public BuildingLayer(Map map, VectorTileLayer tileLayer) { public BuildingLayer(Map map, VectorTileLayer tileLayer) {
super(map); super(map);
tileLayer.addHook(this);
mExtLayer = new ExtrusionRenderer(tileLayer.tileRenderer()) { mExtLayer = new ExtrusionRenderer(tileLayer.tileRenderer()) {
private long mStartTime; private long mStartTime;
@ -79,6 +90,45 @@ public class BuildingLayer extends Layer {
private final static int MIN_ZOOM = 17; private final static int MIN_ZOOM = 17;
@Override
public boolean render(MapTile tile, ElementLayers layers, MapElement element,
RenderStyle style, int level) {
if (!(style instanceof ExtrusionStyle))
return false;
ExtrusionStyle extrusion = (ExtrusionStyle) style;
int height = 0;
int minHeight = 0;
String v = element.tags.getValue(Tag.KEY_HEIGHT);
if (v != null)
height = Integer.parseInt(v);
v = element.tags.getValue(Tag.KEY_MIN_HEIGHT);
if (v != null)
minHeight = Integer.parseInt(v);
ExtrusionLayer l = layers.getExtrusionLayers();
if (l == null) {
double lat = MercatorProjection.toLatitude(tile.y);
float groundScale = (float) MercatorProjection
.groundResolution(lat, 1 << tile.zoomLevel);
l = new ExtrusionLayer(0, groundScale, extrusion.colors);
layers.setExtrusionLayers(l);
}
/* 12m default */
if (height == 0)
height = 12 * 100;
l.add(element, height, minHeight);
return true;
}
//@Override //@Override
//public boolean onTouchEvent(MotionEvent e) { //public boolean onTouchEvent(MotionEvent e) {
// int action = e.getAction() & MotionEvent.ACTION_MASK; // int action = e.getAction() & MotionEvent.ACTION_MASK;

View File

@ -3,7 +3,6 @@ package org.oscim.layers.tile.vector;
import org.oscim.core.Tag; import org.oscim.core.Tag;
import org.oscim.core.TagSet; import org.oscim.core.TagSet;
import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.map.Map; import org.oscim.map.Map;
public class OsmTileLayer extends VectorTileLayer { public class OsmTileLayer extends VectorTileLayer {
@ -17,14 +16,16 @@ public class OsmTileLayer extends VectorTileLayer {
} }
@Override @Override
protected TileLoader createLoader(TileManager tm) { protected TileLoader createLoader() {
return new OsmTileLoader(tm); return new OsmTileLoader(this);
} }
static class OsmTileLoader extends VectorTileLoader { static class OsmTileLoader extends VectorTileLoader {
private final TagSet mFilteredTags;
public OsmTileLoader(TileManager tileManager) { public OsmTileLoader(VectorTileLayer tileLayer) {
super(tileManager); super(tileLayer);
mFilteredTags = new TagSet();
} }
/* Replace tags that should only be matched by key in RenderTheme /* Replace tags that should only be matched by key in RenderTheme
@ -40,7 +41,7 @@ public class OsmTileLayer extends VectorTileLayer {
new TagReplacement(Tag.KEY_MIN_HEIGHT) new TagReplacement(Tag.KEY_MIN_HEIGHT)
}; };
protected boolean filterTags(TagSet tagSet) { protected TagSet filterTags(TagSet tagSet) {
Tag[] tags = tagSet.tags; Tag[] tags = tagSet.tags;
mFilteredTags.clear(); mFilteredTags.clear();
@ -58,7 +59,7 @@ public class OsmTileLayer extends VectorTileLayer {
mFilteredTags.add(t); mFilteredTags.add(t);
} }
return true; return mFilteredTags;
} }
} }
} }

View File

@ -16,12 +16,16 @@
*/ */
package org.oscim.layers.tile.vector; package org.oscim.layers.tile.vector;
import org.oscim.core.MapElement;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLayer; import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager; import org.oscim.layers.tile.TileManager;
import org.oscim.layers.tile.VectorTileRenderer; 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.theme.IRenderTheme; import org.oscim.theme.IRenderTheme;
import org.oscim.theme.styles.RenderStyle;
import org.oscim.tiling.TileSource; import org.oscim.tiling.TileSource;
import org.oscim.tiling.TileSource.OpenResult; import org.oscim.tiling.TileSource.OpenResult;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -58,8 +62,8 @@ public class VectorTileLayer extends TileLayer {
} }
@Override @Override
protected TileLoader createLoader(TileManager tm) { protected TileLoader createLoader() {
return new VectorTileLoader(tm); return new VectorTileLoader(this);
} }
/** /**
@ -98,21 +102,58 @@ public class VectorTileLayer extends TileLayer {
* Set {@link IRenderTheme} used by {@link TileLoader} * Set {@link IRenderTheme} used by {@link TileLoader}
*/ */
public void setRenderTheme(IRenderTheme theme) { public void setRenderTheme(IRenderTheme theme) {
// wait for loaders to finish all current jobs to /* wait for loaders to finish all current jobs to
// not change theme instance hold by loader instance * not change theme instance hold by loader instance
// while running * while running */
pauseLoaders(true); pauseLoaders(true);
mTileManager.clearJobs(); mTileManager.clearJobs();
for (TileLoader l : mTileLoader) mTheme = theme;
((VectorTileLoader) l).setRenderTheme(theme); // for (TileLoader l : mTileLoader)
// ((VectorTileLoader) l).setRenderTheme(theme);
tileRenderer().setOverdrawColor(theme.getMapBackground()); tileRenderer().setOverdrawColor(theme.getMapBackground());
resumeLoaders(); resumeLoaders();
} }
public TileManager getManager() { private IRenderTheme mTheme;
return mTileManager;
public IRenderTheme getTheme() {
return mTheme;
}
public interface TileLoaderProcessHook {
public boolean process(MapTile tile, ElementLayers layers, MapElement element);
}
public interface TileLoaderThemeHook {
public boolean render(MapTile tile, ElementLayers layers,
MapElement element, RenderStyle style, int level);
}
private TileLoaderProcessHook[] mLoaderProcessHooks = new TileLoaderProcessHook[0];
private TileLoaderThemeHook[] mLoaderThemeHooks = new TileLoaderThemeHook[0];
public TileLoaderProcessHook[] loaderProcessHooks() {
return mLoaderProcessHooks;
}
public TileLoaderThemeHook[] loaderThemeHooks() {
return mLoaderThemeHooks;
}
public void addHook(TileLoaderProcessHook h) {
TileLoaderProcessHook[] tmp = mLoaderProcessHooks;
mLoaderProcessHooks = new TileLoaderProcessHook[tmp.length + 1];
System.arraycopy(tmp, 0, mLoaderProcessHooks, 0, tmp.length);
mLoaderProcessHooks[tmp.length] = h;
}
public void addHook(TileLoaderThemeHook h) {
TileLoaderThemeHook[] tmp = mLoaderThemeHooks;
mLoaderThemeHooks = new TileLoaderThemeHook[tmp.length + 1];
System.arraycopy(tmp, 0, mLoaderThemeHooks, 0, tmp.length);
mLoaderThemeHooks[tmp.length] = h;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012, 2013 Hannes Janetzek * Copyright 2012-2014 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).
* *
@ -20,24 +20,20 @@ import static org.oscim.layers.tile.MapTile.State.CANCEL;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.GeometryBuffer.GeometryType; import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement; import org.oscim.core.MapElement;
import org.oscim.core.MercatorProjection; import org.oscim.core.MercatorProjection;
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.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.vector.VectorTileLayer.TileLoaderProcessHook;
import org.oscim.layers.tile.vector.VectorTileLayer.TileLoaderThemeHook;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.ExtrusionLayer;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.LineTexLayer; import org.oscim.renderer.elements.LineTexLayer;
import org.oscim.renderer.elements.MeshLayer; import org.oscim.renderer.elements.MeshLayer;
import org.oscim.renderer.elements.PolygonLayer; import org.oscim.renderer.elements.PolygonLayer;
import org.oscim.renderer.elements.SymbolItem;
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.AreaStyle; import org.oscim.theme.styles.AreaStyle;
@ -62,7 +58,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
public static final byte STROKE_MAX_ZOOM = 17; public static final byte STROKE_MAX_ZOOM = 17;
protected IRenderTheme renderTheme; protected IRenderTheme renderTheme;
protected int renderLevels;
/** current TileDataSource used by this MapTileLoader */ /** current TileDataSource used by this MapTileLoader */
protected ITileDataSource mTileDataSource; protected ITileDataSource mTileDataSource;
@ -79,17 +74,13 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
/** Line-scale-factor depending on zoom and latitude */ /** Line-scale-factor depending on zoom and latitude */
protected float mLineScale = 1.0f; protected float mLineScale = 1.0f;
protected final TagSet mFilteredTags; protected ElementLayers mLayers;
public void setRenderTheme(IRenderTheme theme) { private final VectorTileLayer mTileLayer;
renderTheme = theme;
renderLevels = theme.getLevels();
}
public VectorTileLoader(TileManager tileManager) { public VectorTileLoader(VectorTileLayer tileLayer) {
super(tileManager); super(tileLayer.getManager());
mTileLayer = tileLayer;
mFilteredTags = new TagSet();
} }
@Override @Override
@ -105,12 +96,14 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
log.error("no tile source is set"); log.error("no tile source is set");
return false; return false;
} }
renderTheme = mTileLayer.getTheme();
if (renderTheme == null) { if (renderTheme == null) {
log.error("no theme is set"); log.error("no theme is set");
return false; return false;
} }
//mTileLayer.getLoaderHooks();
/* account for area changes with latitude */ /* account for area changes with latitude */
double lat = MercatorProjection.toLatitude(tile.y); double lat = MercatorProjection.toLatitude(tile.y);
mLineScale = (float) Math.pow(STROKE_INCREASE, tile.zoomLevel - STROKE_MIN_ZOOM); mLineScale = (float) Math.pow(STROKE_INCREASE, tile.zoomLevel - STROKE_MIN_ZOOM);
@ -119,8 +112,8 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
/* scale line width relative to latitude + PI * thumb */ /* scale line width relative to latitude + PI * thumb */
mLineScale *= 0.4f + 0.6f * ((float) Math.sin(Math.abs(lat) * (Math.PI / 180))); mLineScale *= 0.4f + 0.6f * ((float) Math.sin(Math.abs(lat) * (Math.PI / 180)));
mLayers = new ElementLayers();
tile.layers = new ElementLayers(); tile.data = mLayers;
try { try {
/* query data source, which calls process() callback */ /* query data source, which calls process() callback */
@ -151,11 +144,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
} }
} }
public void setDataSource(ITileDataSource mapDatabase) { public void setDataSource(ITileDataSource dataSource) {
if (mTileDataSource != null) if (mTileDataSource != null)
mTileDataSource.destroy(); mTileDataSource.destroy();
mTileDataSource = mapDatabase; mTileDataSource = dataSource;
} }
static class TagReplacement { static class TagReplacement {
@ -171,46 +164,36 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
/** /**
* Override this method to change tags that should be passed * Override this method to change tags that should be passed
* to {@link RenderTheme} matching. * to {@link RenderTheme} matching.
* E.g. to replace tags that should not be cached in Rendertheme
*/ */
protected boolean filterTags(TagSet tagSet) { protected TagSet filterTags(TagSet tagSet) {
mFilteredTags.clear(); return tagSet;
for (int i = 0; i < tagSet.numTags; i++)
mFilteredTags.add(tagSet.tags[i]);
return true;
} }
@Override @Override
public void process(MapElement element) { public void process(MapElement element) {
clearState();
if (isCanceled() || mTile.state(CANCEL)) if (isCanceled() || mTile.state(CANCEL))
throw new CancellationException(); throw new CancellationException();
mElement = element; for (TileLoaderProcessHook h : mTileLayer.loaderProcessHooks())
if (h.process(mTile, mLayers, element))
if (element.type == GeometryType.POINT) {
// remove tags that should not be cached in Rendertheme
filterTags(element.tags);
// get and apply render instructions
renderNode(renderTheme.matchElement(element.type, mFilteredTags, mTile.zoomLevel));
} else {
// replace tags that should not be cached in Rendertheme (e.g. name)
if (!filterTags(element.tags))
return; return;
mCurLayer = getValidLayer(element.layer) * renderLevels; TagSet tags = filterTags(element.tags);
if (tags == null)
return;
// get and apply render instructions mElement = element;
renderWay(renderTheme.matchElement(element.type, mFilteredTags, mTile.zoomLevel));
//boolean closed = element.type == GeometryType.POLY; /* get and apply render instructions */
if (element.type == GeometryType.POINT) {
mCurLineLayer = null; renderNode(renderTheme.matchElement(element.type, tags, mTile.zoomLevel));
} else {
mCurLayer = getValidLayer(element.layer) * renderTheme.getLevels();
renderWay(renderTheme.matchElement(element.type, tags, mTile.zoomLevel));
} }
clearState();
mElement = null;
} }
//protected void debugUnmatched(boolean closed, TagSet tags) { //protected void debugUnmatched(boolean closed, TagSet tags) {
@ -243,6 +226,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
protected void clearState() { protected void clearState() {
mCurLineLayer = null; mCurLineLayer = null;
mElement = null;
} }
/*** RenderThemeCallback ***/ /*** RenderThemeCallback ***/
@ -257,7 +241,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
return; return;
} }
LineLayer ll = mTile.layers.getLineLayer(numLayer); LineLayer ll = mLayers.getLineLayer(numLayer);
if (ll.line == null) { if (ll.line == null) {
ll.line = line; ll.line = line;
@ -271,11 +255,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
ll.addLine(mElement); ll.addLine(mElement);
// NB: keep reference for outline layer(s) /* keep reference for outline layer(s) */
mCurLineLayer = ll; mCurLineLayer = ll;
} else { } else {
LineTexLayer ll = mTile.layers.getLineTexLayer(numLayer); LineTexLayer ll = mLayers.getLineTexLayer(numLayer);
if (ll.line == null) { if (ll.line == null) {
ll.line = line; ll.line = line;
@ -291,129 +275,46 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
} }
} }
// slower to load (requires tesselation) and uses /* slower to load (requires tesselation) and uses
// more memory but should be faster to render * more memory but should be faster to render */
protected final static boolean USE_MESH_POLY = false; protected final static boolean USE_MESH_POLY = false;
@Override @Override
public void renderArea(AreaStyle 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 = mLayers.getMeshLayer(numLayer);
l.area = area; l.area = area;
l.addMesh(mElement); l.addMesh(mElement);
} else { } else {
PolygonLayer l = mTile.layers.getPolygonLayer(numLayer); PolygonLayer l = mLayers.getPolygonLayer(numLayer);
l.area = area; l.area = area;
l.addPolygon(mElement.points, mElement.index); l.addPolygon(mElement.points, mElement.index);
} }
} }
@Override @Override
public void renderAreaText(TextStyle text) { public void renderSymbol(SymbolStyle symbol) {
// TODO place somewhere on polygon for (TileLoaderThemeHook h : mTileLayer.loaderThemeHooks())
String value = mElement.tags.getValue(text.textKey); if (h.render(mTile, mLayers, mElement, symbol, 0))
if (value == null || value.length() == 0)
return;
float x = 0;
float y = 0;
int n = mElement.index[0];
for (int i = 0; i < n;) {
x += mElement.points[i++];
y += mElement.points[i++];
}
x /= (n / 2);
y /= (n / 2);
mTile.labels.push(TextItem.pool.get().set(x, y, value, text));
}
@Override
public void renderPointText(TextStyle text) {
String value = mElement.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return;
for (int i = 0, n = mElement.getNumPoints(); i < n; i++) {
PointF p = mElement.getPoint(i);
mTile.labels.push(TextItem.pool.get().set(p.x, p.y, value, text));
}
}
@Override
public void renderWayText(TextStyle text) {
String value = mElement.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return;
int offset = 0;
for (int i = 0, n = mElement.index.length; i < n; i++) {
int length = mElement.index[i];
if (length < 4)
break; break;
WayDecorator.renderText(null, mElement.points, value, text,
offset, length, mTile);
offset += length;
}
}
@Override
public void renderPointCircle(CircleStyle circle, int level) {
}
@Override
public void renderPointSymbol(SymbolStyle symbol) {
if (symbol.texture == null)
return;
for (int i = 0, n = mElement.getNumPoints(); i < n; i++) {
PointF p = mElement.getPoint(i);
SymbolItem it = SymbolItem.pool.get();
it.set(p.x, p.y, symbol.texture, true);
mTile.symbols.push(it);
}
}
@Override
public void renderAreaSymbol(SymbolStyle symbol) {
} }
@Override @Override
public void renderExtrusion(ExtrusionStyle extrusion, int level) { public void renderExtrusion(ExtrusionStyle extrusion, int level) {
int height = 0; for (TileLoaderThemeHook h : mTileLayer.loaderThemeHooks())
int minHeight = 0; if (h.render(mTile, mLayers, mElement, extrusion, level))
break;
String v = mElement.tags.getValue(Tag.KEY_HEIGHT);
if (v != null)
height = Integer.parseInt(v);
v = mElement.tags.getValue(Tag.KEY_MIN_HEIGHT);
if (v != null)
minHeight = Integer.parseInt(v);
ExtrusionLayer l = mTile.layers.getExtrusionLayers();
if (l == null) {
double lat = MercatorProjection.toLatitude(mTile.y);
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);
} }
@Override @Override
public void setTileImage(Bitmap bitmap) { public void renderCircle(CircleStyle circle, int level) {
}
@Override
public void renderText(TextStyle text) {
for (TileLoaderThemeHook h : mTileLayer.loaderThemeHooks())
if (h.render(mTile, mLayers, mElement, text, 0))
break;
} }
} }

View File

@ -31,6 +31,8 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager
static final Logger log = LoggerFactory.getLogger(LabelLayer.class); static final Logger log = LoggerFactory.getLogger(LabelLayer.class);
public final static String LABEL_DATA = LabelLayer.class.getName();
private final static long MAX_RELABEL_DELAY = 100; private final static long MAX_RELABEL_DELAY = 100;
private final LabelPlacement mLabelPlacer; private final LabelPlacement mLabelPlacer;
@ -39,6 +41,7 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager
public LabelLayer(Map map, VectorTileLayer l) { public LabelLayer(Map map, VectorTileLayer l) {
super(map); super(map);
l.getManager().events.bind(this); l.getManager().events.bind(this);
l.addHook(new LabelTileLoaderHook());
mLabelPlacer = new LabelPlacement(map, l.tileRenderer()); mLabelPlacer = new LabelPlacement(map, l.tileRenderer());
mWorker = new Worker(map); mWorker = new Worker(map);

View File

@ -18,6 +18,10 @@ import org.oscim.utils.geom.OBB2D;
public class LabelPlacement { public class LabelPlacement {
static final boolean dbg = false; static final boolean dbg = false;
public final static LabelTileData getLabels(MapTile tile) {
return (LabelTileData) tile.getData(LabelLayer.LABEL_DATA);
}
private final static float MIN_CAPTION_DIST = 5; private final static float MIN_CAPTION_DIST = 5;
private final static float MIN_WAY_DIST = 3; private final static float MIN_WAY_DIST = 3;
@ -176,7 +180,11 @@ public class LabelPlacement {
private Label addWayLabels(MapTile t, Label l, float dx, float dy, private Label addWayLabels(MapTile t, Label l, float dx, float dy,
double scale) { double scale) {
for (TextItem ti : t.labels) { LabelTileData ld = getLabels(t);
if (ld == null)
return l;
for (TextItem ti : ld.labels) {
if (ti.text.caption) if (ti.text.caption)
continue; continue;
@ -229,7 +237,11 @@ public class LabelPlacement {
private Label addNodeLabels(MapTile t, Label l, float dx, float dy, private Label addNodeLabels(MapTile t, Label l, float dx, float dy,
double scale, float cos, float sin) { double scale, float cos, float sin) {
O: for (TextItem ti : t.labels) { LabelTileData ld = getLabels(t);
if (ld == null)
return l;
O: for (TextItem ti : ld.labels) {
if (!ti.text.caption) if (!ti.text.caption)
continue; continue;
@ -447,7 +459,11 @@ public class LabelPlacement {
float dy = (float) (t.tileY * Tile.SIZE - tileY); float dy = (float) (t.tileY * Tile.SIZE - tileY);
dx = flipLongitude(dx, maxx); dx = flipLongitude(dx, maxx);
for (SymbolItem ti : t.symbols) { LabelTileData ld = getLabels(t);
if (ld == null)
continue;
for (SymbolItem ti : ld.symbols) {
if (ti.texRegion == null) if (ti.texRegion == null)
continue; continue;

View File

@ -0,0 +1,16 @@
package org.oscim.layers.tile.vector.labeling;
import org.oscim.layers.tile.MapTile.TileData;
import org.oscim.renderer.elements.SymbolItem;
import org.oscim.renderer.elements.TextItem;
public class LabelTileData extends TileData {
public final List<SymbolItem> symbols = new List<SymbolItem>();
public final List<TextItem> labels = new List<TextItem>();
@Override
protected void dispose() {
TextItem.pool.releaseAll(labels.clear());
SymbolItem.pool.releaseAll(symbols.clear());
}
}

View File

@ -0,0 +1,106 @@
package org.oscim.layers.tile.vector.labeling;
import static org.oscim.core.GeometryBuffer.GeometryType.LINE;
import static org.oscim.core.GeometryBuffer.GeometryType.POINT;
import static org.oscim.core.GeometryBuffer.GeometryType.POLY;
import static org.oscim.layers.tile.vector.labeling.LabelLayer.LABEL_DATA;
import org.oscim.core.MapElement;
import org.oscim.core.PointF;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.vector.VectorTileLayer.TileLoaderThemeHook;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.SymbolItem;
import org.oscim.renderer.elements.TextItem;
import org.oscim.theme.styles.RenderStyle;
import org.oscim.theme.styles.SymbolStyle;
import org.oscim.theme.styles.TextStyle;
public class LabelTileLoaderHook implements TileLoaderThemeHook {
//public final static LabelTileData EMPTY = new LabelTileData();
private LabelTileData get(MapTile tile) {
// FIXME could be 'this'..
LabelTileData ld = (LabelTileData) tile.getData(LABEL_DATA);
if (ld == null) {
ld = new LabelTileData();
tile.addData(LABEL_DATA, ld);
}
return ld;
}
@Override
public boolean render(MapTile tile, ElementLayers layers, MapElement element,
RenderStyle style, int level) {
if (style instanceof TextStyle) {
LabelTileData ld = get(tile);
TextStyle text = (TextStyle) style;
if (element.type == LINE) {
String value = element.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return false;
int offset = 0;
for (int i = 0, n = element.index.length; i < n; i++) {
int length = element.index[i];
if (length < 4)
break;
WayDecorator.renderText(null, element.points, value, text,
offset, length, ld);
offset += length;
}
}
else if (element.type == POLY) {
// TODO place somewhere on polygon
String value = element.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return false;
float x = 0;
float y = 0;
int n = element.index[0];
for (int i = 0; i < n;) {
x += element.points[i++];
y += element.points[i++];
}
x /= (n / 2);
y /= (n / 2);
ld.labels.push(TextItem.pool.get().set(x, y, value, text));
}
else if (element.type == POINT) {
String value = element.tags.getValue(text.textKey);
if (value == null || value.length() == 0)
return false;
for (int i = 0, n = element.getNumPoints(); i < n; i++) {
PointF p = element.getPoint(i);
ld.labels.push(TextItem.pool.get().set(p.x, p.y, value, text));
}
}
}
else if ((element.type == POINT) && (style instanceof SymbolStyle)) {
SymbolStyle symbol = (SymbolStyle) style;
if (symbol.texture == null)
return false;
LabelTileData ld = get(tile);
for (int i = 0, n = element.getNumPoints(); i < n; i++) {
PointF p = element.getPoint(i);
SymbolItem it = SymbolItem.pool.get();
it.set(p.x, p.y, symbol.texture, true);
ld.symbols.push(it);
}
}
return false;
}
}

View File

@ -15,10 +15,9 @@
* You should have received a copy of the GNU Lesser General Public License along with * 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/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.layers.tile.vector; package org.oscim.layers.tile.vector.labeling;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.renderer.elements.TextItem; import org.oscim.renderer.elements.TextItem;
import org.oscim.theme.styles.TextStyle; import org.oscim.theme.styles.TextStyle;
import org.oscim.utils.geom.GeometryUtils; import org.oscim.utils.geom.GeometryUtils;
@ -27,7 +26,7 @@ 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,
TextStyle text, int pos, int len, MapTile tile) { TextStyle text, int pos, int len, LabelTileData ld) {
//TextItem items = textItems; //TextItem items = textItems;
TextItem t = null; TextItem t = null;
@ -216,7 +215,7 @@ public final class WayDecorator {
t.length = (short) segmentLength; t.length = (short) segmentLength;
t.edges = edge; t.edges = edge;
tile.labels.push(t); ld.labels.push(t);
i = last; i = last;
} }

View File

@ -25,6 +25,7 @@ import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileRenderer; import org.oscim.layers.tile.TileRenderer;
import org.oscim.layers.tile.TileSet; import org.oscim.layers.tile.TileSet;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.ExtrusionLayer; import org.oscim.renderer.elements.ExtrusionLayer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -169,10 +170,11 @@ public class ExtrusionRenderer extends LayerRenderer {
} }
private static ExtrusionLayer getLayer(MapTile t) { private static ExtrusionLayer getLayer(MapTile t) {
if (t.layers == null || !t.state(READY | NEW_DATA)) ElementLayers layers = t.getLayers();
if (layers == null || !t.state(READY | NEW_DATA))
return null; return null;
return t.layers.getExtrusionLayers(); return layers.getExtrusionLayers();
} }
private final boolean debug = false; private final boolean debug = false;
@ -201,7 +203,7 @@ public class ExtrusionRenderer extends LayerRenderer {
GLState.test(false, false); GLState.test(false, false);
for (int i = 0; i < mTileCnt; i++) { for (int i = 0; i < mTileCnt; i++) {
ExtrusionLayer el = tiles[i].layers.getExtrusionLayers(); ExtrusionLayer el = tiles[i].getLayers().getExtrusionLayers();
setMatrix(v, tiles[i], 0); setMatrix(v, tiles[i], 0);
v.mvp.setAsUniform(uExtMatrix); v.mvp.setAsUniform(uExtMatrix);
@ -252,7 +254,7 @@ public class ExtrusionRenderer extends LayerRenderer {
// draw to depth buffer // draw to depth buffer
for (int i = 0; i < mTileCnt; i++) { for (int i = 0; i < mTileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
ExtrusionLayer el = t.layers.getExtrusionLayers(); ExtrusionLayer el = t.getLayers().getExtrusionLayers();
int d = MapRenderer.depthOffset(t) * 10; int d = MapRenderer.depthOffset(t) * 10;
setMatrix(v, t, d); setMatrix(v, t, d);
v.mvp.setAsUniform(uExtMatrix); v.mvp.setAsUniform(uExtMatrix);
@ -278,7 +280,7 @@ public class ExtrusionRenderer extends LayerRenderer {
for (int i = 0; i < mTileCnt; i++) { for (int i = 0; i < mTileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
ExtrusionLayer el = t.layers.getExtrusionLayers(); ExtrusionLayer el = t.getLayers().getExtrusionLayers();
if (el.colors == null) { if (el.colors == null) {
currentColor = mColor; currentColor = mColor;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012, 2013 Hannes Janetzek * Copyright 2012-2014 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).
* *
@ -24,6 +24,7 @@ import static org.oscim.renderer.elements.RenderElement.TEXLINE;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.layers.tile.MapTile.TileData;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
import org.oscim.theme.styles.AreaStyle; import org.oscim.theme.styles.AreaStyle;
import org.oscim.theme.styles.LineStyle; import org.oscim.theme.styles.LineStyle;
@ -35,7 +36,8 @@ import org.slf4j.LoggerFactory;
* MapTile. It can be used for other purposes as well but some optimizations * MapTile. It can be used for other purposes as well but some optimizations
* (and limitations) probably wont make sense in different contexts. * (and limitations) probably wont make sense in different contexts.
*/ */
public class ElementLayers { public class ElementLayers extends TileData {
static final Logger log = LoggerFactory.getLogger(ElementLayers.class); static final Logger log = LoggerFactory.getLogger(ElementLayers.class);
public static void initRenderer(GL20 gl) { public static void initRenderer(GL20 gl) {
@ -57,6 +59,10 @@ public class ElementLayers {
/** Text- and SymbolLayer */ /** Text- and SymbolLayer */
private RenderElement textureLayers; private RenderElement textureLayers;
/**
* FIXME this is somewhat out-of-place, as it is not
* compiled with the other layers
*/
private RenderElement extrusionLayers; private RenderElement extrusionLayers;
/** /**
@ -386,4 +392,9 @@ public class ElementLayers {
vbo = BufferObject.release(vbo); vbo = BufferObject.release(vbo);
} }
@Override
protected void dispose() {
clear();
}
} }

View File

@ -85,22 +85,6 @@ public interface IRenderTheme {
*/ */
void renderExtrusion(ExtrusionStyle extrusion, int level); void renderExtrusion(ExtrusionStyle extrusion, int level);
/**
* Renders an area symbol with the given bitmap.
*
* @param symbol
* the symbol to be rendered.
*/
void renderAreaSymbol(SymbolStyle symbol);
/**
* Renders an area caption with the given text.
*
* @param text
* the text to be rendered.
*/
void renderAreaText(TextStyle text);
/** /**
* Renders a point of interest circle with the given parameters. * Renders a point of interest circle with the given parameters.
* *
@ -109,7 +93,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(CircleStyle circle, int level); void renderCircle(CircleStyle circle, int level);
/** /**
* Renders a point of interest symbol with the given bitmap. * Renders a point of interest symbol with the given bitmap.
@ -117,15 +101,7 @@ public interface IRenderTheme {
* @param symbol * @param symbol
* the symbol to be rendered. * the symbol to be rendered.
*/ */
void renderPointSymbol(SymbolStyle symbol); void renderSymbol(SymbolStyle symbol);
/**
* Renders a point of interest caption with the given text.
*
* @param text
* the text to be rendered.
*/
void renderPointText(TextStyle text);
/** /**
* Renders a way with the given parameters. * Renders a way with the given parameters.
@ -140,7 +116,7 @@ public interface IRenderTheme {
* *
* @param text * @param text
*/ */
void renderWayText(TextStyle text); void renderText(TextStyle text);
} }

View File

@ -49,6 +49,6 @@ public final class CircleStyle extends RenderStyle {
@Override @Override
public void renderNode(Callback renderCallback) { public void renderNode(Callback renderCallback) {
renderCallback.renderPointCircle(this, this.level); renderCallback.renderCircle(this, this.level);
} }
} }

View File

@ -36,12 +36,12 @@ public final class SymbolStyle extends RenderStyle {
} }
@Override @Override
public void renderNode(Callback renderCallback) { public void renderNode(Callback cb) {
renderCallback.renderPointSymbol(this); cb.renderSymbol(this);
} }
@Override @Override
public void renderWay(Callback renderCallback) { public void renderWay(Callback cb) {
renderCallback.renderAreaSymbol(this); cb.renderSymbol(this);
} }
} }

View File

@ -182,17 +182,13 @@ public final class TextStyle extends RenderStyle {
public final TextureRegion texture; public final TextureRegion texture;
@Override @Override
public void renderNode(Callback renderCallback) { public void renderNode(Callback cb) {
if (caption) cb.renderText(this);
renderCallback.renderPointText(this);
} }
@Override @Override
public void renderWay(Callback renderCallback) { public void renderWay(Callback cb) {
if (caption) cb.renderText(this);
renderCallback.renderAreaText(this);
else
renderCallback.renderWayText(this);
} }
@Override @Override