reorder TileGenerator functions
This commit is contained in:
parent
49055f2cc2
commit
74ca621de0
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 Hannes Janetzek
|
* Copyright 2012, 2013 OpenScienceMap
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* 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
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@ -19,7 +19,6 @@ import static org.oscim.generator.JobTile.STATE_NONE;
|
|||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.core.WebMercator;
|
|
||||||
import org.oscim.database.IMapDatabase;
|
import org.oscim.database.IMapDatabase;
|
||||||
import org.oscim.database.IMapDatabaseCallback;
|
import org.oscim.database.IMapDatabaseCallback;
|
||||||
import org.oscim.database.QueryResult;
|
import org.oscim.database.QueryResult;
|
||||||
@ -44,15 +43,20 @@ import android.graphics.Paint;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @author Hannes Janetzek
|
||||||
|
* @note
|
||||||
|
* 1. MapWorker calls TileGenerator.execute to load a tile.
|
||||||
|
* 2. The tile data will be loaded from current MapDatabase
|
||||||
|
* 3. MapDatabase calls the IMapDatabaseCallback functions
|
||||||
|
* implemented by TileGenerator for WAY and POI items.
|
||||||
|
* 4. these callbacks then call RenderTheme to get the matching style.
|
||||||
|
* 5. RenderTheme calls IRenderCallback functions with style information
|
||||||
|
* 6. Styled items become added to MapTile.layers... roughly
|
||||||
*/
|
*/
|
||||||
public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
||||||
|
|
||||||
private static String TAG = TileGenerator.class.getName();
|
private static String TAG = TileGenerator.class.getName();
|
||||||
|
|
||||||
private static final double PI180 = (Math.PI / 180) / 1000000.0;
|
|
||||||
private static final double PIx4 = Math.PI * 4;
|
|
||||||
|
|
||||||
private static final double STROKE_INCREASE = Math.sqrt(2);
|
private static final double STROKE_INCREASE = Math.sqrt(2);
|
||||||
private static final byte LAYERS = 11;
|
private static final byte LAYERS = 11;
|
||||||
|
|
||||||
@ -82,12 +86,11 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
|
|
||||||
private float mStrokeScale = 1.0f;
|
private float mStrokeScale = 1.0f;
|
||||||
|
|
||||||
private boolean mProjected;
|
|
||||||
private float mSimplify;
|
|
||||||
|
|
||||||
private RenderInstruction[] mRenderInstructions = null;
|
private RenderInstruction[] mRenderInstructions = null;
|
||||||
|
|
||||||
private final String TAG_WATER = "water".intern();
|
//private final String TAG_WATER = "water".intern();
|
||||||
|
private final String TAG_BUILDING = "building".intern();
|
||||||
|
|
||||||
private final MapView mMapView;
|
private final MapView mMapView;
|
||||||
|
|
||||||
private final Tag[] debugTagBox = { new Tag("debug", "box") };
|
private final Tag[] debugTagBox = { new Tag("debug", "box") };
|
||||||
@ -99,6 +102,14 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
|
|
||||||
private float mProjectionScaleFactor;
|
private float mProjectionScaleFactor;
|
||||||
|
|
||||||
|
private float mPoiX, mPoiY;
|
||||||
|
|
||||||
|
private Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
|
||||||
|
private Tag mTagName;
|
||||||
|
|
||||||
|
private boolean mDebugDrawPolygons;
|
||||||
|
boolean mDebugDrawUnmatched;
|
||||||
|
|
||||||
public static void setRenderTheme(RenderTheme theme) {
|
public static void setRenderTheme(RenderTheme theme) {
|
||||||
renderTheme = theme;
|
renderTheme = theme;
|
||||||
}
|
}
|
||||||
@ -108,64 +119,166 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
* the MapView
|
* the MapView
|
||||||
*/
|
*/
|
||||||
public TileGenerator(MapView mapView) {
|
public TileGenerator(MapView mapView) {
|
||||||
Log.d(TAG, "init TileGenerator");
|
//Log.d(TAG, "init TileGenerator");
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float mPoiX = 256;
|
public void cleanup() {
|
||||||
private float mPoiY = 256;
|
}
|
||||||
|
|
||||||
private Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
|
public boolean executeJob(JobTile jobTile) {
|
||||||
private Tag mTagName;
|
MapTile tile;
|
||||||
|
|
||||||
private void filterTags(Tag[] tags) {
|
if (mMapDatabase == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tile = mCurrentTile = (MapTile) jobTile;
|
||||||
|
DebugSettings debugSettings = mMapView.getDebugSettings();
|
||||||
|
|
||||||
|
mDebugDrawPolygons = !debugSettings.mDisablePolygons;
|
||||||
|
mDebugDrawUnmatched = debugSettings.mDrawUnmatchted;
|
||||||
|
|
||||||
|
if (tile.layers != null) {
|
||||||
|
// should be fixed now.
|
||||||
|
Log.d(TAG, "XXX tile already loaded " + tile + " " + tile.state);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLevels = TileGenerator.renderTheme.getLevels();
|
||||||
|
|
||||||
|
// limit stroke scale at z=17
|
||||||
|
// if (tile.zoomLevel < STROKE_MAX_ZOOM_LEVEL)
|
||||||
|
setScaleStrokeWidth(tile.zoomLevel);
|
||||||
|
// else
|
||||||
|
// setScaleStrokeWidth(STROKE_MAX_ZOOM_LEVEL);
|
||||||
|
|
||||||
|
// acount for area changes with latitude
|
||||||
|
mProjectionScaleFactor = 0.5f + 0.5f * (
|
||||||
|
(float) Math.sin(Math.abs(MercatorProjection
|
||||||
|
.pixelYToLatitude(tile.pixelY, tile.zoomLevel)) * (Math.PI / 180)));
|
||||||
|
|
||||||
|
mLayers = new Layers();
|
||||||
|
|
||||||
|
if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) {
|
||||||
|
//Log.d(TAG, "Failed loading: " + tile);
|
||||||
|
mLayers.clear();
|
||||||
|
mLayers = null;
|
||||||
|
TextItem.release(mLabels);
|
||||||
|
mLabels = null;
|
||||||
|
|
||||||
|
// FIXME add STATE_FAILED?
|
||||||
|
tile.state = STATE_NONE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugSettings.mDrawTileFrames) {
|
||||||
|
mTagName = new Tag("name", tile.toString(), false);
|
||||||
|
mPoiX = Tile.TILE_SIZE >> 1;
|
||||||
|
mPoiY = 10;
|
||||||
|
TileGenerator.renderTheme.matchNode(this, debugTagWay, (byte) 0);
|
||||||
|
|
||||||
|
mIndices = debugBoxIndex;
|
||||||
|
mCoords = debugBoxCoords;
|
||||||
|
mDrawingLayer = 10 * mLevels;
|
||||||
|
TileGenerator.renderTheme.matchWay(this, debugTagBox, (byte) 0, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.layers = mLayers;
|
||||||
|
tile.labels = mLabels;
|
||||||
|
mLayers = null;
|
||||||
|
mLabels = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte getValidLayer(byte layer) {
|
||||||
|
if (layer < 0) {
|
||||||
|
return 0;
|
||||||
|
} else if (layer >= LAYERS) {
|
||||||
|
return LAYERS - 1;
|
||||||
|
} else {
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the scale stroke factor for the given zoom level.
|
||||||
|
* @param zoomLevel
|
||||||
|
* the zoom level for which the scale stroke factor should be
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
private void setScaleStrokeWidth(byte zoomLevel) {
|
||||||
|
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
|
||||||
|
mStrokeScale = (float) Math.pow(STROKE_INCREASE, zoomLevelDiff);
|
||||||
|
if (mStrokeScale < 1)
|
||||||
|
mStrokeScale = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapDatabase(IMapDatabase mapDatabase) {
|
||||||
|
if (mMapDatabase != null)
|
||||||
|
mMapDatabase.close();
|
||||||
|
|
||||||
|
mMapDatabase = mapDatabase;
|
||||||
|
//mMapProjection = mMapDatabase.getMapProjection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMapDatabase getMapDatabase() {
|
||||||
|
return mMapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean filterTags(Tag[] tags) {
|
||||||
for (int i = 0; i < tags.length; i++) {
|
for (int i = 0; i < tags.length; i++) {
|
||||||
// Log.d(TAG, "check tag: " + tags[i]);
|
String key = tags[i].key;
|
||||||
if (tags[i].key == Tag.TAG_KEY_NAME) {
|
if (key == Tag.TAG_KEY_NAME) {
|
||||||
mTagName = tags[i];
|
mTagName = tags[i];
|
||||||
tags[i] = mTagEmptyName;
|
tags[i] = mTagEmptyName;
|
||||||
|
} else if (mCurrentTile.zoomLevel >= 17 &&
|
||||||
|
key == TAG_BUILDING) {
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private RenderInstruction[] mNodeRenderInstructions;
|
// ---------------- MapDatabaseCallback -----------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderPointOfInterest(byte layer, Tag[] tags, float latitude,
|
public void renderPointOfInterest(byte layer, Tag[] tags, float latitude,
|
||||||
float longitude) {
|
float longitude) {
|
||||||
|
|
||||||
|
// reset state
|
||||||
mTagName = null;
|
mTagName = null;
|
||||||
|
|
||||||
if (mMapProjection != null) {
|
//if (mMapProjection != null) {
|
||||||
long x = mCurrentTile.pixelX;
|
// long x = mCurrentTile.pixelX;
|
||||||
long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
// long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
||||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
// long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||||
|
//
|
||||||
double divx, divy;
|
// double divx, divy;
|
||||||
long dx = (x - (z >> 1));
|
// long dx = (x - (z >> 1));
|
||||||
long dy = (y - (z >> 1));
|
// long dy = (y - (z >> 1));
|
||||||
|
//
|
||||||
if (mMapProjection == WebMercator.NAME) {
|
// if (mMapProjection == WebMercator.NAME) {
|
||||||
double div = WebMercator.f900913 / (z >> 1);
|
// double div = WebMercator.f900913 / (z >> 1);
|
||||||
// divy = f900913 / (z >> 1);
|
// // divy = f900913 / (z >> 1);
|
||||||
mPoiX = (float) (longitude / div - dx);
|
// mPoiX = (float) (longitude / div - dx);
|
||||||
mPoiY = (float) (latitude / div + dy);
|
// mPoiY = (float) (latitude / div + dy);
|
||||||
} else {
|
// } else {
|
||||||
divx = 180000000.0 / (z >> 1);
|
// divx = 180000000.0 / (z >> 1);
|
||||||
divy = z / PIx4;
|
// divy = z / PIx4;
|
||||||
mPoiX = (float) (longitude / divx - dx);
|
// mPoiX = (float) (longitude / divx - dx);
|
||||||
double sinLat = Math.sin(latitude * PI180);
|
// double sinLat = Math.sin(latitude * PI180);
|
||||||
mPoiY = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
|
// mPoiY = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
|
||||||
|
//
|
||||||
// TODO remove this, only used for mapsforge maps
|
// // TODO remove this, only used for mapsforge maps
|
||||||
if (mPoiX < -10 || mPoiX > Tile.TILE_SIZE + 10 || mPoiY < -10
|
// if (mPoiX < -10 || mPoiX > Tile.TILE_SIZE + 10 || mPoiY < -10
|
||||||
|| mPoiY > Tile.TILE_SIZE + 10)
|
// || mPoiY > Tile.TILE_SIZE + 10)
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
} else {
|
//} else {
|
||||||
mPoiX = longitude;
|
mPoiX = longitude;
|
||||||
mPoiY = latitude;
|
mPoiY = latitude;
|
||||||
}
|
//}
|
||||||
|
|
||||||
// remove tags that should not be cached in Rendertheme
|
// remove tags that should not be cached in Rendertheme
|
||||||
filterTags(tags);
|
filterTags(tags);
|
||||||
@ -175,53 +288,45 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
TileGenerator.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
|
TileGenerator.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderWaterBackground() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean mClosed;
|
private boolean mClosed;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWay(byte layer, Tag[] tags, float[] coords, short[] indices,
|
public void renderWay(byte layer, Tag[] tags, float[] coords, short[] indices,
|
||||||
boolean closed) {
|
boolean closed) {
|
||||||
|
|
||||||
|
// reset state
|
||||||
mTagName = null;
|
mTagName = null;
|
||||||
mProjected = false;
|
|
||||||
mCurLineLayer = null;
|
mCurLineLayer = null;
|
||||||
|
|
||||||
mClosed = closed;
|
mClosed = closed;
|
||||||
|
|
||||||
|
// replace tags that should not be cached in Rendertheme (e.g. name)
|
||||||
|
if (!filterTags(tags))
|
||||||
|
return;
|
||||||
|
|
||||||
mDrawingLayer = getValidLayer(layer) * mLevels;
|
mDrawingLayer = getValidLayer(layer) * mLevels;
|
||||||
mSimplify = 0.5f;
|
|
||||||
|
|
||||||
if (closed) {
|
// mProjected = false;
|
||||||
if (mCurrentTile.zoomLevel < 14)
|
// mSimplify = 0.5f;
|
||||||
mSimplify = 0.5f;
|
// if (closed) {
|
||||||
else
|
// if (mCurrentTile.zoomLevel < 14)
|
||||||
mSimplify = 0.2f;
|
// mSimplify = 0.5f;
|
||||||
|
// else
|
||||||
if (tags.length == 1 && TAG_WATER == (tags[0].value))
|
// mSimplify = 0.2f;
|
||||||
mSimplify = 0;
|
// if (tags.length == 1 && TAG_WATER == (tags[0].value))
|
||||||
}
|
// mSimplify = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
mCoords = coords;
|
mCoords = coords;
|
||||||
mIndices = indices;
|
mIndices = indices;
|
||||||
|
|
||||||
// remove tags that should not be cached in Rendertheme
|
|
||||||
filterTags(tags);
|
|
||||||
|
|
||||||
// if (mRenderInstructions != null) {
|
|
||||||
// for (int i = 0, n = mRenderInstructions.length; i < n; i++)
|
|
||||||
// mRenderInstructions[i].renderWay(this, tags);
|
|
||||||
// }
|
|
||||||
|
|
||||||
mRenderInstructions = TileGenerator.renderTheme.matchWay(this, tags,
|
mRenderInstructions = TileGenerator.renderTheme.matchWay(this, tags,
|
||||||
(byte) (mCurrentTile.zoomLevel + 0),
|
(byte) (mCurrentTile.zoomLevel + 0), closed, true);
|
||||||
closed, true);
|
|
||||||
|
|
||||||
if (mRenderInstructions == null && mDebugDrawUnmatched)
|
if (mRenderInstructions == null && mDebugDrawUnmatched)
|
||||||
debugUnmatched(closed, tags);
|
debugUnmatched(closed, tags);
|
||||||
|
|
||||||
|
mCurLineLayer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void debugUnmatched(boolean closed, Tag[] tags) {
|
private void debugUnmatched(boolean closed, Tag[] tags) {
|
||||||
@ -232,14 +337,81 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
mTagName = new Tag("name", tags[0].key + ":" + tags[0].value, false);
|
mTagName = new Tag("name", tags[0].key + ":" + tags[0].value, false);
|
||||||
|
|
||||||
if (closed) {
|
if (closed) {
|
||||||
mRenderInstructions = TileGenerator.renderTheme.matchWay(this, debugTagArea,
|
TileGenerator.renderTheme.matchWay(this, debugTagArea, (byte) 0, true, true);
|
||||||
(byte) 0, true, true);
|
|
||||||
} else {
|
} else {
|
||||||
mRenderInstructions = TileGenerator.renderTheme.matchWay(this, debugTagWay,
|
TileGenerator.renderTheme.matchWay(this, debugTagWay, (byte) 0, true, true);
|
||||||
(byte) 0, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderWaterBackground() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkWay(Tag[] tags, boolean closed) {
|
||||||
|
|
||||||
|
mRenderInstructions = TileGenerator.renderTheme.matchWay(this, tags,
|
||||||
|
(byte) (mCurrentTile.zoomLevel + 0), closed, false);
|
||||||
|
|
||||||
|
return mRenderInstructions != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------- RenderThemeCallback -----------------
|
||||||
|
@Override
|
||||||
|
public void renderWay(Line line, int level) {
|
||||||
|
// projectToTile();
|
||||||
|
|
||||||
|
if (line.outline && mCurLineLayer == null) {
|
||||||
|
// TODO fix this in RenderTheme
|
||||||
|
Log.e(TAG, "theme issue, cannot add outline: line must come before outline!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int numLayer = (mDrawingLayer * 2) + level;
|
||||||
|
|
||||||
|
LineLayer lineLayer = (LineLayer) mLayers.getLayer(numLayer, Layer.LINE);
|
||||||
|
if (lineLayer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lineLayer.line == null) {
|
||||||
|
lineLayer.line = line;
|
||||||
|
|
||||||
|
float w = line.width;
|
||||||
|
if (!line.fixed) {
|
||||||
|
w *= mStrokeScale;
|
||||||
|
w *= mProjectionScaleFactor;
|
||||||
|
}
|
||||||
|
lineLayer.width = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.outline) {
|
||||||
|
lineLayer.addOutline(mCurLineLayer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineLayer.addLine(mCoords, mIndices, mClosed);
|
||||||
|
mCurLineLayer = lineLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderArea(Area area, int level) {
|
||||||
|
if (!mDebugDrawPolygons)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if (!mProjected && !projectToTile())
|
||||||
|
// return;
|
||||||
|
|
||||||
|
int numLayer = mDrawingLayer + level;
|
||||||
|
|
||||||
|
PolygonLayer layer = (PolygonLayer) mLayers.getLayer(numLayer, Layer.POLYGON);
|
||||||
|
if (layer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (layer.area == null)
|
||||||
|
layer.area = area;
|
||||||
|
|
||||||
|
layer.addPolygon(mCoords, mIndices);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAreaCaption(Text text) {
|
public void renderAreaCaption(Text text) {
|
||||||
// Log.d(TAG, "renderAreaCaption: " + mTagName);
|
// Log.d(TAG, "renderAreaCaption: " + mTagName);
|
||||||
@ -287,16 +459,8 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderAreaSymbol(Bitmap symbol) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderPointOfInterestCircle(float radius, Paint fill, int level) {
|
public void renderPointOfInterestCircle(float radius, Paint fill, int level) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -318,256 +482,90 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWay(Line line, int level) {
|
public void renderAreaSymbol(Bitmap symbol) {
|
||||||
projectToTile();
|
|
||||||
|
|
||||||
if (line.outline && mCurLineLayer == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int numLayer = (mDrawingLayer * 2) + level;
|
|
||||||
|
|
||||||
LineLayer lineLayer = (LineLayer) mLayers.getLayer(numLayer, Layer.LINE);
|
|
||||||
if (lineLayer == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (lineLayer.line == null) {
|
|
||||||
lineLayer.line = line;
|
|
||||||
|
|
||||||
float w = line.width;
|
|
||||||
if (!line.fixed) {
|
|
||||||
w *= mStrokeScale;
|
|
||||||
w *= mProjectionScaleFactor;
|
|
||||||
}
|
|
||||||
lineLayer.width = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.outline) {
|
|
||||||
lineLayer.addOutline(mCurLineLayer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCurLineLayer = lineLayer;
|
|
||||||
|
|
||||||
lineLayer.addLine(mCoords, mIndices, mClosed);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderArea(Area area, int level) {
|
|
||||||
if (!mDebugDrawPolygons)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!mProjected && !projectToTile())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int numLayer = mDrawingLayer + level;
|
|
||||||
|
|
||||||
PolygonLayer layer = (PolygonLayer) mLayers.getLayer(numLayer, Layer.POLYGON);
|
|
||||||
if (layer == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (layer.area == null)
|
|
||||||
layer.area = area;
|
|
||||||
|
|
||||||
layer.addPolygon(mCoords, mIndices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWaySymbol(Bitmap symbol, boolean alignCenter, boolean repeat) {
|
public void renderWaySymbol(Bitmap symbol, boolean alignCenter, boolean repeat) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup() {
|
// // TODO move this to Projection classes
|
||||||
// TODO Auto-generated method stub
|
//
|
||||||
|
// private String mMapProjection;
|
||||||
}
|
// private static final double PI180 = (Math.PI / 180) / 1000000.0;
|
||||||
|
// private static final double PIx4 = Math.PI * 4;
|
||||||
private boolean mDebugDrawPolygons;
|
// private boolean mProjected;
|
||||||
boolean mDebugDrawUnmatched;
|
// private float mSimplify;
|
||||||
|
//
|
||||||
public boolean executeJob(JobTile jobTile) {
|
// private boolean projectToTile() {
|
||||||
MapTile tile;
|
// if (mProjected || mMapProjection == null)
|
||||||
|
// return true;
|
||||||
if (mMapDatabase == null)
|
//
|
||||||
return false;
|
// boolean useWebMercator = false;
|
||||||
|
//
|
||||||
tile = mCurrentTile = (MapTile) jobTile;
|
// if (mMapProjection == WebMercator.NAME)
|
||||||
DebugSettings debugSettings = mMapView.getDebugSettings();
|
// useWebMercator = true;
|
||||||
|
//
|
||||||
mDebugDrawPolygons = !debugSettings.mDisablePolygons;
|
// float[] coords = mCoords;
|
||||||
mDebugDrawUnmatched = debugSettings.mDrawUnmatchted;
|
//
|
||||||
|
// long x = mCurrentTile.pixelX;
|
||||||
if (tile.layers != null) {
|
// long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
||||||
// should be fixed now.
|
// long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||||
Log.d(TAG, "XXX tile already loaded "
|
// float min = mSimplify;
|
||||||
+ tile + " " + tile.state);
|
//
|
||||||
return false;
|
// double divx, divy = 0;
|
||||||
}
|
// long dx = (x - (z >> 1));
|
||||||
|
// long dy = (y - (z >> 1));
|
||||||
mLevels = TileGenerator.renderTheme.getLevels();
|
//
|
||||||
|
// if (useWebMercator) {
|
||||||
// limit stroke scale at z=17
|
// divx = WebMercator.f900913 / (z >> 1);
|
||||||
// if (tile.zoomLevel < STROKE_MAX_ZOOM_LEVEL)
|
// } else {
|
||||||
setScaleStrokeWidth(tile.zoomLevel);
|
// divx = 180000000.0 / (z >> 1);
|
||||||
// else
|
// divy = z / PIx4;
|
||||||
// setScaleStrokeWidth(STROKE_MAX_ZOOM_LEVEL);
|
// }
|
||||||
|
//
|
||||||
// acount for area changes with latitude
|
// for (int pos = 0, outPos = 0, i = 0, m = mIndices.length; i < m; i++) {
|
||||||
mProjectionScaleFactor = 0.5f + 0.5f * (
|
// int len = mIndices[i];
|
||||||
(float) Math.sin(Math.abs(MercatorProjection
|
// if (len == 0)
|
||||||
.pixelYToLatitude(tile.pixelY, tile.zoomLevel)) * (Math.PI / 180)));
|
// continue;
|
||||||
|
// if (len < 0)
|
||||||
mLayers = new Layers();
|
// break;
|
||||||
|
//
|
||||||
if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) {
|
// int cnt = 0;
|
||||||
//Log.d(TAG, "Failed loading: " + tile);
|
// float lat, lon, prevLon = 0, prevLat = 0;
|
||||||
mLayers.clear();
|
//
|
||||||
mLayers = null;
|
// for (int end = pos + len; pos < end; pos += 2) {
|
||||||
mLabels = null;
|
//
|
||||||
mCurLineLayer = null;
|
// if (useWebMercator) {
|
||||||
|
// lon = (float) (coords[pos] / divx - dx);
|
||||||
// FIXME add STATE_FAILED?
|
// lat = (float) (coords[pos + 1] / divx + dy);
|
||||||
tile.state = STATE_NONE;
|
// } else {
|
||||||
return false;
|
// lon = (float) ((coords[pos]) / divx - dx);
|
||||||
}
|
// double sinLat = Math.sin(coords[pos + 1] * PI180);
|
||||||
|
// lat = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
|
||||||
if (debugSettings.mDrawTileFrames) {
|
// }
|
||||||
mTagName = new Tag("name", tile.toString(), false);
|
//
|
||||||
mPoiX = Tile.TILE_SIZE >> 1;
|
// if (cnt != 0) {
|
||||||
mPoiY = 10;
|
// // drop small distance intermediate nodes
|
||||||
TileGenerator.renderTheme.matchNode(this, debugTagWay, (byte) 0);
|
// if (lat == prevLat && lon == prevLon)
|
||||||
|
// continue;
|
||||||
mIndices = debugBoxIndex;
|
//
|
||||||
mCoords = debugBoxCoords;
|
// if ((pos != end - 2) &&
|
||||||
mDrawingLayer = 10 * mLevels;
|
// !((lat > prevLat + min || lat < prevLat - min) ||
|
||||||
TileGenerator.renderTheme.matchWay(this, debugTagBox, (byte) 0, false, true);
|
// (lon > prevLon + min || lon < prevLon - min)))
|
||||||
}
|
// continue;
|
||||||
|
// }
|
||||||
tile.layers = mLayers;
|
// coords[outPos++] = prevLon = lon;
|
||||||
tile.labels = mLabels;
|
// coords[outPos++] = prevLat = lat;
|
||||||
|
//
|
||||||
mLayers = null;
|
// cnt += 2;
|
||||||
mLabels = null;
|
// }
|
||||||
mCurLineLayer = null;
|
//
|
||||||
|
// mIndices[i] = (short) cnt;
|
||||||
return true;
|
// }
|
||||||
}
|
// mProjected = true;
|
||||||
|
// // mProjectedResult = true;
|
||||||
private static byte getValidLayer(byte layer) {
|
// return true;
|
||||||
if (layer < 0) {
|
// }
|
||||||
return 0;
|
|
||||||
} else if (layer >= LAYERS) {
|
|
||||||
return LAYERS - 1;
|
|
||||||
} else {
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the scale stroke factor for the given zoom level.
|
|
||||||
* @param zoomLevel
|
|
||||||
* the zoom level for which the scale stroke factor should be
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
private void setScaleStrokeWidth(byte zoomLevel) {
|
|
||||||
int zoomLevelDiff = Math.max(zoomLevel - STROKE_MIN_ZOOM_LEVEL, 0);
|
|
||||||
mStrokeScale = (float) Math.pow(STROKE_INCREASE, zoomLevelDiff);
|
|
||||||
if (mStrokeScale < 1)
|
|
||||||
mStrokeScale = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String mMapProjection;
|
|
||||||
|
|
||||||
public void setMapDatabase(IMapDatabase mapDatabase) {
|
|
||||||
if (mMapDatabase != null)
|
|
||||||
mMapDatabase.close();
|
|
||||||
|
|
||||||
mMapDatabase = mapDatabase;
|
|
||||||
mMapProjection = mMapDatabase.getMapProjection();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IMapDatabase getMapDatabase() {
|
|
||||||
return mMapDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkWay(Tag[] tags, boolean closed) {
|
|
||||||
|
|
||||||
mRenderInstructions = TileGenerator.renderTheme.matchWay(this, tags,
|
|
||||||
(byte) (mCurrentTile.zoomLevel + 0), closed, false);
|
|
||||||
|
|
||||||
return mRenderInstructions != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO move this to Projection classes
|
|
||||||
private boolean projectToTile() {
|
|
||||||
if (mProjected || mMapProjection == null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
boolean useWebMercator = false;
|
|
||||||
|
|
||||||
if (mMapProjection == WebMercator.NAME)
|
|
||||||
useWebMercator = true;
|
|
||||||
|
|
||||||
float[] coords = mCoords;
|
|
||||||
|
|
||||||
long x = mCurrentTile.pixelX;
|
|
||||||
long y = mCurrentTile.pixelY + Tile.TILE_SIZE;
|
|
||||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
|
||||||
float min = mSimplify;
|
|
||||||
|
|
||||||
double divx, divy = 0;
|
|
||||||
long dx = (x - (z >> 1));
|
|
||||||
long dy = (y - (z >> 1));
|
|
||||||
|
|
||||||
if (useWebMercator) {
|
|
||||||
divx = WebMercator.f900913 / (z >> 1);
|
|
||||||
} else {
|
|
||||||
divx = 180000000.0 / (z >> 1);
|
|
||||||
divy = z / PIx4;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int pos = 0, outPos = 0, i = 0, m = mIndices.length; i < m; i++) {
|
|
||||||
int len = mIndices[i];
|
|
||||||
if (len == 0)
|
|
||||||
continue;
|
|
||||||
if (len < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
float lat, lon, prevLon = 0, prevLat = 0;
|
|
||||||
|
|
||||||
for (int end = pos + len; pos < end; pos += 2) {
|
|
||||||
|
|
||||||
if (useWebMercator) {
|
|
||||||
lon = (float) (coords[pos] / divx - dx);
|
|
||||||
lat = (float) (coords[pos + 1] / divx + dy);
|
|
||||||
} else {
|
|
||||||
lon = (float) ((coords[pos]) / divx - dx);
|
|
||||||
double sinLat = Math.sin(coords[pos + 1] * PI180);
|
|
||||||
lat = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cnt != 0) {
|
|
||||||
// drop small distance intermediate nodes
|
|
||||||
if (lat == prevLat && lon == prevLon)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((pos != end - 2) &&
|
|
||||||
!((lat > prevLat + min || lat < prevLat - min) ||
|
|
||||||
(lon > prevLon + min || lon < prevLon - min)))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
coords[outPos++] = prevLon = lon;
|
|
||||||
coords[outPos++] = prevLat = lat;
|
|
||||||
|
|
||||||
cnt += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIndices[i] = (short) cnt;
|
|
||||||
}
|
|
||||||
mProjected = true;
|
|
||||||
// mProjectedResult = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user