Merge branch 'tile_load_hooks'
This commit is contained in:
commit
31e1b0ec99
@ -2,7 +2,6 @@ package org.oscim.layers;
|
||||
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.layers.tile.TileLoader;
|
||||
import org.oscim.layers.tile.TileManager;
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.tiling.source.bitmap.BitmapTileSource;
|
||||
@ -14,8 +13,8 @@ public class JeoTileLayer extends BitmapTileLayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileLoader createLoader(TileManager tm) {
|
||||
return new TileLoader(tm) {
|
||||
protected TileLoader createLoader() {
|
||||
return new TileLoader(this.getManager()) {
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
@ -220,7 +220,7 @@ public class PathLayer extends Layer {
|
||||
}
|
||||
}
|
||||
|
||||
final class Task {
|
||||
final static class Task {
|
||||
ElementLayers layer = new ElementLayers();
|
||||
MapPosition pos = new MapPosition();
|
||||
}
|
||||
|
||||
@ -17,17 +17,18 @@
|
||||
package org.oscim.layers.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.SymbolItem;
|
||||
import org.oscim.renderer.elements.TextItem;
|
||||
import org.oscim.utils.pool.Inlist.List;
|
||||
import org.oscim.utils.pool.Inlist;
|
||||
import org.oscim.utils.quadtree.Node;
|
||||
import org.oscim.utils.quadtree.QuadTree;
|
||||
|
||||
/**
|
||||
* Extends Tile class to hold state and data for concurrent use in
|
||||
* TileManager (Main Thread),
|
||||
* TileLoader (Worker Thread) and
|
||||
* TileRenderer (GL Thread).
|
||||
* Extends Tile class to hold state and data.
|
||||
*
|
||||
* Used concurrently in: TileManager (Main Thread), TileLoader (Worker Thread)
|
||||
* and TileRenderer (GL Thread).
|
||||
*/
|
||||
public class MapTile extends Tile {
|
||||
|
||||
@ -63,6 +64,12 @@ public class MapTile extends Tile {
|
||||
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) {
|
||||
super(tileX, tileY, (byte) zoomLevel);
|
||||
this.x = (double) tileX / (1 << zoomLevel);
|
||||
@ -80,6 +87,13 @@ public class MapTile extends Tile {
|
||||
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)
|
||||
*/
|
||||
@ -91,32 +105,27 @@ public class MapTile extends Tile {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public boolean isVisible;
|
||||
|
||||
/**
|
||||
* Used for fade-effects
|
||||
*/
|
||||
public long fadeTime;
|
||||
|
||||
/**
|
||||
* Pointer to access relatives in QuadTree
|
||||
*/
|
||||
public final TileNode node;
|
||||
|
||||
/**
|
||||
* to avoid drawing a tile twice per frame
|
||||
* Used to avoid drawing a tile twice per frame
|
||||
* TODO remove
|
||||
*/
|
||||
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_CHILD2 = 1 << 1;
|
||||
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
|
||||
* this.rel.*
|
||||
* Test whether it is save to access a proxy item
|
||||
* through this.node.*
|
||||
*/
|
||||
public boolean hasProxy(int proxy) {
|
||||
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() {
|
||||
if (layers != null) {
|
||||
layers.clear();
|
||||
layers = null;
|
||||
while (data != null) {
|
||||
data.dispose();
|
||||
data = data.next;
|
||||
}
|
||||
|
||||
TextItem.pool.releaseAll(labels.clear());
|
||||
SymbolItem.pool.releaseAll(symbols.clear());
|
||||
|
||||
// still needed?
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
return (TileRenderer) mRenderer;
|
||||
@ -55,7 +55,7 @@ public abstract class TileLayer extends Layer implements UpdateListener {
|
||||
mTileLoader = new TileLoader[numLoaders];
|
||||
|
||||
for (int i = 0; i < numLoaders; i++) {
|
||||
mTileLoader[i] = createLoader(mTileManager);
|
||||
mTileLoader[i] = createLoader();
|
||||
mTileLoader[i].start();
|
||||
}
|
||||
}
|
||||
@ -111,4 +111,8 @@ public abstract class TileLayer extends Layer implements UpdateListener {
|
||||
for (TileLoader loader : mTileLoader)
|
||||
loader.proceed();
|
||||
}
|
||||
|
||||
public TileManager getManager() {
|
||||
return mTileManager;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import org.oscim.renderer.ElementRenderer;
|
||||
import org.oscim.renderer.GLViewport;
|
||||
import org.oscim.renderer.LayerRenderer;
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
import org.oscim.renderer.elements.ElementLayers;
|
||||
import org.oscim.utils.ScanBox;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -186,24 +187,25 @@ public abstract class TileRenderer extends LayerRenderer {
|
||||
|
||||
private static int uploadTileData(MapTile tile) {
|
||||
tile.state = READY;
|
||||
ElementLayers layers = tile.getLayers();
|
||||
|
||||
/* tile might contain extrusion or label layers */
|
||||
if (tile.layers == null)
|
||||
if (layers == null)
|
||||
return 1;
|
||||
|
||||
int newSize = tile.layers.getSize();
|
||||
int newSize = layers.getSize();
|
||||
if (newSize <= 0)
|
||||
return 1;
|
||||
|
||||
if (tile.layers.vbo == null)
|
||||
tile.layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
|
||||
if (layers.vbo == null)
|
||||
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);
|
||||
|
||||
tile.layers.vbo = BufferObject.release(tile.layers.vbo);
|
||||
tile.layers.clear();
|
||||
tile.layers = null;
|
||||
layers.vbo = BufferObject.release(layers.vbo);
|
||||
layers.clear();
|
||||
/* throw Exception? */
|
||||
//FIXME tile.layers = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import org.oscim.renderer.GLMatrix;
|
||||
import org.oscim.renderer.GLViewport;
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
import org.oscim.renderer.elements.BitmapLayer;
|
||||
import org.oscim.renderer.elements.ElementLayers;
|
||||
import org.oscim.renderer.elements.LineLayer;
|
||||
import org.oscim.renderer.elements.LineTexLayer;
|
||||
import org.oscim.renderer.elements.MeshLayer;
|
||||
@ -113,11 +114,13 @@ public class VectorTileRenderer extends TileRenderer {
|
||||
/* use holder proxy when it is set */
|
||||
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));
|
||||
return;
|
||||
|
||||
t.layers.vbo.bind();
|
||||
layers.vbo.bind();
|
||||
MapPosition pos = v.pos;
|
||||
/* place tile relative to map position */
|
||||
int z = tile.zoomLevel;
|
||||
@ -134,7 +137,8 @@ public class VectorTileRenderer extends TileRenderer {
|
||||
|
||||
boolean clipped = false;
|
||||
int mode = mClipMode;
|
||||
RenderElement l = t.layers.getBaseLayers();
|
||||
|
||||
RenderElement l = layers.getBaseLayers();
|
||||
|
||||
while (l != null) {
|
||||
if (l.type == POLYGON) {
|
||||
@ -148,11 +152,11 @@ public class VectorTileRenderer extends TileRenderer {
|
||||
clipped = true;
|
||||
}
|
||||
if (l.type == LINE) {
|
||||
l = LineLayer.Renderer.draw(l, v, scale, t.layers);
|
||||
l = LineLayer.Renderer.draw(l, v, scale, layers);
|
||||
continue;
|
||||
}
|
||||
if (l.type == TEXLINE) {
|
||||
l = LineTexLayer.Renderer.draw(l, v, div, t.layers);
|
||||
l = LineTexLayer.Renderer.draw(l, v, div, layers);
|
||||
continue;
|
||||
}
|
||||
if (l.type == MESH) {
|
||||
@ -163,7 +167,7 @@ public class VectorTileRenderer extends TileRenderer {
|
||||
l = l.next;
|
||||
}
|
||||
|
||||
l = t.layers.getTextureLayers();
|
||||
l = layers.getTextureLayers();
|
||||
while (l != null) {
|
||||
if (!clipped) {
|
||||
PolygonLayer.Renderer.draw(null, v, div, true, mode);
|
||||
|
||||
@ -99,7 +99,7 @@ public class BitmapTileLayer extends TileLayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileLoader createLoader(TileManager tm) {
|
||||
return new BitmapTileLoader(tm, mTileSource);
|
||||
protected TileLoader createLoader() {
|
||||
return new BitmapTileLoader(this, mTileSource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,8 @@ import java.util.concurrent.CancellationException;
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.layers.tile.TileLayer;
|
||||
import org.oscim.layers.tile.TileLoader;
|
||||
import org.oscim.layers.tile.TileManager;
|
||||
import org.oscim.renderer.elements.BitmapLayer;
|
||||
import org.oscim.renderer.elements.ElementLayers;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
@ -38,8 +38,8 @@ public class BitmapTileLoader extends TileLoader {
|
||||
|
||||
private final ITileDataSource mTileDataSource;
|
||||
|
||||
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
|
||||
super(tileManager);
|
||||
public BitmapTileLoader(TileLayer tileLayer, TileSource tileSource) {
|
||||
super(tileLayer.getManager());
|
||||
mTileDataSource = tileSource.getDataSource();
|
||||
}
|
||||
|
||||
@ -64,8 +64,9 @@ public class BitmapTileLoader extends TileLoader {
|
||||
|
||||
BitmapLayer l = new BitmapLayer(false);
|
||||
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
|
||||
mTile.layers = new ElementLayers();
|
||||
mTile.layers.setTextureLayers(l);
|
||||
ElementLayers layers = new ElementLayers();
|
||||
layers.setTextureLayers(l);
|
||||
mTile.data = layers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -42,13 +42,14 @@ public class TestTileLayer extends TileLayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TestTileLoader createLoader(TileManager tm) {
|
||||
return new TestTileLoader(tm);
|
||||
protected TestTileLoader createLoader() {
|
||||
return new TestTileLoader(this);
|
||||
}
|
||||
|
||||
static class TestTileLoader extends TileLoader {
|
||||
public TestTileLoader(TileManager tileManager) {
|
||||
super(tileManager);
|
||||
|
||||
public TestTileLoader(TileLayer tileLayer) {
|
||||
super(tileLayer.getManager());
|
||||
}
|
||||
|
||||
GeometryBuffer mGeom = new GeometryBuffer(128, 16);
|
||||
@ -57,9 +58,10 @@ public class TestTileLayer extends TileLayer {
|
||||
@Override
|
||||
public boolean loadTile(MapTile 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.scale = 2;
|
||||
|
||||
|
||||
@ -16,19 +16,30 @@
|
||||
*/
|
||||
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.tile.MapTile;
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer.TileLoaderThemeHook;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.renderer.ExtrusionRenderer;
|
||||
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;
|
||||
|
||||
public class BuildingLayer extends Layer {
|
||||
public class BuildingLayer extends Layer implements TileLoaderThemeHook {
|
||||
//static final Logger log = LoggerFactory.getLogger(BuildingOverlay.class);
|
||||
|
||||
final ExtrusionRenderer mExtLayer;
|
||||
|
||||
public BuildingLayer(Map map, VectorTileLayer tileLayer) {
|
||||
super(map);
|
||||
tileLayer.addHook(this);
|
||||
|
||||
mExtLayer = new ExtrusionRenderer(tileLayer.tileRenderer()) {
|
||||
private long mStartTime;
|
||||
|
||||
@ -79,6 +90,45 @@ public class BuildingLayer extends Layer {
|
||||
|
||||
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
|
||||
//public boolean onTouchEvent(MotionEvent e) {
|
||||
// int action = e.getAction() & MotionEvent.ACTION_MASK;
|
||||
|
||||
@ -3,7 +3,6 @@ package org.oscim.layers.tile.vector;
|
||||
import org.oscim.core.Tag;
|
||||
import org.oscim.core.TagSet;
|
||||
import org.oscim.layers.tile.TileLoader;
|
||||
import org.oscim.layers.tile.TileManager;
|
||||
import org.oscim.map.Map;
|
||||
|
||||
public class OsmTileLayer extends VectorTileLayer {
|
||||
@ -17,14 +16,16 @@ public class OsmTileLayer extends VectorTileLayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileLoader createLoader(TileManager tm) {
|
||||
return new OsmTileLoader(tm);
|
||||
protected TileLoader createLoader() {
|
||||
return new OsmTileLoader(this);
|
||||
}
|
||||
|
||||
static class OsmTileLoader extends VectorTileLoader {
|
||||
private final TagSet mFilteredTags;
|
||||
|
||||
public OsmTileLoader(TileManager tileManager) {
|
||||
super(tileManager);
|
||||
public OsmTileLoader(VectorTileLayer tileLayer) {
|
||||
super(tileLayer);
|
||||
mFilteredTags = new TagSet();
|
||||
}
|
||||
|
||||
/* 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)
|
||||
};
|
||||
|
||||
protected boolean filterTags(TagSet tagSet) {
|
||||
protected TagSet filterTags(TagSet tagSet) {
|
||||
Tag[] tags = tagSet.tags;
|
||||
|
||||
mFilteredTags.clear();
|
||||
@ -58,7 +59,7 @@ public class OsmTileLayer extends VectorTileLayer {
|
||||
mFilteredTags.add(t);
|
||||
}
|
||||
|
||||
return true;
|
||||
return mFilteredTags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,12 +16,16 @@
|
||||
*/
|
||||
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.TileLoader;
|
||||
import org.oscim.layers.tile.TileManager;
|
||||
import org.oscim.layers.tile.VectorTileRenderer;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.renderer.elements.ElementLayers;
|
||||
import org.oscim.theme.IRenderTheme;
|
||||
import org.oscim.theme.styles.RenderStyle;
|
||||
import org.oscim.tiling.TileSource;
|
||||
import org.oscim.tiling.TileSource.OpenResult;
|
||||
import org.slf4j.Logger;
|
||||
@ -58,8 +62,8 @@ public class VectorTileLayer extends TileLayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TileLoader createLoader(TileManager tm) {
|
||||
return new VectorTileLoader(tm);
|
||||
protected TileLoader createLoader() {
|
||||
return new VectorTileLoader(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,21 +102,58 @@ public class VectorTileLayer extends TileLayer {
|
||||
* Set {@link IRenderTheme} used by {@link TileLoader}
|
||||
*/
|
||||
public void setRenderTheme(IRenderTheme theme) {
|
||||
// wait for loaders to finish all current jobs to
|
||||
// not change theme instance hold by loader instance
|
||||
// while running
|
||||
/* wait for loaders to finish all current jobs to
|
||||
* not change theme instance hold by loader instance
|
||||
* while running */
|
||||
pauseLoaders(true);
|
||||
mTileManager.clearJobs();
|
||||
|
||||
for (TileLoader l : mTileLoader)
|
||||
((VectorTileLoader) l).setRenderTheme(theme);
|
||||
mTheme = theme;
|
||||
// for (TileLoader l : mTileLoader)
|
||||
// ((VectorTileLoader) l).setRenderTheme(theme);
|
||||
|
||||
tileRenderer().setOverdrawColor(theme.getMapBackground());
|
||||
|
||||
resumeLoaders();
|
||||
}
|
||||
|
||||
public TileManager getManager() {
|
||||
return mTileManager;
|
||||
private IRenderTheme mTheme;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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).
|
||||
*
|
||||
@ -20,24 +20,20 @@ import static org.oscim.layers.tile.MapTile.State.CANCEL;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.core.PointF;
|
||||
import org.oscim.core.Tag;
|
||||
import org.oscim.core.TagSet;
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
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.ExtrusionLayer;
|
||||
import org.oscim.renderer.elements.LineLayer;
|
||||
import org.oscim.renderer.elements.LineTexLayer;
|
||||
import org.oscim.renderer.elements.MeshLayer;
|
||||
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.RenderTheme;
|
||||
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;
|
||||
|
||||
protected IRenderTheme renderTheme;
|
||||
protected int renderLevels;
|
||||
|
||||
/** current TileDataSource used by this MapTileLoader */
|
||||
protected ITileDataSource mTileDataSource;
|
||||
@ -79,17 +74,13 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
/** Line-scale-factor depending on zoom and latitude */
|
||||
protected float mLineScale = 1.0f;
|
||||
|
||||
protected final TagSet mFilteredTags;
|
||||
protected ElementLayers mLayers;
|
||||
|
||||
public void setRenderTheme(IRenderTheme theme) {
|
||||
renderTheme = theme;
|
||||
renderLevels = theme.getLevels();
|
||||
}
|
||||
private final VectorTileLayer mTileLayer;
|
||||
|
||||
public VectorTileLoader(TileManager tileManager) {
|
||||
super(tileManager);
|
||||
|
||||
mFilteredTags = new TagSet();
|
||||
public VectorTileLoader(VectorTileLayer tileLayer) {
|
||||
super(tileLayer.getManager());
|
||||
mTileLayer = tileLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -105,12 +96,14 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
log.error("no tile source is set");
|
||||
return false;
|
||||
}
|
||||
|
||||
renderTheme = mTileLayer.getTheme();
|
||||
if (renderTheme == null) {
|
||||
log.error("no theme is set");
|
||||
return false;
|
||||
}
|
||||
|
||||
//mTileLayer.getLoaderHooks();
|
||||
|
||||
/* account for area changes with latitude */
|
||||
double lat = MercatorProjection.toLatitude(tile.y);
|
||||
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 */
|
||||
mLineScale *= 0.4f + 0.6f * ((float) Math.sin(Math.abs(lat) * (Math.PI / 180)));
|
||||
|
||||
tile.layers = new ElementLayers();
|
||||
mLayers = new ElementLayers();
|
||||
tile.data = mLayers;
|
||||
|
||||
try {
|
||||
/* 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)
|
||||
mTileDataSource.destroy();
|
||||
|
||||
mTileDataSource = mapDatabase;
|
||||
mTileDataSource = dataSource;
|
||||
}
|
||||
|
||||
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
|
||||
* to {@link RenderTheme} matching.
|
||||
* E.g. to replace tags that should not be cached in Rendertheme
|
||||
*/
|
||||
protected boolean filterTags(TagSet tagSet) {
|
||||
mFilteredTags.clear();
|
||||
for (int i = 0; i < tagSet.numTags; i++)
|
||||
mFilteredTags.add(tagSet.tags[i]);
|
||||
return true;
|
||||
protected TagSet filterTags(TagSet tagSet) {
|
||||
return tagSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(MapElement element) {
|
||||
clearState();
|
||||
|
||||
if (isCanceled() || mTile.state(CANCEL))
|
||||
throw new CancellationException();
|
||||
|
||||
mElement = 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))
|
||||
for (TileLoaderProcessHook h : mTileLayer.loaderProcessHooks())
|
||||
if (h.process(mTile, mLayers, element))
|
||||
return;
|
||||
|
||||
mCurLayer = getValidLayer(element.layer) * renderLevels;
|
||||
TagSet tags = filterTags(element.tags);
|
||||
if (tags == null)
|
||||
return;
|
||||
|
||||
// get and apply render instructions
|
||||
renderWay(renderTheme.matchElement(element.type, mFilteredTags, mTile.zoomLevel));
|
||||
mElement = element;
|
||||
|
||||
//boolean closed = element.type == GeometryType.POLY;
|
||||
|
||||
mCurLineLayer = null;
|
||||
/* get and apply render instructions */
|
||||
if (element.type == GeometryType.POINT) {
|
||||
renderNode(renderTheme.matchElement(element.type, tags, mTile.zoomLevel));
|
||||
} else {
|
||||
mCurLayer = getValidLayer(element.layer) * renderTheme.getLevels();
|
||||
renderWay(renderTheme.matchElement(element.type, tags, mTile.zoomLevel));
|
||||
}
|
||||
|
||||
mElement = null;
|
||||
clearState();
|
||||
}
|
||||
|
||||
//protected void debugUnmatched(boolean closed, TagSet tags) {
|
||||
@ -243,6 +226,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
|
||||
protected void clearState() {
|
||||
mCurLineLayer = null;
|
||||
mElement = null;
|
||||
}
|
||||
|
||||
/*** RenderThemeCallback ***/
|
||||
@ -257,7 +241,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
return;
|
||||
}
|
||||
|
||||
LineLayer ll = mTile.layers.getLineLayer(numLayer);
|
||||
LineLayer ll = mLayers.getLineLayer(numLayer);
|
||||
|
||||
if (ll.line == null) {
|
||||
ll.line = line;
|
||||
@ -271,11 +255,11 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
|
||||
ll.addLine(mElement);
|
||||
|
||||
// NB: keep reference for outline layer(s)
|
||||
/* keep reference for outline layer(s) */
|
||||
mCurLineLayer = ll;
|
||||
|
||||
} else {
|
||||
LineTexLayer ll = mTile.layers.getLineTexLayer(numLayer);
|
||||
LineTexLayer ll = mLayers.getLineTexLayer(numLayer);
|
||||
|
||||
if (ll.line == null) {
|
||||
ll.line = line;
|
||||
@ -291,129 +275,46 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
||||
}
|
||||
}
|
||||
|
||||
// slower to load (requires tesselation) and uses
|
||||
// more memory but should be faster to render
|
||||
/* slower to load (requires tesselation) and uses
|
||||
* more memory but should be faster to render */
|
||||
protected final static boolean USE_MESH_POLY = false;
|
||||
|
||||
@Override
|
||||
public void renderArea(AreaStyle area, int level) {
|
||||
int numLayer = mCurLayer + level;
|
||||
if (USE_MESH_POLY) {
|
||||
MeshLayer l = mTile.layers.getMeshLayer(numLayer);
|
||||
MeshLayer l = mLayers.getMeshLayer(numLayer);
|
||||
l.area = area;
|
||||
l.addMesh(mElement);
|
||||
} else {
|
||||
PolygonLayer l = mTile.layers.getPolygonLayer(numLayer);
|
||||
PolygonLayer l = mLayers.getPolygonLayer(numLayer);
|
||||
l.area = area;
|
||||
l.addPolygon(mElement.points, mElement.index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAreaText(TextStyle text) {
|
||||
// TODO place somewhere on polygon
|
||||
String value = mElement.tags.getValue(text.textKey);
|
||||
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)
|
||||
public void renderSymbol(SymbolStyle symbol) {
|
||||
for (TileLoaderThemeHook h : mTileLayer.loaderThemeHooks())
|
||||
if (h.render(mTile, mLayers, mElement, symbol, 0))
|
||||
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
|
||||
public void renderExtrusion(ExtrusionStyle extrusion, int level) {
|
||||
int height = 0;
|
||||
int minHeight = 0;
|
||||
|
||||
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);
|
||||
for (TileLoaderThemeHook h : mTileLayer.loaderThemeHooks())
|
||||
if (h.render(mTile, mLayers, mElement, extrusion, level))
|
||||
break;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,8 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager
|
||||
|
||||
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 LabelPlacement mLabelPlacer;
|
||||
@ -39,6 +41,7 @@ public class LabelLayer extends Layer implements Map.UpdateListener, TileManager
|
||||
public LabelLayer(Map map, VectorTileLayer l) {
|
||||
super(map);
|
||||
l.getManager().events.bind(this);
|
||||
l.addHook(new LabelTileLoaderHook());
|
||||
|
||||
mLabelPlacer = new LabelPlacement(map, l.tileRenderer());
|
||||
mWorker = new Worker(map);
|
||||
|
||||
@ -18,6 +18,10 @@ import org.oscim.utils.geom.OBB2D;
|
||||
public class LabelPlacement {
|
||||
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_WAY_DIST = 3;
|
||||
|
||||
@ -176,7 +180,11 @@ public class LabelPlacement {
|
||||
private Label addWayLabels(MapTile t, Label l, float dx, float dy,
|
||||
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)
|
||||
continue;
|
||||
|
||||
@ -229,7 +237,11 @@ public class LabelPlacement {
|
||||
private Label addNodeLabels(MapTile t, Label l, float dx, float dy,
|
||||
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)
|
||||
continue;
|
||||
|
||||
@ -447,7 +459,11 @@ public class LabelPlacement {
|
||||
float dy = (float) (t.tileY * Tile.SIZE - tileY);
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,10 +15,9 @@
|
||||
* 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.layers.tile.vector;
|
||||
package org.oscim.layers.tile.vector.labeling;
|
||||
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.renderer.elements.TextItem;
|
||||
import org.oscim.theme.styles.TextStyle;
|
||||
import org.oscim.utils.geom.GeometryUtils;
|
||||
@ -27,7 +26,7 @@ import org.oscim.utils.geom.LineClipper;
|
||||
public final class WayDecorator {
|
||||
|
||||
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 t = null;
|
||||
|
||||
@ -216,7 +215,7 @@ public final class WayDecorator {
|
||||
t.length = (short) segmentLength;
|
||||
|
||||
t.edges = edge;
|
||||
tile.labels.push(t);
|
||||
ld.labels.push(t);
|
||||
|
||||
i = last;
|
||||
}
|
||||
@ -25,6 +25,7 @@ import org.oscim.core.Tile;
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.layers.tile.TileRenderer;
|
||||
import org.oscim.layers.tile.TileSet;
|
||||
import org.oscim.renderer.elements.ElementLayers;
|
||||
import org.oscim.renderer.elements.ExtrusionLayer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -169,10 +170,11 @@ public class ExtrusionRenderer extends LayerRenderer {
|
||||
}
|
||||
|
||||
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 t.layers.getExtrusionLayers();
|
||||
return layers.getExtrusionLayers();
|
||||
}
|
||||
|
||||
private final boolean debug = false;
|
||||
@ -201,7 +203,7 @@ public class ExtrusionRenderer extends LayerRenderer {
|
||||
GLState.test(false, false);
|
||||
|
||||
for (int i = 0; i < mTileCnt; i++) {
|
||||
ExtrusionLayer el = tiles[i].layers.getExtrusionLayers();
|
||||
ExtrusionLayer el = tiles[i].getLayers().getExtrusionLayers();
|
||||
|
||||
setMatrix(v, tiles[i], 0);
|
||||
v.mvp.setAsUniform(uExtMatrix);
|
||||
@ -252,7 +254,7 @@ public class ExtrusionRenderer extends LayerRenderer {
|
||||
// draw to depth buffer
|
||||
for (int i = 0; i < mTileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
ExtrusionLayer el = t.layers.getExtrusionLayers();
|
||||
ExtrusionLayer el = t.getLayers().getExtrusionLayers();
|
||||
int d = MapRenderer.depthOffset(t) * 10;
|
||||
setMatrix(v, t, d);
|
||||
v.mvp.setAsUniform(uExtMatrix);
|
||||
@ -278,7 +280,7 @@ public class ExtrusionRenderer extends LayerRenderer {
|
||||
|
||||
for (int i = 0; i < mTileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
ExtrusionLayer el = t.layers.getExtrusionLayers();
|
||||
ExtrusionLayer el = t.getLayers().getExtrusionLayers();
|
||||
|
||||
if (el.colors == null) {
|
||||
currentColor = mColor;
|
||||
|
||||
@ -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).
|
||||
*
|
||||
@ -24,6 +24,7 @@ import static org.oscim.renderer.elements.RenderElement.TEXLINE;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.layers.tile.MapTile.TileData;
|
||||
import org.oscim.renderer.BufferObject;
|
||||
import org.oscim.theme.styles.AreaStyle;
|
||||
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
|
||||
* (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);
|
||||
|
||||
public static void initRenderer(GL20 gl) {
|
||||
@ -57,6 +59,10 @@ public class ElementLayers {
|
||||
/** Text- and SymbolLayer */
|
||||
private RenderElement textureLayers;
|
||||
|
||||
/**
|
||||
* FIXME this is somewhat out-of-place, as it is not
|
||||
* compiled with the other layers
|
||||
*/
|
||||
private RenderElement extrusionLayers;
|
||||
|
||||
/**
|
||||
@ -386,4 +392,9 @@ public class ElementLayers {
|
||||
vbo = BufferObject.release(vbo);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -85,22 +85,6 @@ public interface IRenderTheme {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -109,7 +93,7 @@ public interface IRenderTheme {
|
||||
* @param level
|
||||
* 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.
|
||||
@ -117,15 +101,7 @@ public interface IRenderTheme {
|
||||
* @param symbol
|
||||
* the symbol to be rendered.
|
||||
*/
|
||||
void renderPointSymbol(SymbolStyle symbol);
|
||||
|
||||
/**
|
||||
* Renders a point of interest caption with the given text.
|
||||
*
|
||||
* @param text
|
||||
* the text to be rendered.
|
||||
*/
|
||||
void renderPointText(TextStyle text);
|
||||
void renderSymbol(SymbolStyle symbol);
|
||||
|
||||
/**
|
||||
* Renders a way with the given parameters.
|
||||
@ -140,7 +116,7 @@ public interface IRenderTheme {
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
void renderWayText(TextStyle text);
|
||||
void renderText(TextStyle text);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -49,6 +49,6 @@ public final class CircleStyle extends RenderStyle {
|
||||
|
||||
@Override
|
||||
public void renderNode(Callback renderCallback) {
|
||||
renderCallback.renderPointCircle(this, this.level);
|
||||
renderCallback.renderCircle(this, this.level);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,12 +36,12 @@ public final class SymbolStyle extends RenderStyle {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderNode(Callback renderCallback) {
|
||||
renderCallback.renderPointSymbol(this);
|
||||
public void renderNode(Callback cb) {
|
||||
cb.renderSymbol(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderWay(Callback renderCallback) {
|
||||
renderCallback.renderAreaSymbol(this);
|
||||
public void renderWay(Callback cb) {
|
||||
cb.renderSymbol(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,17 +182,13 @@ public final class TextStyle extends RenderStyle {
|
||||
public final TextureRegion texture;
|
||||
|
||||
@Override
|
||||
public void renderNode(Callback renderCallback) {
|
||||
if (caption)
|
||||
renderCallback.renderPointText(this);
|
||||
public void renderNode(Callback cb) {
|
||||
cb.renderText(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderWay(Callback renderCallback) {
|
||||
if (caption)
|
||||
renderCallback.renderAreaText(this);
|
||||
else
|
||||
renderCallback.renderWayText(this);
|
||||
public void renderWay(Callback cb) {
|
||||
cb.renderText(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user