serious refactor: TileLoader:
- no more duplication of TileLoaders for GWT -> - decouple loadTile() from TileDataSource completed() call - all TileDataSource MUST call completed(success) in any case now
This commit is contained in:
parent
a8f46fdd8d
commit
c24b4addfa
@ -14,10 +14,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
|
import org.oscim.core.MapElement;
|
||||||
|
import org.oscim.tiling.ITileDataSink;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.utils.Timer;
|
import com.badlogic.gdx.utils.Timer;
|
||||||
|
|
||||||
public abstract class TileLoader {
|
public abstract class TileLoader implements ITileDataSink {
|
||||||
|
|
||||||
private final TileManager mTileManager;
|
private final TileManager mTileManager;
|
||||||
private Timer mTimer;
|
private Timer mTimer;
|
||||||
@ -31,7 +38,7 @@ public abstract class TileLoader {
|
|||||||
|
|
||||||
public abstract void cleanup();
|
public abstract void cleanup();
|
||||||
|
|
||||||
protected abstract boolean executeJob(MapTile tile);
|
protected abstract boolean loadTile(MapTile tile);
|
||||||
|
|
||||||
boolean isInterrupted;
|
boolean isInterrupted;
|
||||||
|
|
||||||
@ -70,48 +77,65 @@ public abstract class TileLoader {
|
|||||||
mPausing = false;
|
mPausing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean mWorking;
|
protected boolean mWorking;
|
||||||
|
protected MapTile mTile;
|
||||||
|
|
||||||
public void go() {
|
public void go() {
|
||||||
if (mWorking) {
|
if (mWorking)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
MapTile tile = mTileManager.getTileJob();
|
mTile = mTileManager.getTileJob();
|
||||||
|
|
||||||
if (tile == null)
|
if (mTile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
executeJob(tile);
|
loadTile(mTile);
|
||||||
|
|
||||||
mWorking = true;
|
mWorking = true;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
completed(FAILED);
|
||||||
tile.clear();
|
|
||||||
jobCompleted(tile, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void jobCompleted(MapTile tile, boolean success) {
|
/**
|
||||||
if (isInterrupted)
|
* Callback to be called by TileDataSource when finished
|
||||||
success = false;
|
* loading or on failure. MUST BE CALLED IN ANY CASE!
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void completed(QueryResult result) {
|
||||||
|
boolean success = (result == SUCCESS) && !isInterrupted;
|
||||||
|
|
||||||
mTileManager.jobCompleted(tile, success);
|
mTileManager.jobCompleted(mTile, success);
|
||||||
|
mTile = null;
|
||||||
|
|
||||||
mWorking = false;
|
mWorking = false;
|
||||||
|
|
||||||
if (!mPausing && mTileManager.hasTileJobs()) {
|
if (mPausing || !mTileManager.hasTileJobs())
|
||||||
|
return;
|
||||||
|
|
||||||
Gdx.app.postRunnable(new Runnable() {
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
go();
|
go();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by TileDataSource
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(MapElement element) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by TileDataSource
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setTileImage(Bitmap bitmap) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
package org.oscim.layers.tile.bitmap;
|
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.State.CANCEL;
|
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
|
||||||
import org.oscim.core.MapElement;
|
|
||||||
import org.oscim.core.Tile;
|
|
||||||
import org.oscim.layers.tile.MapTile;
|
|
||||||
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.ITileDataSink;
|
|
||||||
import org.oscim.tiling.ITileDataSource;
|
|
||||||
import org.oscim.tiling.ITileDataSource.QueryResult;
|
|
||||||
import org.oscim.tiling.TileSource;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class BitmapTileLoader extends TileLoader implements ITileDataSink {
|
|
||||||
|
|
||||||
protected static final Logger log = LoggerFactory.getLogger(BitmapTileLoader.class);
|
|
||||||
|
|
||||||
private final ITileDataSource mTileDataSource;
|
|
||||||
private MapTile mTile;
|
|
||||||
|
|
||||||
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
|
|
||||||
super(tileManager);
|
|
||||||
mTileDataSource = tileSource.getDataSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanup() {
|
|
||||||
mTile = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean executeJob(MapTile tile) {
|
|
||||||
mTile = tile;
|
|
||||||
//QueryResult result = null;
|
|
||||||
//try {
|
|
||||||
if (mTileDataSource.executeQuery(tile, this) != QueryResult.SUCCESS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
// catch (CancellationException e) {
|
|
||||||
// log.debug("{} was canceled", mTile);
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// log.debug("{} {}", mTile, e.getMessage());
|
|
||||||
// } finally {
|
|
||||||
// mTile = null;
|
|
||||||
// }
|
|
||||||
return true;
|
|
||||||
//return result == QueryResult.SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTileImage(Bitmap bitmap) {
|
|
||||||
if (isCanceled() || mTile.state(CANCEL))
|
|
||||||
return;
|
|
||||||
//throw new CancellationException();
|
|
||||||
|
|
||||||
BitmapLayer l = new BitmapLayer(false);
|
|
||||||
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
|
|
||||||
mTile.layers = new ElementLayers();
|
|
||||||
mTile.layers.setTextureLayers(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void process(MapElement element) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed(boolean success) {
|
|
||||||
jobCompleted(mTile, success);
|
|
||||||
mTile = null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,404 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.layers.tile.vector;
|
|
||||||
|
|
||||||
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.core.Tile;
|
|
||||||
import org.oscim.layers.tile.MapTile;
|
|
||||||
import org.oscim.layers.tile.TileLoader;
|
|
||||||
import org.oscim.layers.tile.TileManager;
|
|
||||||
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.styles.Area;
|
|
||||||
import org.oscim.theme.styles.Circle;
|
|
||||||
import org.oscim.theme.styles.Extrusion;
|
|
||||||
import org.oscim.theme.styles.Line;
|
|
||||||
import org.oscim.theme.styles.LineSymbol;
|
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
|
||||||
import org.oscim.theme.styles.Symbol;
|
|
||||||
import org.oscim.theme.styles.Text;
|
|
||||||
import org.oscim.tiling.ITileDataSink;
|
|
||||||
import org.oscim.tiling.ITileDataSource;
|
|
||||||
import org.oscim.tiling.ITileDataSource.QueryResult;
|
|
||||||
import org.oscim.utils.geom.LineClipper;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class VectorTileLoader extends TileLoader implements IRenderTheme.Callback, ITileDataSink {
|
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger(VectorTileLoader.class);
|
|
||||||
|
|
||||||
protected static final double STROKE_INCREASE = Math.sqrt(2.5);
|
|
||||||
protected static final byte LAYERS = 11;
|
|
||||||
|
|
||||||
public static final byte STROKE_MIN_ZOOM = 12;
|
|
||||||
public static final byte STROKE_MAX_ZOOM = 17;
|
|
||||||
|
|
||||||
protected IRenderTheme renderTheme;
|
|
||||||
protected int renderLevels;
|
|
||||||
|
|
||||||
/** current TileDataSource used by this MapTileLoader */
|
|
||||||
protected ITileDataSource mTileDataSource;
|
|
||||||
|
|
||||||
/** currently processed tile */
|
|
||||||
protected MapTile mTile;
|
|
||||||
|
|
||||||
/** currently processed MapElement */
|
|
||||||
protected MapElement mElement;
|
|
||||||
|
|
||||||
/** current line layer (will be used for outline layers) */
|
|
||||||
protected LineLayer mCurLineLayer;
|
|
||||||
|
|
||||||
/** Current layer for adding elements */
|
|
||||||
protected int mCurLayer;
|
|
||||||
|
|
||||||
/** Line-scale-factor depending on zoom and latitude */
|
|
||||||
protected float mLineScale = 1.0f;
|
|
||||||
|
|
||||||
protected final LineClipper mClipper;
|
|
||||||
|
|
||||||
protected final TagSet mFilteredTags;
|
|
||||||
|
|
||||||
public void setRenderTheme(IRenderTheme theme) {
|
|
||||||
renderTheme = theme;
|
|
||||||
renderLevels = theme.getLevels();
|
|
||||||
}
|
|
||||||
|
|
||||||
public VectorTileLoader(TileManager tileManager) {
|
|
||||||
super(tileManager);
|
|
||||||
|
|
||||||
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
|
|
||||||
mFilteredTags = new TagSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanup() {
|
|
||||||
mTileDataSource.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean executeJob(MapTile tile) {
|
|
||||||
|
|
||||||
if (mTileDataSource == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// account for area changes with latitude
|
|
||||||
double lat = MercatorProjection.toLatitude(tile.y);
|
|
||||||
|
|
||||||
mLineScale = (float) Math.pow(STROKE_INCREASE, tile.zoomLevel - STROKE_MIN_ZOOM);
|
|
||||||
if (mLineScale < 1)
|
|
||||||
mLineScale = 1;
|
|
||||||
|
|
||||||
// scale line width relative to latitude + PI * thumb
|
|
||||||
mLineScale *= 0.4f + 0.6f * ((float) Math.sin(Math.abs(lat) * (Math.PI / 180)));
|
|
||||||
|
|
||||||
mTile = tile;
|
|
||||||
mTile.layers = new ElementLayers();
|
|
||||||
|
|
||||||
// query database, which calls renderWay and renderPOI
|
|
||||||
// callbacks while processing map tile data.
|
|
||||||
if (mTileDataSource.executeQuery(mTile, this) != QueryResult.SUCCESS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void completed(boolean success) {
|
|
||||||
jobCompleted(mTile, success);
|
|
||||||
mTile = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static int getValidLayer(int layer) {
|
|
||||||
if (layer < 0) {
|
|
||||||
return 0;
|
|
||||||
} else if (layer >= LAYERS) {
|
|
||||||
return LAYERS - 1;
|
|
||||||
} else {
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataSource(ITileDataSource mapDatabase) {
|
|
||||||
if (mTileDataSource != null)
|
|
||||||
mTileDataSource.destroy();
|
|
||||||
|
|
||||||
mTileDataSource = mapDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
static class TagReplacement {
|
|
||||||
public TagReplacement(String key) {
|
|
||||||
this.key = key;
|
|
||||||
this.tag = new Tag(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
String key;
|
|
||||||
Tag tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean filterTags(TagSet tagSet) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void process(MapElement element) {
|
|
||||||
clearState();
|
|
||||||
|
|
||||||
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))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mCurLayer = getValidLayer(element.layer) * renderLevels;
|
|
||||||
|
|
||||||
// get and apply render instructions
|
|
||||||
renderWay(renderTheme.matchElement(element.type, mFilteredTags, mTile.zoomLevel));
|
|
||||||
|
|
||||||
//boolean closed = element.type == GeometryType.POLY;
|
|
||||||
//if (debug.debugTheme && ri == null)
|
|
||||||
// debugUnmatched(closed, element.tags);
|
|
||||||
|
|
||||||
mCurLineLayer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
mElement = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//protected void debugUnmatched(boolean closed, TagSet tags) {
|
|
||||||
// log.debug("DBG way not matched: " + closed + " "
|
|
||||||
// + Arrays.deepToString(tags));
|
|
||||||
//
|
|
||||||
// mTagName = new Tag("name", tags[0].key + ":"
|
|
||||||
// + tags[0].value, false);
|
|
||||||
//
|
|
||||||
// mElement.tags = closed ? debugTagArea : debugTagWay;
|
|
||||||
// RenderInstruction[] ri = renderTheme.matchElement(mElement, mTile.zoomLevel);
|
|
||||||
// renderWay(ri);
|
|
||||||
//}
|
|
||||||
|
|
||||||
protected void renderWay(RenderStyle[] ri) {
|
|
||||||
if (ri == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0, n = ri.length; i < n; i++)
|
|
||||||
ri[i].renderWay(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void renderNode(RenderStyle[] ri) {
|
|
||||||
if (ri == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0, n = ri.length; i < n; i++)
|
|
||||||
ri[i].renderNode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void clearState() {
|
|
||||||
mCurLineLayer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** RenderThemeCallback ***/
|
|
||||||
@Override
|
|
||||||
public void renderWay(Line line, int level) {
|
|
||||||
int numLayer = mCurLayer + level;
|
|
||||||
|
|
||||||
if (line.stipple == 0) {
|
|
||||||
if (line.outline && mCurLineLayer == null) {
|
|
||||||
log.error("BUG in theme: line must come before outline!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LineLayer ll = mTile.layers.getLineLayer(numLayer);
|
|
||||||
|
|
||||||
if (ll == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ll.line == null) {
|
|
||||||
ll.line = line;
|
|
||||||
ll.scale = line.fixed ? 1 : mLineScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.outline) {
|
|
||||||
ll.addOutline(mCurLineLayer);
|
|
||||||
} else {
|
|
||||||
ll.addLine(mElement);
|
|
||||||
|
|
||||||
// keep reference for outline layer(s)
|
|
||||||
mCurLineLayer = ll;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LineTexLayer ll = mTile.layers.getLineTexLayer(numLayer);
|
|
||||||
|
|
||||||
if (ll == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ll.line == null) {
|
|
||||||
ll.line = line;
|
|
||||||
|
|
||||||
float w = line.width;
|
|
||||||
if (!line.fixed)
|
|
||||||
w *= mLineScale;
|
|
||||||
|
|
||||||
ll.width = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
ll.addLine(mElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final static boolean USE_MESH_POLY = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderArea(Area area, int level) {
|
|
||||||
int numLayer = mCurLayer + level;
|
|
||||||
if (USE_MESH_POLY) {
|
|
||||||
MeshLayer l = mTile.layers.getMeshLayer(numLayer);
|
|
||||||
l.area = area;
|
|
||||||
l.addMesh(mElement);
|
|
||||||
} else {
|
|
||||||
PolygonLayer l = mTile.layers.getPolygonLayer(numLayer);
|
|
||||||
l.area = area;
|
|
||||||
l.addPolygon(mElement.points, mElement.index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderAreaText(Text text) {
|
|
||||||
// TODO place somewhere on polygon
|
|
||||||
String value = mElement.tags.getValue(text.textKey);
|
|
||||||
if (value == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PointF p = mElement.getPoint(0);
|
|
||||||
mTile.labels.push(TextItem.pool.get().set(p.x, p.y, value, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderPointText(Text text) {
|
|
||||||
String value = mElement.tags.getValue(text.textKey);
|
|
||||||
if (value == null)
|
|
||||||
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(Text text) {
|
|
||||||
String value = mElement.tags.getValue(text.textKey);
|
|
||||||
if (value == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (int i = 0, n = mElement.index.length; i < n; i++) {
|
|
||||||
int length = mElement.index[i];
|
|
||||||
if (length < 4)
|
|
||||||
break;
|
|
||||||
|
|
||||||
WayDecorator.renderText(mClipper, mElement.points, value, text,
|
|
||||||
offset, length, mTile);
|
|
||||||
offset += length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderPointCircle(Circle circle, int level) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderPointSymbol(Symbol symbol) {
|
|
||||||
if (symbol.texture == null) {
|
|
||||||
log.debug("missing symbol for " + mElement.tags.toString());
|
|
||||||
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(Symbol symbol) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderWaySymbol(LineSymbol symbol) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderExtrusion(Extrusion 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTileImage(Bitmap bitmap) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,16 +14,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.tiling.source;
|
package org.oscim.tiling.source;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.MapTile;
|
||||||
import org.oscim.tiling.ITileDataSink;
|
import org.oscim.tiling.ITileDataSink;
|
||||||
import org.oscim.tiling.ITileDataSource;
|
import org.oscim.tiling.ITileDataSource;
|
||||||
import org.oscim.tiling.source.ITileDecoder;
|
|
||||||
import org.oscim.tiling.source.LwHttp;
|
|
||||||
import org.oscim.tiling.source.UrlTileDataSource;
|
|
||||||
import org.oscim.tiling.source.UrlTileSource;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -43,22 +42,20 @@ public class UrlTileDataSource implements ITileDataSource {
|
|||||||
UrlTileSource getTileSource() {
|
UrlTileSource getTileSource() {
|
||||||
return mTileSource;
|
return mTileSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ITileDataSink mSink;
|
private ITileDataSink mSink;
|
||||||
private MapTile mTile;
|
private MapTile mTile;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(MapTile tile, ITileDataSink sink) {
|
public void query(MapTile tile, ITileDataSink sink) {
|
||||||
QueryResult result = QueryResult.SUCCESS;
|
|
||||||
mTile = tile;
|
mTile = tile;
|
||||||
mSink = sink;
|
mSink = sink;
|
||||||
try {
|
try {
|
||||||
mConn.sendRequest(tile, this);
|
mConn.sendRequest(tile, this);
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
result = QueryResult.FAILED;
|
sink.completed(FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void process(InputStream is) {
|
public void process(InputStream is) {
|
||||||
@ -72,10 +69,14 @@ public class UrlTileDataSource implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!win)
|
if (!win)
|
||||||
log.debug(mTile + " failed");
|
log.debug("{} failed", mTile);
|
||||||
|
|
||||||
mConn.requestCompleted();
|
mConn.requestCompleted();
|
||||||
mSink.completed(win);
|
|
||||||
|
mSink.completed(win ? SUCCESS : FAILED);
|
||||||
|
|
||||||
|
mTile = null;
|
||||||
|
mSink = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package org.oscim.tiling.source.bitmap;
|
package org.oscim.tiling.source.bitmap;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
import org.oscim.gdx.client.GwtBitmap;
|
import org.oscim.gdx.client.GwtBitmap;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.MapTile;
|
||||||
import org.oscim.tiling.ITileDataSink;
|
import org.oscim.tiling.ITileDataSink;
|
||||||
@ -48,7 +51,7 @@ public abstract class BitmapTileSource extends UrlTileSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(final MapTile tile, final ITileDataSink sink) {
|
public void query(final MapTile tile, final ITileDataSink sink) {
|
||||||
|
|
||||||
int pos = mTileSource.formatTilePath(tile, mRequestBuffer, 0);
|
int pos = mTileSource.formatTilePath(tile, mRequestBuffer, 0);
|
||||||
|
|
||||||
@ -73,7 +76,7 @@ public abstract class BitmapTileSource extends UrlTileSource {
|
|||||||
img.addLoadHandler(new LoadHandler() {
|
img.addLoadHandler(new LoadHandler() {
|
||||||
public void onLoad(LoadEvent event) {
|
public void onLoad(LoadEvent event) {
|
||||||
sink.setTileImage(new GwtBitmap(img));
|
sink.setTileImage(new GwtBitmap(img));
|
||||||
sink.completed(true);
|
sink.completed(SUCCESS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -81,11 +84,10 @@ public abstract class BitmapTileSource extends UrlTileSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(ErrorEvent event) {
|
public void onError(ErrorEvent event) {
|
||||||
sink.completed(false);
|
sink.completed(FAILED);
|
||||||
RootPanel.get().remove(img);
|
RootPanel.get().remove(img);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return QueryResult.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,7 +24,7 @@ public class JeoTileLayer extends BitmapTileLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean executeJob(MapTile tile) {
|
protected boolean loadTile(MapTile tile) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package org.oscim.layers;
|
package org.oscim.layers;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.TILE_NOT_FOUND;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -32,7 +36,7 @@ public class JeoTileSource extends TileSource {
|
|||||||
return new ITileDataSource() {
|
return new ITileDataSource() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(MapTile tile, ITileDataSink sink) {
|
public void query(MapTile tile, ITileDataSink sink) {
|
||||||
log.debug("query {}", tile);
|
log.debug("query {}", tile);
|
||||||
try {
|
try {
|
||||||
Tile t = mTileDataset.read(tile.zoomLevel, tile.tileX,
|
Tile t = mTileDataset.read(tile.zoomLevel, tile.tileX,
|
||||||
@ -40,20 +44,20 @@ public class JeoTileSource extends TileSource {
|
|||||||
(1 << tile.zoomLevel) - 1 - tile.tileY);
|
(1 << tile.zoomLevel) - 1 - tile.tileY);
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
log.debug("not found {}", tile);
|
log.debug("not found {}", tile);
|
||||||
return QueryResult.TILE_NOT_FOUND;
|
sink.completed(TILE_NOT_FOUND);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Bitmap b = CanvasAdapter.g.decodeBitmap(new ByteArrayInputStream(t.getData()));
|
Bitmap b = CanvasAdapter.g.decodeBitmap(new ByteArrayInputStream(t.getData()));
|
||||||
sink.setTileImage(b);
|
sink.setTileImage(b);
|
||||||
log.debug("success {}", tile);
|
log.debug("success {}", tile);
|
||||||
|
sink.completed(SUCCESS);
|
||||||
return QueryResult.SUCCESS;
|
return;
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
log.debug("fail {}", tile);
|
log.debug("fail {}", tile);
|
||||||
|
sink.completed(FAILED);
|
||||||
return QueryResult.FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,23 +16,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
|
import org.oscim.core.MapElement;
|
||||||
|
import org.oscim.tiling.ITileDataSink;
|
||||||
import org.oscim.utils.PausableThread;
|
import org.oscim.utils.PausableThread;
|
||||||
|
|
||||||
public abstract class TileLoader extends PausableThread {
|
public abstract class TileLoader extends PausableThread implements ITileDataSink {
|
||||||
private static int id;
|
private static int id;
|
||||||
|
|
||||||
private final String THREAD_NAME;
|
private final String THREAD_NAME;
|
||||||
private final TileManager mTileManager;
|
private final TileManager mTileManager;
|
||||||
|
|
||||||
|
/** currently processed tile */
|
||||||
|
protected MapTile mTile;
|
||||||
|
|
||||||
public TileLoader(TileManager tileManager) {
|
public TileLoader(TileManager tileManager) {
|
||||||
super();
|
super();
|
||||||
mTileManager = tileManager;
|
mTileManager = tileManager;
|
||||||
THREAD_NAME = "TileLoader" + (id++);
|
THREAD_NAME = "TileLoader" + (id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void cleanup();
|
protected abstract boolean loadTile(MapTile tile);
|
||||||
|
|
||||||
protected abstract boolean executeJob(MapTile tile);
|
|
||||||
|
|
||||||
public void go() {
|
public void go() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -42,29 +49,17 @@ public abstract class TileLoader extends PausableThread {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doWork() {
|
protected void doWork() {
|
||||||
|
mTile = mTileManager.getTileJob();
|
||||||
|
|
||||||
MapTile tile = mTileManager.getTileJob();
|
if (mTile == null)
|
||||||
|
|
||||||
if (tile == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean success = false;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
success = executeJob(tile);
|
loadTile(mTile);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
success = false;
|
completed(FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInterrupted())
|
|
||||||
success = false;
|
|
||||||
|
|
||||||
mTileManager.jobCompleted(tile, success);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void jobCompleted(MapTile tile, boolean success) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,4 +76,34 @@ public abstract class TileLoader extends PausableThread {
|
|||||||
protected boolean hasWork() {
|
protected boolean hasWork() {
|
||||||
return mTileManager.hasTileJobs();
|
return mTileManager.hasTileJobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void cleanup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to be called by TileDataSource when finished
|
||||||
|
* loading or on failure. MUST BE CALLED IN ANY CASE!
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void completed(QueryResult result) {
|
||||||
|
boolean success = (result == SUCCESS) && !isInterrupted();
|
||||||
|
|
||||||
|
mTileManager.jobCompleted(mTile, success);
|
||||||
|
mTile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by TileDataSource
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void process(MapElement element) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by TileDataSource
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setTileImage(Bitmap bitmap) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,6 +513,7 @@ public class TileManager {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!success || tile.state == CANCEL) {
|
if (!success || tile.state == CANCEL) {
|
||||||
|
log.debug("failed loading: {}", tile);
|
||||||
tile.clear();
|
tile.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
package org.oscim.layers.tile.bitmap;
|
package org.oscim.layers.tile.bitmap;
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.State.CANCEL;
|
import static org.oscim.layers.tile.MapTile.State.CANCEL;
|
||||||
@ -5,26 +21,22 @@ 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.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.MapElement;
|
|
||||||
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.TileLoader;
|
import org.oscim.layers.tile.TileLoader;
|
||||||
import org.oscim.layers.tile.TileManager;
|
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.ITileDataSink;
|
|
||||||
import org.oscim.tiling.ITileDataSource;
|
import org.oscim.tiling.ITileDataSource;
|
||||||
import org.oscim.tiling.ITileDataSource.QueryResult;
|
|
||||||
import org.oscim.tiling.TileSource;
|
import org.oscim.tiling.TileSource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class BitmapTileLoader extends TileLoader implements ITileDataSink {
|
public class BitmapTileLoader extends TileLoader {
|
||||||
|
|
||||||
protected static final Logger log = LoggerFactory.getLogger(BitmapTileLoader.class);
|
protected static final Logger log = LoggerFactory.getLogger(BitmapTileLoader.class);
|
||||||
|
|
||||||
private final ITileDataSource mTileDataSource;
|
private final ITileDataSource mTileDataSource;
|
||||||
private MapTile mTile;
|
|
||||||
|
|
||||||
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
|
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
|
||||||
super(tileManager);
|
super(tileManager);
|
||||||
@ -32,24 +44,17 @@ public class BitmapTileLoader extends TileLoader implements ITileDataSink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanup() {
|
protected boolean loadTile(MapTile tile) {
|
||||||
mTile = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean executeJob(MapTile tile) {
|
|
||||||
mTile = tile;
|
|
||||||
QueryResult result = null;
|
|
||||||
try {
|
try {
|
||||||
result = mTileDataSource.executeQuery(tile, this);
|
mTileDataSource.query(tile, this);
|
||||||
} catch (CancellationException e) {
|
} catch (CancellationException e) {
|
||||||
log.debug("{} was canceled", mTile);
|
log.debug("{} was canceled", tile);
|
||||||
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("{} {}", mTile, e.getMessage());
|
log.debug("{} {}", tile, e.getMessage());
|
||||||
} finally {
|
return false;
|
||||||
mTile = null;
|
|
||||||
}
|
}
|
||||||
return result == QueryResult.SUCCESS;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,12 +69,6 @@ public class BitmapTileLoader extends TileLoader implements ITileDataSink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(MapElement element) {
|
public void cleanup() {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed(boolean success) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public class TestTileLayer extends TileLayer {
|
|||||||
Line mLineStyle = new Line(Color.BLUE, 2f, Cap.ROUND);
|
Line mLineStyle = new Line(Color.BLUE, 2f, Cap.ROUND);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean executeJob(MapTile tile) {
|
public boolean loadTile(MapTile tile) {
|
||||||
log.debug("load tile " + tile);
|
log.debug("load tile " + tile);
|
||||||
tile.layers = new ElementLayers();
|
tile.layers = new ElementLayers();
|
||||||
|
|
||||||
|
@ -48,14 +48,11 @@ import org.oscim.theme.styles.LineSymbol;
|
|||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.theme.styles.Symbol;
|
import org.oscim.theme.styles.Symbol;
|
||||||
import org.oscim.theme.styles.Text;
|
import org.oscim.theme.styles.Text;
|
||||||
import org.oscim.tiling.ITileDataSink;
|
|
||||||
import org.oscim.tiling.ITileDataSource;
|
import org.oscim.tiling.ITileDataSource;
|
||||||
import org.oscim.tiling.ITileDataSource.QueryResult;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class VectorTileLoader extends TileLoader implements IRenderTheme.Callback,
|
public class VectorTileLoader extends TileLoader implements IRenderTheme.Callback {
|
||||||
ITileDataSink {
|
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger(VectorTileLoader.class);
|
static final Logger log = LoggerFactory.getLogger(VectorTileLoader.class);
|
||||||
|
|
||||||
@ -71,9 +68,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
/** current TileDataSource used by this MapTileLoader */
|
/** current TileDataSource used by this MapTileLoader */
|
||||||
protected ITileDataSource mTileDataSource;
|
protected ITileDataSource mTileDataSource;
|
||||||
|
|
||||||
/** currently processed tile */
|
|
||||||
protected MapTile mTile;
|
|
||||||
|
|
||||||
/** currently processed MapElement */
|
/** currently processed MapElement */
|
||||||
protected MapElement mElement;
|
protected MapElement mElement;
|
||||||
|
|
||||||
@ -106,7 +100,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean executeJob(MapTile tile) {
|
public boolean loadTile(MapTile tile) {
|
||||||
|
|
||||||
if (mTileDataSource == null) {
|
if (mTileDataSource == null) {
|
||||||
log.error("no tile source is set");
|
log.error("no tile source is set");
|
||||||
@ -118,31 +112,34 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
if (mLineScale < 1)
|
if (mLineScale < 1)
|
||||||
mLineScale = 1;
|
mLineScale = 1;
|
||||||
|
|
||||||
// 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)));
|
||||||
|
|
||||||
mTile = tile;
|
tile.layers = new ElementLayers();
|
||||||
mTile.layers = new ElementLayers();
|
|
||||||
QueryResult result = null;
|
|
||||||
try {
|
try {
|
||||||
// query database, which calls 'process' callback
|
/* query data source, which calls process() callback */
|
||||||
result = mTileDataSource.executeQuery(mTile, this);
|
mTileDataSource.query(tile, this);
|
||||||
} catch (CancellationException e) {
|
} catch (CancellationException e) {
|
||||||
log.debug("{} was canceled", mTile);
|
log.debug("{} was canceled", tile);
|
||||||
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("{} {}", mTile, e.getMessage());
|
log.debug("{} {}", tile, e.getMessage());
|
||||||
} finally {
|
return false;
|
||||||
mTile = null;
|
|
||||||
clearState();
|
|
||||||
}
|
}
|
||||||
return (result == QueryResult.SUCCESS);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completed(QueryResult result) {
|
||||||
|
super.completed(result);
|
||||||
|
clearState();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int getValidLayer(int layer) {
|
protected static int getValidLayer(int layer) {
|
||||||
@ -254,8 +251,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
public void renderWay(Line line, int level) {
|
public void renderWay(Line line, int level) {
|
||||||
int numLayer = mCurLayer + level;
|
int numLayer = mCurLayer + level;
|
||||||
|
|
||||||
// line = line.getCurrent();
|
|
||||||
|
|
||||||
if (line.stipple == 0) {
|
if (line.stipple == 0) {
|
||||||
if (line.outline && mCurLineLayer == null) {
|
if (line.outline && mCurLineLayer == null) {
|
||||||
log.debug("missing line for outline! " + mElement.tags
|
log.debug("missing line for outline! " + mElement.tags
|
||||||
@ -395,7 +390,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderExtrusion(Extrusion extrusion, int level) {
|
public void renderExtrusion(Extrusion extrusion, int level) {
|
||||||
|
|
||||||
int height = 0;
|
int height = 0;
|
||||||
int minHeight = 0;
|
int minHeight = 0;
|
||||||
|
|
||||||
@ -424,13 +418,6 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
|
|||||||
l.add(mElement, height, minHeight);
|
l.add(mElement, height, minHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* used for event-driven loading by html backend
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void completed(boolean success) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTileImage(Bitmap bitmap) {
|
public void setTileImage(Bitmap bitmap) {
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import org.oscim.core.MapElement;
|
|||||||
* MapDatabase callback (implemented by MapTileLoader)
|
* MapDatabase callback (implemented by MapTileLoader)
|
||||||
* .
|
* .
|
||||||
* NOTE: MapElement passed belong to the caller! i.e. dont hold
|
* NOTE: MapElement passed belong to the caller! i.e. dont hold
|
||||||
* references to its arrays after callback function returns.
|
* references to any of its data after callback function returns.
|
||||||
*/
|
*/
|
||||||
public interface ITileDataSink {
|
public interface ITileDataSink {
|
||||||
|
|
||||||
@ -31,5 +31,12 @@ public interface ITileDataSink {
|
|||||||
|
|
||||||
void setTileImage(Bitmap bitmap);
|
void setTileImage(Bitmap bitmap);
|
||||||
|
|
||||||
void completed(boolean success);
|
void completed(QueryResult result);
|
||||||
|
|
||||||
|
public static enum QueryResult {
|
||||||
|
SUCCESS,
|
||||||
|
FAILED,
|
||||||
|
TILE_NOT_FOUND,
|
||||||
|
DELAYED,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package org.oscim.tiling;
|
|||||||
|
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.MapTile;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -33,17 +32,9 @@ public interface ITileDataSource {
|
|||||||
* the tile to read.
|
* the tile to read.
|
||||||
* @param mapDataSink
|
* @param mapDataSink
|
||||||
* the callback which handles the extracted map elements.
|
* the callback which handles the extracted map elements.
|
||||||
* @return true if successful
|
|
||||||
*/
|
*/
|
||||||
abstract QueryResult executeQuery(MapTile tile,
|
abstract void query(MapTile tile, ITileDataSink mapDataSink);
|
||||||
ITileDataSink mapDataSink);
|
|
||||||
|
|
||||||
abstract void destroy();
|
abstract void destroy();
|
||||||
|
|
||||||
public static enum QueryResult {
|
|
||||||
SUCCESS,
|
|
||||||
FAILED,
|
|
||||||
TILE_NOT_FOUND,
|
|
||||||
DELAYED,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.tiling.source;
|
package org.oscim.tiling.source;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
@ -24,10 +27,10 @@ import java.net.UnknownHostException;
|
|||||||
|
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.MapTile;
|
||||||
import org.oscim.tiling.ITileCache;
|
import org.oscim.tiling.ITileCache;
|
||||||
import org.oscim.tiling.ITileDataSink;
|
|
||||||
import org.oscim.tiling.ITileDataSource;
|
|
||||||
import org.oscim.tiling.ITileCache.TileReader;
|
import org.oscim.tiling.ITileCache.TileReader;
|
||||||
import org.oscim.tiling.ITileCache.TileWriter;
|
import org.oscim.tiling.ITileCache.TileWriter;
|
||||||
|
import org.oscim.tiling.ITileDataSink;
|
||||||
|
import org.oscim.tiling.ITileDataSource;
|
||||||
import org.oscim.utils.IOUtils;
|
import org.oscim.utils.IOUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -48,7 +51,7 @@ public class UrlTileDataSource implements ITileDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(MapTile tile, ITileDataSink sink) {
|
public void query(MapTile tile, ITileDataSink sink) {
|
||||||
ITileCache cache = mTileSource.tileCache;
|
ITileCache cache = mTileSource.tileCache;
|
||||||
|
|
||||||
if (mUseCache) {
|
if (mUseCache) {
|
||||||
@ -56,9 +59,10 @@ public class UrlTileDataSource implements ITileDataSource {
|
|||||||
if (c != null) {
|
if (c != null) {
|
||||||
InputStream is = c.getInputStream();
|
InputStream is = c.getInputStream();
|
||||||
try {
|
try {
|
||||||
if (mTileDecoder.decode(tile, sink, is))
|
if (mTileDecoder.decode(tile, sink, is)) {
|
||||||
return QueryResult.SUCCESS;
|
sink.completed(SUCCESS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.debug("{} Cache read: {}", tile, e);
|
log.debug("{} Cache read: {}", tile, e);
|
||||||
} finally {
|
} finally {
|
||||||
@ -95,7 +99,7 @@ public class UrlTileDataSource implements ITileDataSource {
|
|||||||
if (cacheWriter != null)
|
if (cacheWriter != null)
|
||||||
cacheWriter.complete(success);
|
cacheWriter.complete(success);
|
||||||
}
|
}
|
||||||
return success ? QueryResult.SUCCESS : QueryResult.FAILED;
|
sink.completed(success ? SUCCESS : FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.tiling.source.mapfile;
|
package org.oscim.tiling.source.mapfile;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
@ -142,14 +145,13 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
|
|
||||||
private final MapFileTileSource mTileSource;
|
private final MapFileTileSource mTileSource;
|
||||||
|
|
||||||
//private int mReductionCnt;
|
|
||||||
//private int mSkipPoly;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(MapTile tile, ITileDataSink mapDataSink) {
|
public void query(MapTile tile, ITileDataSink sink) {
|
||||||
|
|
||||||
if (mTileSource.fileHeader == null)
|
if (mTileSource.fileHeader == null) {
|
||||||
return QueryResult.FAILED;
|
sink.completed(FAILED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mIntBuffer == null)
|
if (mIntBuffer == null)
|
||||||
mIntBuffer = new int[MAXIMUM_WAY_NODES_SEQUENCE_LENGTH * 2];
|
mIntBuffer = new int[MAXIMUM_WAY_NODES_SEQUENCE_LENGTH * 2];
|
||||||
@ -172,11 +174,6 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
minLon = (int) (Math.abs(MercatorProjection.toLongitude(tile.x + size)
|
minLon = (int) (Math.abs(MercatorProjection.toLongitude(tile.x + size)
|
||||||
- MercatorProjection.toLongitude(tile.x)) * 1e6) / simplify;
|
- MercatorProjection.toLongitude(tile.x)) * 1e6) / simplify;
|
||||||
|
|
||||||
//mReductionCnt = 0;
|
|
||||||
//mSkipPoly = 0;
|
|
||||||
|
|
||||||
//log.debug("simplify by " + minLat + "/" + minLon);
|
|
||||||
|
|
||||||
QueryParameters queryParameters = new QueryParameters();
|
QueryParameters queryParameters = new QueryParameters();
|
||||||
queryParameters.queryZoomLevel =
|
queryParameters.queryZoomLevel =
|
||||||
mTileSource.fileHeader.getQueryZoomLevel(tile.zoomLevel);
|
mTileSource.fileHeader.getQueryZoomLevel(tile.zoomLevel);
|
||||||
@ -189,20 +186,20 @@ public class MapDatabase implements ITileDataSource {
|
|||||||
log.warn("no sub-file for zoom level: "
|
log.warn("no sub-file for zoom level: "
|
||||||
+ queryParameters.queryZoomLevel);
|
+ queryParameters.queryZoomLevel);
|
||||||
|
|
||||||
return QueryResult.FAILED;
|
sink.completed(FAILED);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryCalculations.calculateBaseTiles(queryParameters, tile, subFileParameter);
|
QueryCalculations.calculateBaseTiles(queryParameters, tile, subFileParameter);
|
||||||
QueryCalculations.calculateBlocks(queryParameters, subFileParameter);
|
QueryCalculations.calculateBlocks(queryParameters, subFileParameter);
|
||||||
processBlocks(mapDataSink, queryParameters, subFileParameter);
|
processBlocks(sink, queryParameters, subFileParameter);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(e.getMessage());
|
log.error(e.getMessage());
|
||||||
return QueryResult.FAILED;
|
sink.completed(FAILED);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.debug("reduced points " + mReductionCnt + " / polys " + mSkipPoly);
|
sink.completed(SUCCESS);
|
||||||
|
|
||||||
return QueryResult.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapDatabase(MapFileTileSource tileSource) throws IOException {
|
public MapDatabase(MapFileTileSource tileSource) throws IOException {
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.tiling.source.test;
|
package org.oscim.tiling.source.test;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||||
|
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
@ -74,8 +76,7 @@ public class TestTileSource extends TileSource {
|
|||||||
private boolean renderPlace = false;
|
private boolean renderPlace = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryResult executeQuery(MapTile tile,
|
public void query(MapTile tile, ITileDataSink sink) {
|
||||||
ITileDataSink mapDataSink) {
|
|
||||||
|
|
||||||
int size = Tile.SIZE;
|
int size = Tile.SIZE;
|
||||||
MapElement e = mElem;
|
MapElement e = mElem;
|
||||||
@ -107,7 +108,7 @@ public class TestTileSource extends TileSource {
|
|||||||
|
|
||||||
e.setLayer(0);
|
e.setLayer(0);
|
||||||
e.tags.set(mTags);
|
e.tags.set(mTags);
|
||||||
mapDataSink.process(e);
|
sink.process(e);
|
||||||
|
|
||||||
if (renderWays) {
|
if (renderWays) {
|
||||||
e.clear();
|
e.clear();
|
||||||
@ -128,7 +129,7 @@ public class TestTileSource extends TileSource {
|
|||||||
e.addPoint(size / 2, size / 2 + size);
|
e.addPoint(size / 2, size / 2 + size);
|
||||||
|
|
||||||
// //e.setLayer(mTagsWay, 0);
|
// //e.setLayer(mTagsWay, 0);
|
||||||
mapDataSink.process(e);
|
sink.process(e);
|
||||||
|
|
||||||
e.clear();
|
e.clear();
|
||||||
// left-top to center
|
// left-top to center
|
||||||
@ -146,7 +147,7 @@ public class TestTileSource extends TileSource {
|
|||||||
|
|
||||||
e.setLayer(1);
|
e.setLayer(1);
|
||||||
e.tags.set(mTagsWay);
|
e.tags.set(mTagsWay);
|
||||||
mapDataSink.process(e);
|
sink.process(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderBoundary) {
|
if (renderBoundary) {
|
||||||
@ -162,7 +163,7 @@ public class TestTileSource extends TileSource {
|
|||||||
|
|
||||||
e.setLayer(1);
|
e.setLayer(1);
|
||||||
e.tags.set(mTagsBoundary);
|
e.tags.set(mTagsBoundary);
|
||||||
mapDataSink.process(e);
|
sink.process(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderPlace) {
|
if (renderPlace) {
|
||||||
@ -172,12 +173,10 @@ public class TestTileSource extends TileSource {
|
|||||||
|
|
||||||
mTagsPlace[1] = new Tag("name", tile.toString());
|
mTagsPlace[1] = new Tag("name", tile.toString());
|
||||||
e.tags.set(mTagsPlace);
|
e.tags.set(mTagsPlace);
|
||||||
mapDataSink.process(e);
|
sink.process(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapDataSink.completed(true);
|
sink.completed(SUCCESS);
|
||||||
|
|
||||||
return QueryResult.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user