started work on labeling
This commit is contained in:
parent
331aa6bf68
commit
7f573f0ac4
@ -88,7 +88,8 @@
|
||||
<string name="preferences_show_scale_bar_desc">Show the scale of the map</string>
|
||||
<string name="preferences_show_tile_coordinates">Tile coordinates</string>
|
||||
<string name="preferences_show_tile_coordinates_desc">Show coordinates on tiles</string>
|
||||
<string name="preferences_show_tile_frames">Tile boundaries</string>
|
||||
<string name="preferences_show_unmatched_ways">Draw unmatched ways</string>
|
||||
<string name="preferences_show_tile_frames">Tile boundaries</string>
|
||||
<string name="preferences_show_tile_frames_desc">Draw tile boundaries</string>
|
||||
<string name="preferences_disable_polygons">Disable Polygon rendering</string>
|
||||
<string name="preferences_show_water_tiles_desc">Highlight tiles which have the water flag set</string>
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
android:key="showFpsCounter" /> -->
|
||||
<CheckBoxPreference android:title="@string/preferences_show_tile_frames" android:summary="@string/preferences_show_tile_frames_desc"
|
||||
android:key="drawTileFrames" />
|
||||
<!-- <CheckBoxPreference android:title="@string/preferences_show_tile_coordinates" android:summary="@string/preferences_show_tile_coordinates_desc"
|
||||
android:key="drawTileCoordinates" /> -->
|
||||
<CheckBoxPreference android:title="@string/preferences_show_unmatched_ways" android:summary="@string/preferences_show_unmatched_ways"
|
||||
android:key="drawUnmatchedWays" />
|
||||
<CheckBoxPreference android:title="@string/preferences_disable_polygons" android:summary="@string/preferences_disable_polygons"
|
||||
android:key="disablePolygons" />
|
||||
</PreferenceCategory>
|
||||
|
||||
@ -29,13 +29,13 @@ public class DebugSettings {
|
||||
*/
|
||||
public final boolean mDrawTileFrames;
|
||||
|
||||
public final boolean mDrawUnmatchted;
|
||||
|
||||
/**
|
||||
* True if highlighting of water tiles is enabled, false otherwise.
|
||||
*/
|
||||
public final boolean mDisablePolygons;
|
||||
|
||||
private final int mHashCodeValue;
|
||||
|
||||
/**
|
||||
* @param drawTileCoordinates
|
||||
* if drawing of tile coordinates is enabled.
|
||||
@ -43,49 +43,14 @@ public class DebugSettings {
|
||||
* if drawing of tile frames is enabled.
|
||||
* @param disablePolygons
|
||||
* if highlighting of water tiles is enabled.
|
||||
* @param drawUnmatched
|
||||
* ...
|
||||
*/
|
||||
public DebugSettings(boolean drawTileCoordinates, boolean drawTileFrames,
|
||||
boolean disablePolygons) {
|
||||
boolean disablePolygons, boolean drawUnmatched) {
|
||||
mDrawTileCoordinates = drawTileCoordinates;
|
||||
mDrawTileFrames = drawTileFrames;
|
||||
mDrawUnmatchted = drawUnmatched;
|
||||
mDisablePolygons = disablePolygons;
|
||||
mHashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof DebugSettings)) {
|
||||
return false;
|
||||
}
|
||||
DebugSettings other = (DebugSettings) obj;
|
||||
if (mDrawTileCoordinates != other.mDrawTileCoordinates) {
|
||||
return false;
|
||||
}
|
||||
if (mDrawTileFrames != other.mDrawTileFrames) {
|
||||
return false;
|
||||
}
|
||||
if (mDisablePolygons != other.mDisablePolygons) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mHashCodeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hash code of this object.
|
||||
*/
|
||||
private int calculateHashCode() {
|
||||
int result = 1;
|
||||
result = 31 * result + (mDrawTileCoordinates ? 1231 : 1237);
|
||||
result = 31 * result + (mDrawTileFrames ? 1231 : 1237);
|
||||
result = 31 * result + (mDisablePolygons ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ import org.mapsforge.android.rendertheme.RenderThemeHandler;
|
||||
import org.mapsforge.android.utils.GlConfigChooser;
|
||||
import org.mapsforge.core.GeoPoint;
|
||||
import org.mapsforge.core.MapPosition;
|
||||
import org.mapsforge.core.Tile;
|
||||
import org.mapsforge.database.FileOpenResult;
|
||||
import org.mapsforge.database.IMapDatabase;
|
||||
import org.mapsforge.database.MapFileInfo;
|
||||
@ -93,9 +94,9 @@ public class MapView extends GLSurfaceView {
|
||||
private IMapRenderer mMapRenderer;
|
||||
private JobQueue mJobQueue;
|
||||
private MapWorker mMapWorkers[];
|
||||
private int mNumMapWorkers = 4;
|
||||
private int mNumMapWorkers = 6;
|
||||
private JobParameters mJobParameters;
|
||||
private DebugSettings mDebugSettings;
|
||||
public DebugSettings debugSettings;
|
||||
private String mMapFile;
|
||||
|
||||
/**
|
||||
@ -122,6 +123,8 @@ public class MapView extends GLSurfaceView {
|
||||
MapDatabaseFactory.getMapDatabase(attributeSet));
|
||||
}
|
||||
|
||||
private boolean mDebugDatabase = false;
|
||||
|
||||
private MapView(Context context, AttributeSet attributeSet,
|
||||
MapRenderers mapGeneratorType, MapDatabases mapDatabaseType) {
|
||||
|
||||
@ -131,13 +134,17 @@ public class MapView extends GLSurfaceView {
|
||||
throw new IllegalArgumentException(
|
||||
"context is not an instance of MapActivity");
|
||||
}
|
||||
Log.d(TAG, "create MapView: " + mapDatabaseType.name());
|
||||
|
||||
setWillNotDraw(true);
|
||||
setWillNotCacheDrawing(true);
|
||||
// TODO make this dpi dependent
|
||||
Tile.TILE_SIZE = 400;
|
||||
|
||||
// setWillNotDraw(true);
|
||||
// setWillNotCacheDrawing(true);
|
||||
|
||||
MapActivity mapActivity = (MapActivity) context;
|
||||
|
||||
mDebugSettings = new DebugSettings(false, false, false);
|
||||
debugSettings = new DebugSettings(false, false, false, false);
|
||||
|
||||
mJobParameters = new JobParameters(DEFAULT_RENDER_THEME, DEFAULT_TEXT_SCALE);
|
||||
mMapController = new MapController(this);
|
||||
@ -161,8 +168,14 @@ public class MapView extends GLSurfaceView {
|
||||
mMapWorkers = new MapWorker[mNumMapWorkers];
|
||||
|
||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||
IMapDatabase mapDatabase = MapDatabaseFactory
|
||||
.createMapDatabase(mapDatabaseType);
|
||||
IMapDatabase mapDatabase;
|
||||
if (mDebugDatabase) {
|
||||
mapDatabase = MapDatabaseFactory
|
||||
.createMapDatabase(MapDatabases.JSON_READER);
|
||||
|
||||
} else {
|
||||
mapDatabase = MapDatabaseFactory.createMapDatabase(mapDatabaseType);
|
||||
}
|
||||
|
||||
IMapGenerator mapGenerator = mMapRenderer.createMapGenerator();
|
||||
mapGenerator.setMapDatabase(mapDatabase);
|
||||
@ -170,8 +183,6 @@ public class MapView extends GLSurfaceView {
|
||||
if (i == 0) {
|
||||
mMapDatabase = mapDatabase;
|
||||
initMapStartPosition();
|
||||
|
||||
// mapGenerator.setRendertheme(DEFAULT_RENDER_THEME);
|
||||
}
|
||||
mMapWorkers[i] = new MapWorker(i, this, mapGenerator, mMapRenderer);
|
||||
mMapWorkers[i].start();
|
||||
@ -179,13 +190,13 @@ public class MapView extends GLSurfaceView {
|
||||
|
||||
setRenderTheme(InternalRenderTheme.OSMARENDER);
|
||||
|
||||
mapActivity.registerMapView(this);
|
||||
|
||||
setEGLConfigChooser(new GlConfigChooser());
|
||||
setEGLContextClientVersion(2);
|
||||
|
||||
setRenderer(mMapRenderer);
|
||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||
|
||||
mapActivity.registerMapView(this);
|
||||
}
|
||||
|
||||
private void initMapStartPosition() {
|
||||
@ -212,7 +223,7 @@ public class MapView extends GLSurfaceView {
|
||||
* @return the debug settings which are used in this MapView.
|
||||
*/
|
||||
public DebugSettings getDebugSettings() {
|
||||
return mDebugSettings;
|
||||
return debugSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,14 +313,14 @@ public class MapView extends GLSurfaceView {
|
||||
* Calculates all necessary tiles and adds jobs accordingly.
|
||||
*/
|
||||
public void redrawTiles() {
|
||||
if (getWidth() > 0 && getHeight() > 0)
|
||||
if (getWidth() <= 0 || getHeight() <= 0)
|
||||
return;
|
||||
|
||||
mMapRenderer.redrawTiles(false);
|
||||
}
|
||||
|
||||
void clearAndRedrawMapView() {
|
||||
if (getWidth() > 0 && getHeight() > 0)
|
||||
private void clearAndRedrawMapView() {
|
||||
if (getWidth() <= 0 || getHeight() <= 0)
|
||||
return;
|
||||
|
||||
mMapRenderer.redrawTiles(true);
|
||||
@ -343,7 +354,7 @@ public class MapView extends GLSurfaceView {
|
||||
* the new DebugSettings for this MapView.
|
||||
*/
|
||||
public void setDebugSettings(DebugSettings debugSettings) {
|
||||
mDebugSettings = debugSettings;
|
||||
this.debugSettings = debugSettings;
|
||||
|
||||
clearAndRedrawMapView();
|
||||
}
|
||||
@ -377,7 +388,7 @@ public class MapView extends GLSurfaceView {
|
||||
|
||||
mJobQueue.clear();
|
||||
|
||||
mapWorkersPause();
|
||||
mapWorkersPause(true);
|
||||
|
||||
for (MapWorker mapWorker : mMapWorkers) {
|
||||
|
||||
@ -445,6 +456,9 @@ public class MapView extends GLSurfaceView {
|
||||
*/
|
||||
|
||||
public void setMapDatabase(MapDatabases mapDatabaseType) {
|
||||
if (mDebugDatabase)
|
||||
return;
|
||||
|
||||
IMapGenerator mapGenerator;
|
||||
|
||||
Log.d(TAG, "setMapDatabase " + mapDatabaseType.name());
|
||||
@ -452,7 +466,9 @@ public class MapView extends GLSurfaceView {
|
||||
if (mMapDatabaseType == mapDatabaseType)
|
||||
return;
|
||||
|
||||
mapWorkersPause();
|
||||
mMapDatabaseType = mapDatabaseType;
|
||||
|
||||
mapWorkersPause(true);
|
||||
|
||||
for (MapWorker mapWorker : mMapWorkers) {
|
||||
mapGenerator = mapWorker.getMapGenerator();
|
||||
@ -468,6 +484,8 @@ public class MapView extends GLSurfaceView {
|
||||
setMapFile(mapFile);
|
||||
|
||||
mapWorkersProceed();
|
||||
|
||||
Log.d(TAG, ">>>");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -510,7 +528,7 @@ public class MapView extends GLSurfaceView {
|
||||
|
||||
private boolean setRenderTheme(Theme theme) {
|
||||
|
||||
mapWorkersPause();
|
||||
mapWorkersPause(true);
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
@ -607,7 +625,7 @@ public class MapView extends GLSurfaceView {
|
||||
int oldHeight) {
|
||||
mJobQueue.clear();
|
||||
|
||||
mapWorkersPause();
|
||||
mapWorkersPause(true);
|
||||
|
||||
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
||||
|
||||
@ -668,8 +686,7 @@ public class MapView extends GLSurfaceView {
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
for (MapWorker mapWorker : mMapWorkers)
|
||||
mapWorker.pause();
|
||||
mapWorkersPause(false);
|
||||
|
||||
// mMapMover.pause();
|
||||
// mZoomAnimator.pause();
|
||||
@ -678,8 +695,7 @@ public class MapView extends GLSurfaceView {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
for (MapWorker mapWorker : mMapWorkers)
|
||||
mapWorker.proceed();
|
||||
mapWorkersProceed();
|
||||
|
||||
// mMapMover.proceed();
|
||||
// mZoomAnimator.proceed();
|
||||
@ -747,21 +763,24 @@ public class MapView extends GLSurfaceView {
|
||||
public void addJobs(ArrayList<MapGeneratorJob> jobs) {
|
||||
mJobQueue.setJobs(jobs);
|
||||
|
||||
for (MapWorker m : mMapWorkers) {
|
||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||
MapWorker m = mMapWorkers[i];
|
||||
synchronized (m) {
|
||||
m.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mapWorkersPause() {
|
||||
private void mapWorkersPause(boolean wait) {
|
||||
for (MapWorker mapWorker : mMapWorkers) {
|
||||
if (!mapWorker.isPausing())
|
||||
mapWorker.pause();
|
||||
}
|
||||
for (MapWorker mapWorker : mMapWorkers) {
|
||||
if (!mapWorker.isPausing())
|
||||
mapWorker.awaitPausing();
|
||||
if (wait) {
|
||||
for (MapWorker mapWorker : mMapWorkers) {
|
||||
if (!mapWorker.isPausing())
|
||||
mapWorker.awaitPausing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.mapsforge.android.mapgenerator.MapTile;
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
@ -21,10 +23,12 @@ class GLMapTile extends MapTile {
|
||||
|
||||
VertexBufferObject lineVBO;
|
||||
VertexBufferObject polygonVBO;
|
||||
TextTexture texture;
|
||||
|
||||
LineLayers lineLayers;
|
||||
PolygonLayers polygonLayers;
|
||||
// MeshLayers meshLayers;
|
||||
LineLayer lineLayers;
|
||||
PolygonLayer polygonLayers;
|
||||
|
||||
ArrayList<TextItem> labels;
|
||||
|
||||
boolean newData;
|
||||
boolean loading;
|
||||
|
||||
@ -14,35 +14,27 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
class Layer {
|
||||
LinkedList<PoolItem> pool;
|
||||
PoolItem pool;
|
||||
|
||||
protected PoolItem curItem;
|
||||
|
||||
int verticesCnt;
|
||||
int offset;
|
||||
|
||||
final int layer;
|
||||
// final int color;
|
||||
final float[] colors;
|
||||
|
||||
Layer(int l, int color) {
|
||||
Layer(int l) {
|
||||
layer = l;
|
||||
verticesCnt = 0;
|
||||
|
||||
colors = new float[4];
|
||||
|
||||
colors[0] = (color >> 16 & 0xff) / 255.0f;
|
||||
colors[1] = (color >> 8 & 0xff) / 255.0f;
|
||||
colors[2] = (color >> 0 & 0xff) / 255.0f;
|
||||
colors[3] = (color >> 24 & 0xff) / 255.0f;
|
||||
}
|
||||
|
||||
float[] getNextPoolItem() {
|
||||
curItem.used = PoolItem.SIZE;
|
||||
curItem = LayerPool.get();
|
||||
pool.add(curItem);
|
||||
|
||||
curItem.next = VertexPool.get();
|
||||
curItem = curItem.next;
|
||||
|
||||
return curItem.vertices;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,34 +14,39 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
import android.util.FloatMath;
|
||||
|
||||
class LineLayer extends Layer {
|
||||
ArrayList<LineLayer> outlines;
|
||||
boolean isOutline;
|
||||
boolean isFixed;
|
||||
Line line;
|
||||
|
||||
LineLayer next;
|
||||
LineLayer outlines;
|
||||
|
||||
float width;
|
||||
boolean isOutline;
|
||||
|
||||
LineLayer(int layer, int color, boolean outline, boolean fixed) {
|
||||
super(layer, color);
|
||||
isOutline = outline;
|
||||
isFixed = fixed;
|
||||
if (outline) {
|
||||
outlines = new ArrayList<LineLayer>();
|
||||
} else {
|
||||
curItem = LayerPool.get();
|
||||
LineLayer(int layer, Line line, boolean outline) {
|
||||
super(layer);
|
||||
|
||||
pool = new LinkedList<PoolItem>();
|
||||
pool.add(curItem);
|
||||
this.line = line;
|
||||
this.isOutline = outline;
|
||||
|
||||
if (!outline) {
|
||||
curItem = VertexPool.get();
|
||||
pool = curItem;
|
||||
}
|
||||
}
|
||||
|
||||
void addOutline(LineLayer link) {
|
||||
if (!outlines.contains(link))
|
||||
outlines.add(link);
|
||||
for (LineLayer l = outlines; l != null; l = l.outlines)
|
||||
if (link == l)
|
||||
return;
|
||||
|
||||
link.outlines = outlines;
|
||||
outlines = link;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -49,7 +54,7 @@ class LineLayer extends Layer {
|
||||
*/
|
||||
void addLine(float[] pointArray, int pos, int length, float w, boolean capRound) {
|
||||
float x, y, nextX, nextY, prevX, prevY, ux, uy, vx, vy, wx, wy;
|
||||
double a;
|
||||
float a;
|
||||
int pointPos = pos;
|
||||
boolean rounded = capRound;
|
||||
width = w;
|
||||
@ -59,10 +64,12 @@ class LineLayer extends Layer {
|
||||
// amount of vertices used
|
||||
verticesCnt += length + (rounded ? 6 : 2);
|
||||
|
||||
int MAX = PoolItem.SIZE;
|
||||
|
||||
float[] curVertices = curItem.vertices;
|
||||
int vertexPos = curItem.used;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -77,7 +84,7 @@ class LineLayer extends Layer {
|
||||
vx = nextX - x;
|
||||
vy = nextY - y;
|
||||
|
||||
a = Math.sqrt(vx * vx + vy * vy);
|
||||
a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
|
||||
vx = (float) (vx / a);
|
||||
vy = (float) (vy / a);
|
||||
@ -103,7 +110,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -113,7 +120,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -123,7 +130,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -134,7 +141,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -161,7 +168,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -171,7 +178,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -195,14 +202,14 @@ class LineLayer extends Layer {
|
||||
// Unit vector pointing back to previous node
|
||||
vx = prevX - x;
|
||||
vy = prevY - y;
|
||||
a = Math.sqrt(vx * vx + vy * vy);
|
||||
a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
vx = (float) (vx / a);
|
||||
vy = (float) (vy / a);
|
||||
|
||||
// Unit vector pointing forward to next node
|
||||
wx = nextX - x;
|
||||
wy = nextY - y;
|
||||
a = Math.sqrt(wx * wx + wy * wy);
|
||||
a = FloatMath.sqrt(wx * wx + wy * wy);
|
||||
wx = (float) (wx / a);
|
||||
wy = (float) (wy / a);
|
||||
|
||||
@ -242,7 +249,7 @@ class LineLayer extends Layer {
|
||||
uxw = ux * w;
|
||||
uyw = uy * w;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -252,7 +259,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -271,7 +278,7 @@ class LineLayer extends Layer {
|
||||
vx = prevX - x;
|
||||
vy = prevY - y;
|
||||
|
||||
a = Math.sqrt(vx * vx + vy * vy);
|
||||
a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
|
||||
vx = (float) (vx / a);
|
||||
vy = (float) (vy / a);
|
||||
@ -288,11 +295,16 @@ class LineLayer extends Layer {
|
||||
outside = (x <= 0 || x >= Tile.TILE_SIZE || y <= 0 || y >= Tile.TILE_SIZE)
|
||||
&& (x - vxw <= 0 || x - vxw >= Tile.TILE_SIZE || y - vyw <= 0 || y - vyw >= Tile.TILE_SIZE);
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
curItem.used = vertexPos;
|
||||
curItem = LayerPool.get();
|
||||
pool.add(curItem);
|
||||
curVertices = curItem.vertices;
|
||||
// if (vertexPos == MAX) {
|
||||
// curItem.used = vertexPos;
|
||||
// curItem = LayerPool.get();
|
||||
// pool.add(curItem);
|
||||
// curVertices = curItem.vertices;
|
||||
// vertexPos = 0;
|
||||
// }
|
||||
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
|
||||
@ -302,7 +314,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -312,7 +324,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -323,7 +335,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -334,7 +346,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -358,7 +370,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = -1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
@ -369,7 +381,7 @@ class LineLayer extends Layer {
|
||||
curVertices[vertexPos++] = 1.0f;
|
||||
curVertices[vertexPos++] = 0.0f;
|
||||
|
||||
if (vertexPos == PoolItem.SIZE) {
|
||||
if (vertexPos == MAX) {
|
||||
curVertices = getNextPoolItem();
|
||||
vertexPos = 0;
|
||||
}
|
||||
|
||||
@ -19,42 +19,17 @@ import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
class LineLayers {
|
||||
private static int NUM_VERTEX_FLOATS = 4;
|
||||
|
||||
private SparseArray<LineLayer> layers;
|
||||
|
||||
LineLayer[] array = null;
|
||||
int size = 0;
|
||||
|
||||
LineLayers() {
|
||||
layers = new SparseArray<LineLayer>(10);
|
||||
}
|
||||
|
||||
LineLayer getLayer(int layer, int color, boolean outline, boolean fixed) {
|
||||
LineLayer l = layers.get(layer);
|
||||
if (l != null) {
|
||||
return l;
|
||||
}
|
||||
|
||||
l = new LineLayer(layer, color, outline, fixed);
|
||||
layers.put(layer, l);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
FloatBuffer compileLayerData(FloatBuffer buf) {
|
||||
static FloatBuffer compileLayerData(LineLayer layers, FloatBuffer buf) {
|
||||
FloatBuffer fbuf = buf;
|
||||
int size = 0;
|
||||
|
||||
array = new LineLayer[layers.size()];
|
||||
for (LineLayer l = layers; l != null; l = l.next)
|
||||
size += l.verticesCnt;
|
||||
|
||||
for (int i = 0, n = layers.size(); i < n; i++) {
|
||||
LineLayer l = layers.valueAt(i);
|
||||
array[i] = l;
|
||||
size += l.verticesCnt * NUM_VERTEX_FLOATS;
|
||||
}
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
|
||||
@ -65,40 +40,42 @@ class LineLayers {
|
||||
}
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
LineLayer l = array[i];
|
||||
PoolItem last = null, items = null;
|
||||
|
||||
for (LineLayer l = layers; l != null; l = l.next) {
|
||||
if (l.isOutline)
|
||||
continue;
|
||||
|
||||
for (PoolItem item : l.pool) {
|
||||
for (PoolItem item = l.pool; item != null; item = item.next) {
|
||||
fbuf.put(item.vertices, 0, item.used);
|
||||
last = item;
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
pos += l.verticesCnt;
|
||||
|
||||
LayerPool.add(l.pool);
|
||||
if (last != null) {
|
||||
last.next = items;
|
||||
items = l.pool;
|
||||
}
|
||||
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
fbuf.flip();
|
||||
VertexPool.add(items);
|
||||
|
||||
// not needed for drawing
|
||||
layers = null;
|
||||
fbuf.flip();
|
||||
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
ShortBuffer compileLayerData(ShortBuffer buf) {
|
||||
static ShortBuffer compileLayerData(LineLayer layers, ShortBuffer buf) {
|
||||
int size = 0;
|
||||
ShortBuffer sbuf = buf;
|
||||
|
||||
array = new LineLayer[layers.size()];
|
||||
for (LineLayer l = layers; l != null; l = l.next)
|
||||
size += l.verticesCnt;
|
||||
|
||||
for (int i = 0, n = layers.size(); i < n; i++) {
|
||||
LineLayer l = layers.valueAt(i);
|
||||
array[i] = l;
|
||||
size += l.verticesCnt * NUM_VERTEX_FLOATS;
|
||||
}
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 2).order(
|
||||
@ -111,29 +88,40 @@ class LineLayers {
|
||||
|
||||
short[] data = new short[PoolItem.SIZE];
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
LineLayer l = array[i];
|
||||
PoolItem last = null, items = null;
|
||||
|
||||
for (LineLayer l = layers; l != null; l = l.next) {
|
||||
if (l.isOutline)
|
||||
continue;
|
||||
|
||||
for (int k = 0, m = l.pool.size(); k < m; k++) {
|
||||
PoolItem item = l.pool.get(k);
|
||||
for (PoolItem item = l.pool; item != null; item = item.next) {
|
||||
PoolItem.toHalfFloat(item, data);
|
||||
sbuf.put(data, 0, item.used);
|
||||
last = item;
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
pos += l.verticesCnt;
|
||||
|
||||
LayerPool.add(l.pool);
|
||||
if (last != null) {
|
||||
last.next = items;
|
||||
items = l.pool;
|
||||
}
|
||||
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
sbuf.flip();
|
||||
VertexPool.add(items);
|
||||
|
||||
// not needed for drawing
|
||||
layers = null;
|
||||
sbuf.flip();
|
||||
|
||||
return sbuf;
|
||||
}
|
||||
|
||||
static void clear(LineLayer layer) {
|
||||
for (LineLayer l = layer; l != null; l = l.next) {
|
||||
if (l.pool != null)
|
||||
VertexPool.add(l.pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,11 +14,14 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.mapsforge.android.mapgenerator.IMapGenerator;
|
||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.RenderInstruction;
|
||||
import org.mapsforge.core.MercatorProjection;
|
||||
@ -27,9 +30,9 @@ import org.mapsforge.core.Tile;
|
||||
import org.mapsforge.core.WebMercator;
|
||||
import org.mapsforge.database.IMapDatabase;
|
||||
import org.mapsforge.database.IMapDatabaseCallback;
|
||||
import org.mapsforge.database.QueryResult;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.Log;
|
||||
|
||||
@ -54,11 +57,14 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
private GLMapTile mCurrentTile;
|
||||
|
||||
private float[] mWayNodes;
|
||||
private int[] mWays;
|
||||
private short[] mWays;
|
||||
|
||||
private LineLayers mLineLayers;
|
||||
private PolygonLayers mPolyLayers;
|
||||
// private MeshLayers mMeshLayers;
|
||||
private LineLayer mLineLayers;
|
||||
private PolygonLayer mPolyLayers;
|
||||
private LineLayer mCurLineLayer;
|
||||
private PolygonLayer mCurPolyLayer;
|
||||
|
||||
private ArrayList<TextItem> mLabels;
|
||||
|
||||
private int mDrawingLayer;
|
||||
private int mLevels;
|
||||
@ -71,13 +77,60 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
*/
|
||||
public MapGenerator() {
|
||||
Log.d(TAG, "init DatabaseRenderer");
|
||||
LayerPool.init();
|
||||
VertexPool.init();
|
||||
}
|
||||
|
||||
private float mPoiX = 256;
|
||||
private float mPoiY = 256;
|
||||
|
||||
private Tag mTagEmptyName = new Tag("name", "");
|
||||
private Tag mTagName;
|
||||
|
||||
private void filterTags(Tag[] tags) {
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
// Log.d(TAG, "check tag: " + tags[i]);
|
||||
if (tags[i].key == mTagEmptyName.key && tags[i].value != null) {
|
||||
mTagName = tags[i];
|
||||
tags[i] = mTagEmptyName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPointOfInterest(byte layer, int latitude, int longitude, Tag[] tags) {
|
||||
// TODO Auto-generated method stub
|
||||
public void renderPointOfInterest(byte layer, float latitude, float longitude,
|
||||
Tag[] tags) {
|
||||
|
||||
mTagName = null;
|
||||
|
||||
long x = mCurrentTile.x;
|
||||
long y = mCurrentTile.y;
|
||||
long z = Tile.TILE_SIZE << mCurrentTile.zoomLevel;
|
||||
|
||||
double divx, divy;
|
||||
long dx = (x - (z >> 1));
|
||||
long dy = (y - (z >> 1));
|
||||
|
||||
if (useSphericalMercator) {
|
||||
divx = f900913 / (z >> 1);
|
||||
divy = f900913 / (z >> 1);
|
||||
mPoiX = (float) (longitude / divx - dx);
|
||||
mPoiY = (float) (latitude / divy + dy);
|
||||
} else {
|
||||
divx = 180000000.0 / (z >> 1);
|
||||
divy = z / PIx4;
|
||||
mPoiX = (float) (longitude / divx - dx);
|
||||
double sinLat = Math.sin(latitude * PI180);
|
||||
mPoiY = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
|
||||
if (mPoiX < -10 || mPoiX > Tile.TILE_SIZE + 10 || mPoiY < -10
|
||||
|| mPoiY > Tile.TILE_SIZE + 10)
|
||||
return;
|
||||
}
|
||||
|
||||
// remove tags that should not be cached in Rendertheme
|
||||
filterTags(tags);
|
||||
// Log.d(TAG, "renderPointOfInterest: " + mTagName);
|
||||
|
||||
MapGenerator.renderTheme.matchNode(this, tags, mCurrentTile.zoomLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,7 +147,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
if (mProjected)
|
||||
return mProjectedResult;
|
||||
|
||||
float minx = Float.MAX_VALUE, miny = Float.MAX_VALUE, maxx = Float.MIN_VALUE, maxy = Float.MIN_VALUE;
|
||||
// float minx = Float.MAX_VALUE, miny = Float.MAX_VALUE, maxx = Float.MIN_VALUE, maxy = Float.MIN_VALUE;
|
||||
|
||||
float[] coords = mWayNodes;
|
||||
|
||||
@ -133,16 +186,16 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
lat = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
|
||||
}
|
||||
|
||||
if (area && i == 0) {
|
||||
if (lon < minx)
|
||||
minx = lon;
|
||||
if (lon > maxx)
|
||||
maxx = lon;
|
||||
if (lat < miny)
|
||||
miny = lat;
|
||||
if (lat > maxy)
|
||||
maxy = lat;
|
||||
}
|
||||
// if (area && i == 0) {
|
||||
// if (lon < minx)
|
||||
// minx = lon;
|
||||
// if (lon > maxx)
|
||||
// maxx = lon;
|
||||
// if (lat < miny)
|
||||
// miny = lat;
|
||||
// if (lat > maxy)
|
||||
// maxy = lat;
|
||||
// }
|
||||
|
||||
if (cnt != 0) {
|
||||
// drop small distance intermediate nodes
|
||||
@ -161,38 +214,44 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
cnt += 2;
|
||||
}
|
||||
|
||||
if (area) {
|
||||
// Log.d(TAG, "area:" + (maxx - minx) * (maxy - miny));
|
||||
if ((maxx - minx) * (maxy - miny) < 2000 / mCurrentTile.zoomLevel) {
|
||||
mProjected = true;
|
||||
mProjectedResult = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if (area) {
|
||||
// // Log.d(TAG, "area:" + (maxx - minx) * (maxy - miny));
|
||||
// if ((maxx - minx) * (maxy - miny) < 2000 / mCurrentTile.zoomLevel) {
|
||||
// mProjected = true;
|
||||
// mProjectedResult = false;
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
mWays[i] = cnt;
|
||||
mWays[i] = (short) cnt;
|
||||
}
|
||||
mProjected = true;
|
||||
mProjectedResult = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean firstMatch;
|
||||
private boolean prevClosed;
|
||||
// private boolean firstMatch;
|
||||
// private boolean prevClosed;
|
||||
|
||||
private RenderInstruction[] mRenderInstructions = null;
|
||||
|
||||
private final String TAG_WATER = "water".intern();
|
||||
|
||||
@Override
|
||||
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, int[] wayLength,
|
||||
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, short[] wayLength,
|
||||
boolean changed) {
|
||||
|
||||
// Log.d(TAG, "render way: " + layer);
|
||||
mTagName = null;
|
||||
|
||||
mProjected = false;
|
||||
mDrawingLayer = getValidLayer(layer) * mLevels;
|
||||
|
||||
int len = wayLength[0];
|
||||
boolean closed = (wayNodes[0] == wayNodes[len - 2] &&
|
||||
wayNodes[1] == wayNodes[len - 1]);
|
||||
// int len = wayLength[0];
|
||||
// boolean closed = (wayNodes[0] == wayNodes[len - 2] &&
|
||||
// wayNodes[1] == wayNodes[len - 1]);
|
||||
|
||||
boolean closed = changed;
|
||||
mSimplify = 0.5f;
|
||||
|
||||
if (closed) {
|
||||
@ -201,36 +260,76 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
else
|
||||
mSimplify = 0.2f;
|
||||
|
||||
if (tags.length == 1 && "water".equals(tags[0].value))
|
||||
if (tags.length == 1 && TAG_WATER == (tags[0].value))
|
||||
mSimplify = 0;
|
||||
}
|
||||
|
||||
mWayNodes = wayNodes;
|
||||
mWays = wayLength;
|
||||
|
||||
if (!firstMatch && prevClosed == closed && !changed) {
|
||||
if (mRenderInstructions != null) {
|
||||
for (int i = 0, n = mRenderInstructions.length; i < n; i++)
|
||||
mRenderInstructions[i].renderWay(this, tags);
|
||||
}
|
||||
// MapGenerator.renderTheme.matchWay(this, tags,
|
||||
// (byte) (mCurrentTile.zoomLevel + 0),
|
||||
// closed, false);
|
||||
// if (mRenderInstructions != null) {
|
||||
// for (int i = 0, n = mRenderInstructions.length; i < n; i++)
|
||||
// mRenderInstructions[i].renderWay(this, tags);
|
||||
// }
|
||||
|
||||
// prevClosed = closed;
|
||||
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0),
|
||||
closed, true);
|
||||
|
||||
if (mRenderInstructions == null && mDebugDrawUnmatched)
|
||||
debugUnmatched(closed, tags);
|
||||
|
||||
// firstMatch = false;
|
||||
}
|
||||
|
||||
private void debugUnmatched(boolean closed, Tag[] tags) {
|
||||
|
||||
Log.d(TAG, "way not matched: " + tags[0] + " "
|
||||
+ (tags.length > 1 ? tags[1] : "") + " " + closed);
|
||||
|
||||
mTagName = new Tag("name", tags[0].key + ":" + tags[0].value, false);
|
||||
|
||||
if (closed) {
|
||||
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, debugTagArea,
|
||||
(byte) 0, true, true);
|
||||
} else {
|
||||
prevClosed = closed;
|
||||
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0),
|
||||
closed, true);
|
||||
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, debugTagWay,
|
||||
(byte) 0, true, true);
|
||||
}
|
||||
|
||||
firstMatch = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAreaCaption(String caption, float verticalOffset, Paint paint,
|
||||
Paint stroke) {
|
||||
// TODO Auto-generated method stub
|
||||
public void renderAreaCaption(Caption caption) {
|
||||
// Log.d(TAG, "renderAreaCaption: " + mTagName);
|
||||
|
||||
if (mTagName == null)
|
||||
return;
|
||||
|
||||
if (caption.textKey == mTagEmptyName.key) {
|
||||
if (mLabels == null)
|
||||
mLabels = new ArrayList<TextItem>();
|
||||
mLabels.add(new TextItem(mWayNodes[0], mWayNodes[1], mTagName.value, caption));
|
||||
}
|
||||
|
||||
// if (caption.textKey == mTagEmptyName.key)
|
||||
// mLabels.add(new TextItem(mPoiX, mPoiY, mTagName.value, caption));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPointOfInterestCaption(Caption caption) {
|
||||
// Log.d(TAG, "renderPointOfInterestCaption: " + mPoiX + " " + mPoiY + " "
|
||||
// + mTagName);
|
||||
|
||||
if (mTagName == null)
|
||||
return;
|
||||
|
||||
if (caption.textKey == mTagEmptyName.key) {
|
||||
if (mLabels == null)
|
||||
mLabels = new ArrayList<TextItem>();
|
||||
mLabels.add(new TextItem(mPoiX, mPoiY, mTagName.value, caption));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -239,13 +338,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPointOfInterestCaption(String caption, float verticalOffset,
|
||||
Paint paint, Paint stroke) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPointOfInterestCircle(float radius, Paint fill, int level) {
|
||||
// TODO Auto-generated method stub
|
||||
@ -260,12 +352,60 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
@Override
|
||||
public void renderWay(Line line) {
|
||||
|
||||
projectToTile(false);
|
||||
|
||||
LineLayer outlineLayer = null;
|
||||
LineLayer l = mLineLayers.getLayer(mDrawingLayer + line.level, line.color, false,
|
||||
line.fixed);
|
||||
LineLayer lineLayer = null;
|
||||
|
||||
int numLayer = mDrawingLayer + line.level;
|
||||
|
||||
// LineLayer l = mLineLayers;
|
||||
//
|
||||
// for (; l != null; l = l.next)
|
||||
// if (l.next == null || l.next.layer > numLayer)
|
||||
// break;
|
||||
//
|
||||
// if (l == null || l == mLineLayers) {
|
||||
// // insert at start
|
||||
// lineLayer = new LineLayer(numLayer, line, false);
|
||||
// lineLayer.next = mLineLayers;
|
||||
// mLineLayers = lineLayer;
|
||||
// } else if (l.layer == numLayer) {
|
||||
// lineLayer = l;
|
||||
// } else {
|
||||
// // insert between current and next layer
|
||||
// lineLayer = new LineLayer(numLayer, line, false);
|
||||
// lineLayer.next = l.next;
|
||||
// l.next = lineLayer;
|
||||
// }
|
||||
|
||||
// FIXME simplify this...
|
||||
if (mCurLineLayer != null && mCurLineLayer.layer == numLayer) {
|
||||
lineLayer = mCurLineLayer;
|
||||
} else if (mLineLayers == null || mLineLayers.layer > numLayer) {
|
||||
// insert new layer at start
|
||||
lineLayer = new LineLayer(numLayer, line, false);
|
||||
lineLayer.next = mLineLayers;
|
||||
mLineLayers = lineLayer;
|
||||
} else {
|
||||
for (LineLayer l = mLineLayers; l != null; l = l.next) {
|
||||
if (l.layer == numLayer) {
|
||||
lineLayer = l;
|
||||
break;
|
||||
}
|
||||
if (l.next == null || l.next.layer > numLayer) {
|
||||
lineLayer = new LineLayer(numLayer, line, false);
|
||||
// insert new layer between current and next layer
|
||||
lineLayer.next = l.next;
|
||||
l.next = lineLayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lineLayer == null)
|
||||
return;
|
||||
|
||||
mCurLineLayer = lineLayer;
|
||||
|
||||
float w = line.strokeWidth;
|
||||
|
||||
@ -273,13 +413,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
w *= mStrokeScale;
|
||||
w *= mProjectionScaleFactor;
|
||||
}
|
||||
if (line.outline != -1) {
|
||||
Line outline = MapGenerator.renderTheme.getOutline(line.outline);
|
||||
if (outline != null) {
|
||||
outlineLayer = mLineLayers.getLayer(mDrawingLayer + outline.level,
|
||||
outline.color, true, false);
|
||||
outlineLayer.addOutline(l);
|
||||
}
|
||||
else {
|
||||
w *= 1.2; // TODO make this dependent on dpi
|
||||
}
|
||||
|
||||
for (int i = 0, pos = 0, n = mWays.length; i < n; i++) {
|
||||
@ -287,10 +422,44 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
// need at least two points
|
||||
if (length >= 4)
|
||||
l.addLine(mWayNodes, pos, length, w, line.round);
|
||||
lineLayer.addLine(mWayNodes, pos, length, w, line.round);
|
||||
|
||||
pos += length;
|
||||
}
|
||||
|
||||
if (line.outline < 0)
|
||||
return;
|
||||
|
||||
Line outline = MapGenerator.renderTheme.getOutline(line.outline);
|
||||
|
||||
if (outline == null)
|
||||
return;
|
||||
|
||||
numLayer = mDrawingLayer + outline.level;
|
||||
|
||||
if (mLineLayers == null || mLineLayers.layer > numLayer) {
|
||||
// insert new layer at start
|
||||
outlineLayer = new LineLayer(numLayer, outline, true);
|
||||
outlineLayer.next = mLineLayers;
|
||||
mLineLayers = outlineLayer;
|
||||
} else {
|
||||
for (LineLayer l = mLineLayers; l != null; l = l.next) {
|
||||
if (l.layer == numLayer) {
|
||||
outlineLayer = l;
|
||||
break;
|
||||
}
|
||||
if (l.next == null || l.next.layer > numLayer) {
|
||||
outlineLayer = new LineLayer(numLayer, outline, true);
|
||||
// insert new layer between current and next layer
|
||||
outlineLayer.next = l.next;
|
||||
l.next = outlineLayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outlineLayer != null)
|
||||
outlineLayer.addOutline(lineLayer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -302,17 +471,41 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
if (!projectToTile(false))
|
||||
return;
|
||||
|
||||
PolygonLayer l = mPolyLayers.getLayer(mDrawingLayer + area.level, area.color,
|
||||
area.fade);
|
||||
int numLayer = mDrawingLayer + area.level;
|
||||
PolygonLayer layer = null;
|
||||
|
||||
// MeshLayer l = mMeshLayers.getLayer(mDrawingLayer + area.level, area.color,
|
||||
// area.fade);
|
||||
if (mCurPolyLayer != null && mCurPolyLayer.layer == numLayer) {
|
||||
layer = mCurPolyLayer;
|
||||
} else if (mPolyLayers == null || mPolyLayers.layer > numLayer) {
|
||||
// insert new layer at start
|
||||
layer = new PolygonLayer(numLayer, area);
|
||||
layer.next = mPolyLayers;
|
||||
mPolyLayers = layer;
|
||||
} else {
|
||||
for (PolygonLayer l = mPolyLayers; l != null; l = l.next) {
|
||||
if (l.layer >= numLayer) {
|
||||
layer = l;
|
||||
break;
|
||||
}
|
||||
|
||||
if (l.next == null || l.next.layer > numLayer) {
|
||||
layer = new PolygonLayer(numLayer, area);
|
||||
// insert new layer between current and next layer
|
||||
layer.next = l.next;
|
||||
l.next = layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layer == null)
|
||||
return;
|
||||
|
||||
mCurPolyLayer = layer;
|
||||
|
||||
for (int i = 0, pos = 0, n = mWays.length; i < n; i++) {
|
||||
int length = mWays[i];
|
||||
// need at least three points
|
||||
if (length >= 6)
|
||||
l.addPolygon(mWayNodes, pos, length);
|
||||
layer.addPolygon(mWayNodes, pos, length);
|
||||
|
||||
pos += length;
|
||||
}
|
||||
@ -338,10 +531,10 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
}
|
||||
|
||||
private boolean mDebugDrawPolygons;
|
||||
boolean mDebugDrawUnmatched;
|
||||
|
||||
@Override
|
||||
public boolean executeJob(MapGeneratorJob mapGeneratorJob) {
|
||||
// Log.d(TAG, "load " + mCurrentTile);
|
||||
|
||||
if (!(mapGeneratorJob.tile instanceof GLMapTile))
|
||||
return false;
|
||||
@ -353,7 +546,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
|
||||
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
|
||||
|
||||
mDebugDrawUnmatched = mapGeneratorJob.debugSettings.mDrawUnmatchted;
|
||||
if (mCurrentTile.isLoading || mCurrentTile.isDrawn)
|
||||
return false;
|
||||
|
||||
@ -363,32 +556,49 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
|
||||
setScaleStrokeWidth(mCurrentTile.zoomLevel);
|
||||
|
||||
mLineLayers = new LineLayers();
|
||||
mPolyLayers = new PolygonLayers();
|
||||
// mMeshLayers = new MeshLayers();
|
||||
mCurrentTile.lineLayers = mLineLayers;
|
||||
mCurrentTile.polygonLayers = mPolyLayers;
|
||||
// mCurrentTile.meshLayers = mMeshLayers;
|
||||
mLineLayers = null;
|
||||
mPolyLayers = null;
|
||||
mLabels = null;
|
||||
|
||||
firstMatch = true;
|
||||
// firstMatch = true;
|
||||
|
||||
mProjectionScaleFactor = (float) (1.0 / Math.cos(MercatorProjection
|
||||
.pixelYToLatitude(mCurrentTile.pixelY, mCurrentTile.zoomLevel)
|
||||
* (Math.PI / 180))) / 1.5f;
|
||||
mMapDatabase.executeQuery(mCurrentTile, this);
|
||||
* (Math.PI / 180))); // / 1.5f;
|
||||
|
||||
if (mMapDatabase.executeQuery(mCurrentTile, this) != QueryResult.SUCCESS) {
|
||||
LineLayers.clear(mLineLayers);
|
||||
PolygonLayers.clear(mPolyLayers);
|
||||
mLineLayers = null;
|
||||
mPolyLayers = null;
|
||||
mCurrentTile.isLoading = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
|
||||
float[] coords = { 0, 0, 0, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE,
|
||||
Tile.TILE_SIZE, 0, 0, 0 };
|
||||
LineLayer ll = mLineLayers.getLayer(Integer.MAX_VALUE, Color.BLACK, false,
|
||||
true);
|
||||
ll.addLine(coords, 0, coords.length, 1.5f, false);
|
||||
mTagName = new Tag("name", mCurrentTile.toString(), false);
|
||||
mPoiX = 10;
|
||||
mPoiY = 10;
|
||||
MapGenerator.renderTheme.matchNode(this, debugTagWay, (byte) 0);
|
||||
// float[] coords = { 0, 0, 0, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE,
|
||||
// Tile.TILE_SIZE, 0, 0, 0 };
|
||||
// LineLayer ll = mLineLayers.getLayer(Integer.MAX_VALUE, Color.BLACK, false,
|
||||
// true, -1);
|
||||
// ll.addLine(coords, 0, coords.length, 1.5f, false);
|
||||
}
|
||||
mCurrentTile.lineLayers = mLineLayers;
|
||||
mCurrentTile.polygonLayers = mPolyLayers;
|
||||
mCurrentTile.labels = mLabels;
|
||||
mCurPolyLayer = null;
|
||||
mCurLineLayer = null;
|
||||
|
||||
mCurrentTile.newData = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Tag[] debugTagWay = { new Tag("debug", "way") };
|
||||
private Tag[] debugTagArea = { new Tag("debug", "area") };
|
||||
|
||||
private float mProjectionScaleFactor;
|
||||
|
||||
private static byte getValidLayer(byte layer) {
|
||||
@ -431,4 +641,13 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
|
||||
public void setRenderTheme(RenderTheme theme) {
|
||||
MapGenerator.renderTheme = theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkWay(Tag[] tags, boolean closed) {
|
||||
|
||||
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0), closed, false);
|
||||
|
||||
return mRenderInstructions != null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import static android.opengl.GLES20.GL_EXTENSIONS;
|
||||
import static android.opengl.GLES20.GL_FLOAT;
|
||||
import static android.opengl.GLES20.GL_INVERT;
|
||||
import static android.opengl.GLES20.GL_NEVER;
|
||||
import static android.opengl.GLES20.GL_ONE;
|
||||
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
||||
import static android.opengl.GLES20.GL_SCISSOR_TEST;
|
||||
import static android.opengl.GLES20.GL_SRC_ALPHA;
|
||||
@ -80,6 +81,7 @@ import org.mapsforge.android.mapgenerator.JobParameters;
|
||||
import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||
import org.mapsforge.android.mapgenerator.TileCacheKey;
|
||||
import org.mapsforge.android.mapgenerator.TileDistanceSort;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||
import org.mapsforge.android.utils.GlConfigChooser;
|
||||
import org.mapsforge.android.utils.GlUtils;
|
||||
import org.mapsforge.core.MapPosition;
|
||||
@ -102,7 +104,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
// private boolean mTriangulate = false;
|
||||
|
||||
private static int CACHE_TILES_MAX = 400;
|
||||
private static int CACHE_TILES_MAX = 250;
|
||||
private static int CACHE_TILES = CACHE_TILES_MAX;
|
||||
private static int LIMIT_BUFFERS = 20 * MB;
|
||||
|
||||
@ -127,28 +129,29 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
private JobParameters mJobParameter;
|
||||
private MapPosition mMapPosition, mPrevMapPosition;
|
||||
|
||||
private int mWidth, mHeight;
|
||||
private float mAspect;
|
||||
private static int mWidth, mHeight;
|
||||
private static float mAspect;
|
||||
|
||||
// draw position is updated from current position in onDrawFrame
|
||||
// keeping the position consistent while drawing
|
||||
private double mDrawX, mDrawY, mDrawZ, mCurX, mCurY, mCurZ;
|
||||
private float mDrawScale, mCurScale;
|
||||
private static double mDrawX, mDrawY, mDrawZ, mCurX, mCurY, mCurZ;
|
||||
private static float mDrawScale, mCurScale;
|
||||
|
||||
// current center tile
|
||||
private long mTileX, mTileY;
|
||||
private static long mTileX, mTileY;
|
||||
|
||||
private FloatBuffer floatBuffer[];
|
||||
private ShortBuffer shortBuffer[];
|
||||
private static int rotateBuffers = 2;
|
||||
private static FloatBuffer floatBuffer[];
|
||||
private static ShortBuffer shortBuffer[];
|
||||
|
||||
boolean useHalfFloat = false;
|
||||
static boolean useHalfFloat = false;
|
||||
|
||||
// bytes currently loaded in VBOs
|
||||
private int mBufferMemoryUsage;
|
||||
private static int mBufferMemoryUsage;
|
||||
|
||||
// flag set by updateVisibleList when current visible tiles changed.
|
||||
// used in onDrawFrame to nextTiles to curTiles
|
||||
private boolean mUpdateTiles;
|
||||
private static boolean mUpdateTiles;
|
||||
|
||||
class TilesData {
|
||||
int cnt = 0;
|
||||
@ -159,30 +162,30 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private float[] mMVPMatrix = new float[16];
|
||||
private static float[] mMVPMatrix = new float[16];
|
||||
// private float[] mMMatrix = new float[16];
|
||||
// private float[] mRMatrix = new float[16];
|
||||
|
||||
// newTiles is set in updateVisibleList and synchronized swapped
|
||||
// with nextTiles on main thread.
|
||||
// nextTiles is swapped with curTiles in onDrawFrame in GL thread.
|
||||
private TilesData newTiles, nextTiles, curTiles;
|
||||
private static TilesData newTiles, nextTiles, curTiles;
|
||||
|
||||
private boolean mInitial;
|
||||
|
||||
// shader handles
|
||||
private int gLineProgram;
|
||||
private int gLineVertexPositionHandle;
|
||||
private int gLineTexturePositionHandle;
|
||||
private int gLineColorHandle;
|
||||
private int gLineMatrixHandle;
|
||||
private int gLineModeHandle;
|
||||
private int gLineWidthHandle;
|
||||
private static int lineProgram;
|
||||
private static int hLineVertexPosition;
|
||||
private static int hLineTexturePosition;
|
||||
private static int hLineColor;
|
||||
private static int hLineMatrix;
|
||||
private static int hLineMode;
|
||||
private static int hLineWidth;
|
||||
|
||||
private int gPolygonProgram;
|
||||
private int gPolygonVertexPositionHandle;
|
||||
private int gPolygonMatrixHandle;
|
||||
private int gPolygonColorHandle;
|
||||
private static int polygonProgram;
|
||||
private static int hPolygonVertexPosition;
|
||||
private static int hPolygonMatrix;
|
||||
private static int hPolygonColor;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -261,7 +264,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
GLMapTile t = mTileList.remove(j);
|
||||
if (t.isActive) {
|
||||
// Log.d(TAG, "EEEK removing active tile");
|
||||
Log.d(TAG, "EEEK removing active tile");
|
||||
mTileList.add(t);
|
||||
continue;
|
||||
}
|
||||
@ -441,18 +444,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
updateTileDistances();
|
||||
|
||||
// scramble tile draw order, might help to make draw calls independent... just a guess :)
|
||||
// scramble tile draw order: might help to make gl
|
||||
// pipelines more independent... just a guess :)
|
||||
for (int i = 1; i < tiles / 2; i += 2) {
|
||||
GLMapTile tmp = newTiles.tiles[i];
|
||||
newTiles.tiles[i] = newTiles.tiles[tiles - i];
|
||||
newTiles.tiles[tiles - i] = tmp;
|
||||
}
|
||||
|
||||
int removes = mTiles.size() - CACHE_TILES;
|
||||
|
||||
if (removes > 0)
|
||||
Collections.sort(mTileList, mTileDistanceSort);
|
||||
|
||||
// pass new tile list to glThread
|
||||
synchronized (this) {
|
||||
for (int i = 0; i < nextTiles.cnt; i++)
|
||||
@ -472,7 +471,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
mUpdateTiles = true;
|
||||
}
|
||||
|
||||
limitCache(removes);
|
||||
int removes = mTiles.size() - CACHE_TILES;
|
||||
|
||||
if (removes > 0) {
|
||||
Collections.sort(mTileList, mTileDistanceSort);
|
||||
limitCache(removes);
|
||||
}
|
||||
|
||||
if (mJobList.size() > 0)
|
||||
mMapView.addJobs(mJobList);
|
||||
@ -593,7 +597,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
float alpha = 1.0f;
|
||||
|
||||
if (l.fadeLevel >= mDrawZ) {
|
||||
if (l.area.fade >= mDrawZ) {
|
||||
|
||||
alpha = (mDrawScale > 1.3f ? mDrawScale : 1.3f) - alpha;
|
||||
if (alpha > 1.0f)
|
||||
@ -608,8 +612,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
blend = false;
|
||||
}
|
||||
|
||||
glUniform4f(gPolygonColorHandle,
|
||||
l.colors[0], l.colors[1], l.colors[2], alpha);
|
||||
glUniform4f(hPolygonColor,
|
||||
l.area.color[0], l.area.color[1], l.area.color[2], alpha);
|
||||
|
||||
// set stencil buffer mask used to draw this layer
|
||||
glStencilFunc(GL_EQUAL, 0xff, 1 << c);
|
||||
@ -625,7 +629,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
private boolean drawPolygons(GLMapTile tile, int diff) {
|
||||
int cnt = 0;
|
||||
|
||||
if (tile.polygonLayers == null || tile.polygonLayers.array == null)
|
||||
if (tile.polygonLayers == null)
|
||||
return true;
|
||||
|
||||
glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
||||
@ -635,27 +639,23 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||
|
||||
if (useHalfFloat) {
|
||||
glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
glVertexAttribPointer(hPolygonVertexPosition, 2,
|
||||
OES_HALF_FLOAT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
} else {
|
||||
glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
glVertexAttribPointer(hPolygonVertexPosition, 2,
|
||||
GL_FLOAT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
}
|
||||
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
setMatrix(tile, diff);
|
||||
glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
|
||||
glUniformMatrix4fv(hPolygonMatrix, 1, false, mMVPMatrix, 0);
|
||||
|
||||
boolean firstPass = true;
|
||||
|
||||
for (int i = 0, n = tile.polygonLayers.array.length; i < n; i++) {
|
||||
PolygonLayer l = tile.polygonLayers.array[i];
|
||||
|
||||
for (PolygonLayer l = tile.polygonLayers; l != null; l = l.next) {
|
||||
// fade out polygon layers (set in RederTheme)
|
||||
if (l.fadeLevel > 0 && l.fadeLevel > mDrawZ)
|
||||
if (l.area.fade > 0 && l.area.fade > mDrawZ)
|
||||
continue;
|
||||
|
||||
if (cnt == 0) {
|
||||
@ -668,8 +668,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
if (firstPass)
|
||||
firstPass = false;
|
||||
else {
|
||||
// eeek, nexus! - cant do old-school polygons
|
||||
// glFinish();
|
||||
GLES20.glFlush();
|
||||
|
||||
// clear stencilbuffer
|
||||
glStencilMask(0xFF);
|
||||
@ -703,56 +702,16 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
// eeek, nexus! - cant do old-school polygons
|
||||
// glFinish();
|
||||
}
|
||||
GLES20.glFlush();
|
||||
return true;
|
||||
}
|
||||
|
||||
private int mLastBoundVBO;
|
||||
|
||||
// private boolean drawTriangles(GLMapTile tile, int diff) {
|
||||
//
|
||||
// if (tile.meshLayers == null || tile.meshLayers.array == null)
|
||||
// return true;
|
||||
//
|
||||
// glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
||||
//
|
||||
// if (mLastBoundVBO != tile.polygonVBO.id) {
|
||||
// mLastBoundVBO = tile.polygonVBO.id;
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||
//
|
||||
// if (useHalfFloat) {
|
||||
// glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
// OES_HALF_FLOAT, false, 0,
|
||||
// POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
// } else {
|
||||
// glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
// GL_FLOAT, false, 0,
|
||||
// POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
// }
|
||||
//
|
||||
// // glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// }
|
||||
// setMatrix(tile, diff);
|
||||
// glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
|
||||
//
|
||||
// MeshLayer[] layers = tile.meshLayers.array;
|
||||
//
|
||||
// for (int i = 0, n = layers.length; i < n; i++) {
|
||||
// MeshLayer l = layers[i];
|
||||
// glUniform4fv(gPolygonColorHandle, 1, l.colors, 0);
|
||||
//
|
||||
// // glUniform4f(gPolygonColorHandle, 1, 0, 0, 1);
|
||||
//
|
||||
// // System.out.println("draw: " + l.offset + " " + l.verticesCnt);
|
||||
// glDrawArrays(GL_TRIANGLES, l.offset, l.verticesCnt);
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
private static int mLastBoundVBO;
|
||||
|
||||
private boolean drawLines(GLMapTile tile, int diff) {
|
||||
float z = 1;
|
||||
|
||||
if (tile.lineLayers == null || tile.lineLayers.array == null)
|
||||
if (tile.lineLayers == null)
|
||||
return false;
|
||||
|
||||
glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
|
||||
@ -762,27 +721,24 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
|
||||
|
||||
if (useHalfFloat) {
|
||||
glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
|
||||
glVertexAttribPointer(hLineVertexPosition, 2, OES_HALF_FLOAT,
|
||||
false, 8, LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
|
||||
glVertexAttribPointer(hLineTexturePosition, 2, OES_HALF_FLOAT,
|
||||
false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
|
||||
} else {
|
||||
glVertexAttribPointer(gLineVertexPositionHandle, 2, GL_FLOAT,
|
||||
glVertexAttribPointer(hLineVertexPosition, 2, GL_FLOAT,
|
||||
false, 16, LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
glVertexAttribPointer(gLineTexturePositionHandle, 2, GL_FLOAT,
|
||||
glVertexAttribPointer(hLineTexturePosition, 2, GL_FLOAT,
|
||||
false, 16, LINE_VERTICES_DATA_TEX_OFFSET);
|
||||
}
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
if (diff != 0)
|
||||
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
|
||||
|
||||
setMatrix(tile, diff);
|
||||
glUniformMatrix4fv(gLineMatrixHandle, 1, false, mMVPMatrix, 0);
|
||||
|
||||
LineLayer[] layers = tile.lineLayers.array;
|
||||
glUniformMatrix4fv(hLineMatrix, 1, false, mMVPMatrix, 0);
|
||||
|
||||
boolean drawOutlines = false;
|
||||
boolean drawFixed = false;
|
||||
@ -792,52 +748,67 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
// linear scale for fixed lines
|
||||
float fdiv = 0.9f / (mDrawScale / z);
|
||||
|
||||
// int cnt = 0;
|
||||
for (int i = 0, n = layers.length; i < n; i++) {
|
||||
LineLayer l = layers[i];
|
||||
boolean first = true;
|
||||
|
||||
for (LineLayer l = tile.lineLayers; l != null; l = l.next) {
|
||||
Line line = l.line;
|
||||
if (line.fade > 0 && line.fade > mDrawZ)
|
||||
continue;
|
||||
|
||||
// set line width and mode
|
||||
if ((i == 0) || (l.isOutline != drawOutlines) || (l.isFixed != drawFixed)) {
|
||||
if (first || (l.isOutline != drawOutlines)
|
||||
|| (line.fixed != drawFixed)) {
|
||||
first = false;
|
||||
drawOutlines = l.isOutline;
|
||||
drawFixed = l.isFixed;
|
||||
drawFixed = line.fixed;
|
||||
|
||||
if (drawOutlines) {
|
||||
glUniform2f(gLineModeHandle, 0, wdiv);
|
||||
glUniform2f(hLineMode, 0, wdiv);
|
||||
} else if (!drawFixed) {
|
||||
glUniform2f(gLineModeHandle, 0, wdiv * 0.98f);
|
||||
glUniform2f(hLineMode, 0, wdiv * 0.98f);
|
||||
}
|
||||
}
|
||||
|
||||
if (drawFixed) {
|
||||
if (l.width < 1.0)
|
||||
glUniform2f(gLineModeHandle, 0.4f, fdiv);
|
||||
glUniform2f(hLineMode, 0.4f, fdiv);
|
||||
else
|
||||
glUniform2f(gLineModeHandle, 0, fdiv);
|
||||
glUniform2f(hLineMode, 0, fdiv);
|
||||
}
|
||||
|
||||
if (line.fade >= mDrawZ) {
|
||||
float alpha = 1.0f;
|
||||
|
||||
alpha = (mDrawScale > 1.3f ? mDrawScale : 1.3f) - alpha;
|
||||
if (alpha > 1.0f)
|
||||
alpha = 1.0f;
|
||||
glUniform4f(hLineColor,
|
||||
line.color[0], line.color[1], line.color[2], alpha);
|
||||
} else {
|
||||
glUniform4fv(hLineColor, 1, line.color, 0);
|
||||
}
|
||||
glUniform4fv(gLineColorHandle, 1, l.colors, 0);
|
||||
|
||||
if (drawOutlines) {
|
||||
for (int j = 0, m = l.outlines.size(); j < m; j++) {
|
||||
LineLayer o = l.outlines.get(j);
|
||||
for (LineLayer o = l.outlines; o != null; o = o.outlines) {
|
||||
|
||||
if (mSimpleLines)
|
||||
glUniform1f(gLineWidthHandle, o.width);
|
||||
glUniform1f(hLineWidth, o.width);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mSimpleLines)
|
||||
glUniform1f(gLineWidthHandle, l.width);
|
||||
glUniform1f(hLineWidth, l.width);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
||||
}
|
||||
}
|
||||
|
||||
GLES20.glFlush();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setMatrix(GLMapTile tile, int diff) {
|
||||
private static void setMatrix(GLMapTile tile, int diff) {
|
||||
float x, y, scale;
|
||||
float z = 1;
|
||||
|
||||
@ -858,7 +829,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
mMVPMatrix[5] = (scale);
|
||||
}
|
||||
|
||||
private boolean setTileScissor(GLMapTile tile, float div) {
|
||||
private static boolean setTileScissor(GLMapTile tile, float div) {
|
||||
|
||||
double dx, dy, scale;
|
||||
|
||||
@ -916,12 +887,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
private int uploadCnt = 0;
|
||||
|
||||
private boolean uploadTileData(GLMapTile tile) {
|
||||
ShortBuffer sbuf = null;
|
||||
FloatBuffer fbuf = null;
|
||||
|
||||
// double start = SystemClock.uptimeMillis();
|
||||
|
||||
// use multiple buffers to avoid overwriting buffer while current data is uploaded
|
||||
// (or rather the blocking which is required to avoid this)
|
||||
if (uploadCnt >= 10) {
|
||||
// use multiple buffers to avoid overwriting buffer while current
|
||||
// data is uploaded (or rather the blocking which is required to avoid this)
|
||||
if (uploadCnt >= rotateBuffers) {
|
||||
// mMapView.requestRender();
|
||||
// return false;
|
||||
uploadCnt = 0;
|
||||
@ -939,27 +912,34 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
tile.polygonVBO = mVBOs.remove(mVBOs.size() - 1);
|
||||
}
|
||||
}
|
||||
if (useHalfFloat)
|
||||
shortBuffer[uploadCnt * 2] = tile.lineLayers
|
||||
.compileLayerData(shortBuffer[uploadCnt * 2]);
|
||||
else
|
||||
floatBuffer[uploadCnt * 2] = tile.lineLayers
|
||||
.compileLayerData(floatBuffer[uploadCnt * 2]);
|
||||
int size = 0;
|
||||
|
||||
if (tile.lineLayers.size > 0) {
|
||||
if (useHalfFloat) {
|
||||
sbuf = LineLayers.compileLayerData(tile.lineLayers,
|
||||
shortBuffer[uploadCnt * 2]);
|
||||
size = sbuf.remaining();
|
||||
shortBuffer[uploadCnt * 2] = sbuf;
|
||||
} else {
|
||||
fbuf = LineLayers.compileLayerData(tile.lineLayers,
|
||||
floatBuffer[uploadCnt * 2]);
|
||||
size = fbuf.remaining();
|
||||
floatBuffer[uploadCnt * 2] = fbuf;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
mBufferMemoryUsage -= tile.lineVBO.size;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
|
||||
// glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW);
|
||||
|
||||
if (useHalfFloat) {
|
||||
tile.lineVBO.size = tile.lineLayers.size * SHORT_BYTES;
|
||||
tile.lineVBO.size = size * SHORT_BYTES;
|
||||
glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||
shortBuffer[uploadCnt * 2], GL_DYNAMIC_DRAW);
|
||||
sbuf, GL_DYNAMIC_DRAW);
|
||||
} else {
|
||||
tile.lineVBO.size = tile.lineLayers.size * FLOAT_BYTES;
|
||||
tile.lineVBO.size = size * FLOAT_BYTES;
|
||||
glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||
floatBuffer[uploadCnt * 2], GL_DYNAMIC_DRAW);
|
||||
fbuf, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
mBufferMemoryUsage += tile.lineVBO.size;
|
||||
@ -968,16 +948,19 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
tile.lineLayers = null;
|
||||
}
|
||||
|
||||
// if (!mTriangulate) {
|
||||
if (useHalfFloat)
|
||||
shortBuffer[uploadCnt * 2 + 1] = tile.polygonLayers
|
||||
.compileLayerData(shortBuffer[uploadCnt * 2 + 1]);
|
||||
else
|
||||
floatBuffer[uploadCnt * 2 + 1] = tile.polygonLayers
|
||||
.compileLayerData(floatBuffer[uploadCnt * 2 + 1]);
|
||||
|
||||
if (useHalfFloat) {
|
||||
sbuf = PolygonLayers.compileLayerData(tile.polygonLayers,
|
||||
shortBuffer[uploadCnt * 2 + 1]);
|
||||
size = sbuf.remaining();
|
||||
shortBuffer[uploadCnt * 2 + 1] = sbuf;
|
||||
} else {
|
||||
fbuf = PolygonLayers.compileLayerData(tile.polygonLayers,
|
||||
floatBuffer[uploadCnt * 2 + 1]);
|
||||
size = fbuf.remaining();
|
||||
floatBuffer[uploadCnt * 2 + 1] = fbuf;
|
||||
}
|
||||
// Upload polygon data to vertex buffer object
|
||||
if (tile.polygonLayers.size > 0) {
|
||||
if (size > 0) {
|
||||
mBufferMemoryUsage -= tile.polygonVBO.size;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||
@ -985,54 +968,24 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
// GL_DYNAMIC_DRAW);
|
||||
|
||||
if (useHalfFloat) {
|
||||
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
|
||||
tile.polygonVBO.size = size * SHORT_BYTES;
|
||||
glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
shortBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||
sbuf, GL_DYNAMIC_DRAW);
|
||||
} else {
|
||||
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
|
||||
tile.polygonVBO.size = size * FLOAT_BYTES;
|
||||
glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
floatBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||
fbuf, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
mBufferMemoryUsage += tile.polygonVBO.size;
|
||||
|
||||
} else {
|
||||
tile.polygonLayers = null;
|
||||
}
|
||||
// }
|
||||
// else {
|
||||
// if (useHalfFloat)
|
||||
// shortBuffer[uploadCnt * 2 + 1] = tile.meshLayers
|
||||
// .compileLayerData(shortBuffer[uploadCnt * 2 + 1]);
|
||||
// else
|
||||
// floatBuffer[uploadCnt * 2 + 1] = tile.meshLayers
|
||||
// .compileLayerData(floatBuffer[uploadCnt * 2 + 1]);
|
||||
//
|
||||
// // Upload triangle data to vertex buffer object
|
||||
// if (tile.meshLayers.size > 0) {
|
||||
// mBufferMemoryUsage -= tile.polygonVBO.size;
|
||||
//
|
||||
// glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||
// // glBufferData(GL_ARRAY_BUFFER, 0, null,
|
||||
// // GL_DYNAMIC_DRAW);
|
||||
//
|
||||
// if (useHalfFloat) {
|
||||
// tile.polygonVBO.size = tile.meshLayers.size * SHORT_BYTES;
|
||||
// glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
// shortBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||
// } else {
|
||||
// tile.polygonVBO.size = tile.meshLayers.size * FLOAT_BYTES;
|
||||
// glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
// floatBuffer[uploadCnt * 2 + 1], GL_DYNAMIC_DRAW);
|
||||
// }
|
||||
// mBufferMemoryUsage += tile.polygonVBO.size;
|
||||
//
|
||||
// } else {
|
||||
// tile.meshLayers = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
tile.newData = false;
|
||||
tile.isDrawn = true;
|
||||
tile.isLoading = false;
|
||||
|
||||
// double compile = SystemClock.uptimeMillis();
|
||||
// glFinish();
|
||||
// double now = SystemClock.uptimeMillis();
|
||||
@ -1044,8 +997,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
return true;
|
||||
}
|
||||
|
||||
// private long startTime = SystemClock.uptimeMillis();
|
||||
|
||||
@Override
|
||||
public void onDrawFrame(GL10 glUnused) {
|
||||
long start = 0, poly_time = 0, clear_time = 0;
|
||||
@ -1057,20 +1008,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
start = SystemClock.uptimeMillis();
|
||||
|
||||
glStencilMask(0xFF);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
// long endTime = SystemClock.uptimeMillis();
|
||||
// long dt = endTime - startTime;
|
||||
// if (dt < 33)
|
||||
// try {
|
||||
// Thread.sleep(33 - dt);
|
||||
// } catch (InterruptedException e) {
|
||||
// Log.d(TAG, "interrupt");
|
||||
// return;
|
||||
// }
|
||||
// startTime = SystemClock.uptimeMillis();
|
||||
|
||||
synchronized (this) {
|
||||
mDrawX = mCurX;
|
||||
mDrawY = mCurY;
|
||||
@ -1114,13 +1053,20 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
uploadCnt = 0;
|
||||
mLastBoundVBO = -1;
|
||||
|
||||
int updateTextures = 0;
|
||||
|
||||
// check visible tiles, set tile clip scissors, upload new vertex data
|
||||
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
GLMapTile tile = tiles[i];
|
||||
|
||||
if (!setTileScissor(tile, 1))
|
||||
continue;
|
||||
|
||||
if (tile.texture == null && tile.labels != null &&
|
||||
mTextRenderer.drawToTexture(tile))
|
||||
updateTextures++;
|
||||
|
||||
if (tile.newData) {
|
||||
uploadTileData(tile);
|
||||
continue;
|
||||
@ -1143,25 +1089,25 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
if (GlUtils.checkGlOutOfMemory("upload: " + mBufferMemoryUsage)
|
||||
&& LIMIT_BUFFERS > MB)
|
||||
LIMIT_BUFFERS -= MB;
|
||||
if (updateTextures > 0)
|
||||
mTextRenderer.compileTextures();
|
||||
|
||||
// if (GlUtils.checkGlOutOfMemory("upload: " + mBufferMemoryUsage)
|
||||
// && LIMIT_BUFFERS > MB)
|
||||
// LIMIT_BUFFERS -= MB;
|
||||
|
||||
if (timing)
|
||||
clear_time = (SystemClock.uptimeMillis() - start);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
glUseProgram(gPolygonProgram);
|
||||
glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||
glUseProgram(polygonProgram);
|
||||
glEnableVertexAttribArray(hPolygonVertexPosition);
|
||||
|
||||
// if (!mTriangulate) {
|
||||
glDisable(GL_BLEND);
|
||||
// Draw Polygons
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
// glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
if (tiles[i].isVisible) {
|
||||
GLMapTile tile = tiles[i];
|
||||
@ -1172,24 +1118,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
drawProxyPolygons(tile);
|
||||
}
|
||||
}
|
||||
// GlUtils.checkGlError("polygons");
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
// } else {
|
||||
// // Draw Triangles
|
||||
// for (int i = 0; i < tileCnt; i++) {
|
||||
// if (tiles[i].isVisible) {
|
||||
// GLMapTile tile = tiles[i];
|
||||
//
|
||||
// if (tile.isDrawn)
|
||||
// drawTriangles(tile, 0);
|
||||
// else
|
||||
// drawProxyTriangles(tile);
|
||||
// }
|
||||
// }
|
||||
// // GlUtils.checkGlError("triangles");
|
||||
// }
|
||||
|
||||
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
||||
glDisableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||
glDisableVertexAttribArray(hPolygonVertexPosition);
|
||||
|
||||
if (timing) {
|
||||
glFinish();
|
||||
@ -1198,10 +1131,10 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
// Draw lines
|
||||
glEnable(GL_BLEND);
|
||||
glUseProgram(gLineProgram);
|
||||
glUseProgram(lineProgram);
|
||||
|
||||
glEnableVertexAttribArray(gLineVertexPositionHandle);
|
||||
glEnableVertexAttribArray(gLineTexturePositionHandle);
|
||||
glEnableVertexAttribArray(hLineVertexPosition);
|
||||
glEnableVertexAttribArray(hLineTexturePosition);
|
||||
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
if (tiles[i].isVisible) {
|
||||
@ -1214,20 +1147,37 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(hLineVertexPosition);
|
||||
glDisableVertexAttribArray(hLineTexturePosition);
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
mTextRenderer.beginDraw();
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
if (!tiles[i].isVisible || tiles[i].texture == null)
|
||||
continue;
|
||||
|
||||
setMatrix(tiles[i], 0);
|
||||
|
||||
mTextRenderer.drawTile(tiles[i], mMVPMatrix);
|
||||
}
|
||||
mTextRenderer.endDraw();
|
||||
|
||||
if (timing) {
|
||||
glFinish();
|
||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
|
||||
+ clear_time + " " + poly_time);
|
||||
}
|
||||
glDisableVertexAttribArray(gLineVertexPositionHandle);
|
||||
glDisableVertexAttribArray(gLineTexturePositionHandle);
|
||||
// GlUtils.checkGlError("lines");
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
private int[] mVboIds;
|
||||
private static TextRenderer mTextRenderer;
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
|
||||
GlUtils.checkGlError("onSurfaceChanged");
|
||||
|
||||
mVBOs.clear();
|
||||
mTiles.clear();
|
||||
mTileList.clear();
|
||||
@ -1246,20 +1196,27 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
mAspect = (float) height / width;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
GlUtils.checkGlError("glViewport");
|
||||
|
||||
int tiles = (mWidth / Tile.TILE_SIZE + 4) * (mHeight / Tile.TILE_SIZE + 4);
|
||||
curTiles = new TilesData(tiles);
|
||||
newTiles = new TilesData(tiles);
|
||||
nextTiles = new TilesData(tiles);
|
||||
int numTiles = (mWidth / (Tile.TILE_SIZE / 2) + 2)
|
||||
* (mHeight / (Tile.TILE_SIZE / 2) + 2);
|
||||
|
||||
curTiles = new TilesData(numTiles);
|
||||
newTiles = new TilesData(numTiles);
|
||||
nextTiles = new TilesData(numTiles);
|
||||
|
||||
// Set up vertex buffer objects
|
||||
int numVBO = (CACHE_TILES + tiles) * 2;
|
||||
mVboIds = new int[numVBO];
|
||||
int numVBO = (CACHE_TILES + numTiles) * 2;
|
||||
int[] mVboIds = new int[numVBO];
|
||||
glGenBuffers(numVBO, mVboIds, 0);
|
||||
GlUtils.checkGlError("glGenBuffers");
|
||||
|
||||
for (int i = 0; i < numVBO; i++)
|
||||
mVBOs.add(new VertexBufferObject(mVboIds[i]));
|
||||
|
||||
// Set up textures
|
||||
mTextRenderer = new TextRenderer(numTiles * 2);
|
||||
|
||||
mDebugSettings = mMapView.getDebugSettings();
|
||||
mJobParameter = mMapView.getJobParameters();
|
||||
|
||||
@ -1273,14 +1230,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// Set up the program for rendering lines
|
||||
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
lineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
Shaders.gLineFragmentShader);
|
||||
if (gLineProgram == 0) {
|
||||
if (lineProgram == 0) {
|
||||
mSimpleLines = true;
|
||||
Log.e(TAG, "trying simple line program.");
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
lineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
Shaders.gLineFragmentShaderSimple);
|
||||
if (gLineProgram == 0) {
|
||||
if (lineProgram == 0) {
|
||||
Log.e(TAG, "Could not create line program.");
|
||||
return;
|
||||
}
|
||||
@ -1290,48 +1247,51 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
|
||||
if (ext.indexOf("GL_OES_vertex_half_float") >= 0) {
|
||||
useHalfFloat = true;
|
||||
shortBuffer = new ShortBuffer[20];
|
||||
shortBuffer = new ShortBuffer[rotateBuffers * 2];
|
||||
}
|
||||
else {
|
||||
floatBuffer = new FloatBuffer[20];
|
||||
floatBuffer = new FloatBuffer[rotateBuffers * 2];
|
||||
}
|
||||
Log.d(TAG, "Extensions: " + ext);
|
||||
|
||||
gLineMatrixHandle = glGetUniformLocation(gLineProgram, "u_center");
|
||||
gLineModeHandle = glGetUniformLocation(gLineProgram, "u_mode");
|
||||
gLineColorHandle = glGetUniformLocation(gLineProgram, "u_color");
|
||||
gLineVertexPositionHandle = GLES20
|
||||
.glGetAttribLocation(gLineProgram, "a_position");
|
||||
gLineTexturePositionHandle = glGetAttribLocation(gLineProgram, "a_st");
|
||||
hLineMatrix = glGetUniformLocation(lineProgram, "u_center");
|
||||
hLineMode = glGetUniformLocation(lineProgram, "u_mode");
|
||||
hLineColor = glGetUniformLocation(lineProgram, "u_color");
|
||||
hLineVertexPosition = GLES20.glGetAttribLocation(lineProgram, "a_position");
|
||||
hLineTexturePosition = glGetAttribLocation(lineProgram, "a_st");
|
||||
if (mSimpleLines)
|
||||
gLineWidthHandle = glGetUniformLocation(gLineProgram, "u_width");
|
||||
hLineWidth = glGetUniformLocation(lineProgram, "u_width");
|
||||
|
||||
// Set up the program for rendering polygons
|
||||
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
|
||||
polygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
|
||||
Shaders.gPolygonFragmentShader);
|
||||
if (gPolygonProgram == 0) {
|
||||
if (polygonProgram == 0) {
|
||||
Log.e(TAG, "Could not create polygon program.");
|
||||
return;
|
||||
}
|
||||
gPolygonMatrixHandle = glGetUniformLocation(gPolygonProgram, "u_center");
|
||||
gPolygonVertexPositionHandle = glGetAttribLocation(gPolygonProgram,
|
||||
"a_position");
|
||||
gPolygonColorHandle = glGetUniformLocation(gPolygonProgram, "u_color");
|
||||
hPolygonMatrix = glGetUniformLocation(polygonProgram, "u_center");
|
||||
hPolygonVertexPosition = glGetAttribLocation(polygonProgram, "a_position");
|
||||
hPolygonColor = glGetUniformLocation(polygonProgram, "u_color");
|
||||
|
||||
// glUseProgram(gPolygonProgram);
|
||||
// glEnableVertexAttribArray(gPolygonVertexPositionHandle);
|
||||
// glUseProgram(polygonProgram);
|
||||
// glEnableVertexAttribArray(hPolygonVertexPosition);
|
||||
//
|
||||
// glUseProgram(gLineProgram);
|
||||
// glEnableVertexAttribArray(gLineVertexPositionHandle);
|
||||
// glEnableVertexAttribArray(gLineTexturePositionHandle);
|
||||
// glUseProgram(lineProgram);
|
||||
// glEnableVertexAttribArray(hLineVertexPosition);
|
||||
// glEnableVertexAttribArray(hLineTexturePosition);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DITHER);
|
||||
glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
|
||||
glClearStencil(0);
|
||||
|
||||
GlUtils.checkGlError("onSurfaceCreated");
|
||||
|
||||
}
|
||||
|
||||
private void drawProxyLines(GLMapTile tile) {
|
||||
@ -1397,38 +1357,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// private void drawProxyTriangles(GLMapTile tile) {
|
||||
// if (tile.parent != null && tile.parent.isDrawn) {
|
||||
// tile.parent.sx = tile.sx;
|
||||
// tile.parent.sy = tile.sy;
|
||||
// tile.parent.sw = tile.sw;
|
||||
// tile.parent.sh = tile.sh;
|
||||
// drawTriangles(tile.parent, -1);
|
||||
// } else {
|
||||
// int drawn = 0;
|
||||
//
|
||||
// for (int i = 0; i < 4; i++) {
|
||||
// GLMapTile c = tile.child[i];
|
||||
//
|
||||
// if (c != null && c.isDrawn && setTileScissor(c, 2)) {
|
||||
// drawTriangles(c, 1);
|
||||
// drawn++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (drawn < 4 && tile.parent != null) {
|
||||
// GLMapTile p = tile.parent.parent;
|
||||
// if (p != null && p.isDrawn) {
|
||||
// p.sx = tile.sx;
|
||||
// p.sy = tile.sy;
|
||||
// p.sw = tile.sw;
|
||||
// p.sh = tile.sh;
|
||||
// drawTriangles(p, -2);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean processedTile() {
|
||||
return true;
|
||||
|
||||
@ -14,21 +14,21 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||
|
||||
class PolygonLayer extends Layer {
|
||||
int fadeLevel;
|
||||
PolygonLayer next;
|
||||
Area area;
|
||||
|
||||
private boolean first = true;
|
||||
private float originX;
|
||||
private float originY;
|
||||
|
||||
PolygonLayer(int layer, int color, int fade) {
|
||||
super(layer, color);
|
||||
fadeLevel = fade;
|
||||
curItem = LayerPool.get();
|
||||
pool = new LinkedList<PoolItem>();
|
||||
pool.add(curItem);
|
||||
PolygonLayer(int layer, Area area) {
|
||||
super(layer);
|
||||
this.area = area;
|
||||
curItem = VertexPool.get();
|
||||
pool = curItem;
|
||||
}
|
||||
|
||||
void addPolygon(float[] points, int pos, int length) {
|
||||
|
||||
@ -22,50 +22,20 @@ import java.nio.ShortBuffer;
|
||||
import org.mapsforge.android.utils.FastMath;
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
class PolygonLayers {
|
||||
private static final int NUM_VERTEX_FLOATS = 2;
|
||||
private static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1,
|
||||
static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1,
|
||||
Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
|
||||
-2, Tile.TILE_SIZE + 1, -2 };
|
||||
|
||||
private static short[] mByteFillCoords = null;
|
||||
|
||||
private SparseArray<PolygonLayer> layers;
|
||||
|
||||
PolygonLayer[] array = null;
|
||||
int size;
|
||||
|
||||
PolygonLayers() {
|
||||
layers = new SparseArray<PolygonLayer>(10);
|
||||
size = 4;
|
||||
}
|
||||
|
||||
PolygonLayer getLayer(int layer, int color, int fade) {
|
||||
PolygonLayer l = layers.get(layer);
|
||||
if (l != null) {
|
||||
// if (color == l.color)
|
||||
return l;
|
||||
|
||||
// return getLayer(layer + 1, color, fade);
|
||||
}
|
||||
|
||||
l = new PolygonLayer(layer, color, fade);
|
||||
layers.put(layer, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
FloatBuffer compileLayerData(FloatBuffer buf) {
|
||||
static FloatBuffer compileLayerData(PolygonLayer layers, FloatBuffer buf) {
|
||||
FloatBuffer fbuf = buf;
|
||||
int size = 4;
|
||||
|
||||
array = new PolygonLayer[layers.size()];
|
||||
|
||||
for (int i = 0, n = layers.size(); i < n; i++) {
|
||||
PolygonLayer l = layers.valueAt(i);
|
||||
array[i] = l;
|
||||
for (PolygonLayer l = layers; l != null; l = l.next)
|
||||
size += l.verticesCnt;
|
||||
}
|
||||
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
@ -81,38 +51,40 @@ class PolygonLayers {
|
||||
fbuf.put(mFillCoords, 0, 8);
|
||||
int pos = 4;
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
PolygonLayer l = array[i];
|
||||
PoolItem last = null, items = null;
|
||||
|
||||
for (PoolItem item : l.pool) {
|
||||
for (PolygonLayer l = layers; l != null; l = l.next) {
|
||||
|
||||
for (PoolItem item = l.pool; item != null; item = item.next) {
|
||||
fbuf.put(item.vertices, 0, item.used);
|
||||
last = item;
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
pos += l.verticesCnt;
|
||||
|
||||
LayerPool.add(l.pool);
|
||||
if (last != null) {
|
||||
last.next = items;
|
||||
items = l.pool;
|
||||
}
|
||||
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
fbuf.flip();
|
||||
VertexPool.add(items);
|
||||
|
||||
// not needed for drawing
|
||||
layers = null;
|
||||
fbuf.flip();
|
||||
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
ShortBuffer compileLayerData(ShortBuffer buf) {
|
||||
static final short[] tmpItem = new short[PoolItem.SIZE];
|
||||
|
||||
static ShortBuffer compileLayerData(PolygonLayer layers, ShortBuffer buf) {
|
||||
ShortBuffer sbuf = buf;
|
||||
int size = 4;
|
||||
|
||||
array = new PolygonLayer[layers.size()];
|
||||
|
||||
for (int i = 0, n = layers.size(); i < n; i++) {
|
||||
PolygonLayer l = layers.valueAt(i);
|
||||
array[i] = l;
|
||||
for (PolygonLayer l = layers; l != null; l = l.next)
|
||||
size += l.verticesCnt;
|
||||
}
|
||||
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
@ -124,7 +96,7 @@ class PolygonLayers {
|
||||
sbuf.clear();
|
||||
}
|
||||
|
||||
short[] data = new short[PoolItem.SIZE];
|
||||
short[] data = tmpItem;
|
||||
|
||||
if (mByteFillCoords == null) {
|
||||
mByteFillCoords = new short[8];
|
||||
@ -141,27 +113,38 @@ class PolygonLayers {
|
||||
sbuf.put(mByteFillCoords, 0, 8);
|
||||
int pos = 4;
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
PolygonLayer l = array[i];
|
||||
PoolItem last = null, items = null;
|
||||
|
||||
for (int k = 0, m = l.pool.size(); k < m; k++) {
|
||||
PoolItem item = l.pool.get(k);
|
||||
for (PolygonLayer l = layers; l != null; l = l.next) {
|
||||
|
||||
for (PoolItem item = l.pool; item != null; item = item.next) {
|
||||
PoolItem.toHalfFloat(item, data);
|
||||
sbuf.put(data, 0, item.used);
|
||||
last = item;
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
pos += l.verticesCnt;
|
||||
|
||||
LayerPool.add(l.pool);
|
||||
if (last != null) {
|
||||
last.next = items;
|
||||
items = l.pool;
|
||||
}
|
||||
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
sbuf.flip();
|
||||
VertexPool.add(items);
|
||||
|
||||
// not needed for drawing
|
||||
layers = null;
|
||||
sbuf.flip();
|
||||
|
||||
return sbuf;
|
||||
}
|
||||
|
||||
static void clear(PolygonLayer layers) {
|
||||
for (PolygonLayer l = layers; l != null; l = l.next) {
|
||||
if (l.pool != null)
|
||||
VertexPool.add(l.pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,13 +24,14 @@ import java.nio.IntBuffer;
|
||||
class PoolItem {
|
||||
final float[] vertices;
|
||||
int used;
|
||||
PoolItem next;
|
||||
|
||||
PoolItem() {
|
||||
vertices = new float[SIZE];
|
||||
used = 0;
|
||||
}
|
||||
|
||||
static int SIZE = 256;
|
||||
static int SIZE = 128;
|
||||
|
||||
private static final float FLOAT_HALF_PREC = 5.96046E-8f;
|
||||
private static final float FLOAT_HALF_MAX = 65504f;
|
||||
|
||||
@ -23,6 +23,8 @@ class Shaders {
|
||||
+ "attribute vec2 a_st;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
// + " gl_Position = u_center * vec4(a_position.x, a_position.y, 0.0, 1.0);"
|
||||
// + " v_st = a_position.zw;"
|
||||
+ " gl_Position = u_center * a_position;"
|
||||
+ " v_st = a_st;"
|
||||
+ "}";
|
||||
|
||||
35
src/org/mapsforge/android/glrenderer/TextItem.java
Normal file
35
src/org/mapsforge/android/glrenderer/TextItem.java
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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.mapsforge.android.glrenderer;
|
||||
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
||||
|
||||
public class TextItem {
|
||||
TextItem next;
|
||||
|
||||
final float x, y;
|
||||
final String text;
|
||||
final Caption caption;
|
||||
final float width;
|
||||
|
||||
public TextItem(float x, float y, String text, Caption caption) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.text = text;
|
||||
this.caption = caption;
|
||||
this.width = caption.paint.measureText(text);
|
||||
}
|
||||
|
||||
}
|
||||
28
src/org/mapsforge/android/glrenderer/TextLayer.java
Normal file
28
src/org/mapsforge/android/glrenderer/TextLayer.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
||||
|
||||
public class TextLayer {
|
||||
public ArrayList<TextItem> labels;
|
||||
|
||||
void addLabel(float x, float y, String text, Caption caption) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
405
src/org/mapsforge/android/glrenderer/TextRenderer.java
Normal file
405
src/org/mapsforge/android/glrenderer/TextRenderer.java
Normal file
@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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.mapsforge.android.glrenderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.mapsforge.android.utils.GlUtils;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLUtils;
|
||||
import android.util.Log;
|
||||
|
||||
public class TextRenderer {
|
||||
private final static int TEXTURE_WIDTH = 512;
|
||||
private final static int TEXTURE_HEIGHT = 256;
|
||||
|
||||
final static int MAX_LABELS = 30;
|
||||
|
||||
private final Bitmap mBitmap;
|
||||
private final Canvas mCanvas;
|
||||
private int mFontPadX = 1;
|
||||
private int mFontPadY = 1;
|
||||
private int mBitmapFormat;
|
||||
private int mBitmapType;
|
||||
private ByteBuffer mByteBuffer;
|
||||
private FloatBuffer mFloatBuffer;
|
||||
private TextTexture[] mTextures;
|
||||
|
||||
private int mIndicesVBO;
|
||||
private int mVerticesVBO;
|
||||
|
||||
final static int INDICES_PER_SPRITE = 6; // Indices Per Sprite
|
||||
final static int VERTICES_PER_SPRITE = 4; // Vertices Per Sprite
|
||||
final static int FLOATS_PER_VERTICE = 4;
|
||||
|
||||
private static int mTextProgram;
|
||||
static int mTextUVPMatrixLocation;
|
||||
static int mTextVertexLocation;
|
||||
static int mTextTextureCoordLocation;
|
||||
static int mTextUColorLocation;
|
||||
|
||||
static Paint mPaint = new Paint(Color.BLACK);
|
||||
|
||||
boolean debug = false;
|
||||
float[] debugVertices = {
|
||||
|
||||
0, 0,
|
||||
0, 1,
|
||||
|
||||
0, TEXTURE_HEIGHT - 1,
|
||||
0, 0,
|
||||
|
||||
TEXTURE_WIDTH - 1, 0,
|
||||
1, 1,
|
||||
|
||||
TEXTURE_WIDTH - 1, TEXTURE_HEIGHT - 1,
|
||||
1, 0,
|
||||
|
||||
};
|
||||
|
||||
TextRenderer(int numTextures) {
|
||||
mBitmap = Bitmap
|
||||
.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
|
||||
mBitmapFormat = GLUtils.getInternalFormat(mBitmap);
|
||||
mBitmapType = GLUtils.getType(mBitmap);
|
||||
|
||||
mTextProgram = GlUtils.createProgram(textVertexShader, textFragmentShader);
|
||||
|
||||
mTextUVPMatrixLocation = GLES20.glGetUniformLocation(mTextProgram, "mvp");
|
||||
mTextUColorLocation = GLES20.glGetUniformLocation(mTextProgram, "col");
|
||||
mTextVertexLocation = GLES20.glGetAttribLocation(mTextProgram, "vertex");
|
||||
mTextTextureCoordLocation = GLES20.glGetAttribLocation(mTextProgram, "tex_coord");
|
||||
|
||||
// mVertexBuffer = new float[];
|
||||
int bufferSize = numTextures
|
||||
* MAX_LABELS * VERTICES_PER_SPRITE
|
||||
* FLOATS_PER_VERTICE * (Float.SIZE / 8);
|
||||
|
||||
mByteBuffer = ByteBuffer.allocateDirect(bufferSize)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
|
||||
mFloatBuffer = mByteBuffer.asFloatBuffer();
|
||||
|
||||
int[] textureIds = new int[numTextures];
|
||||
TextTexture[] textures = new TextTexture[numTextures];
|
||||
GLES20.glGenTextures(numTextures, textureIds, 0);
|
||||
|
||||
for (int i = 0; i < numTextures; i++) {
|
||||
// setup filters for texture
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIds[i]);
|
||||
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
|
||||
GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
|
||||
GLES20.GL_LINEAR);
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
|
||||
GLES20.GL_CLAMP_TO_EDGE); // Set U Wrapping
|
||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
|
||||
GLES20.GL_CLAMP_TO_EDGE); // Set V Wrapping
|
||||
|
||||
// load the generated bitmap onto the texture
|
||||
// GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mBitmap, 0);
|
||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mBitmapFormat, mBitmap,
|
||||
mBitmapType, 0);
|
||||
|
||||
textures[i] = new TextTexture(textureIds[i]);
|
||||
}
|
||||
GlUtils.checkGlError("init textures");
|
||||
|
||||
mTextures = textures;
|
||||
|
||||
// Setup triangle indices
|
||||
short[] indices = new short[MAX_LABELS * INDICES_PER_SPRITE];
|
||||
int len = indices.length;
|
||||
short j = 0;
|
||||
for (int i = 0; i < len; i += INDICES_PER_SPRITE, j += VERTICES_PER_SPRITE) {
|
||||
indices[i + 0] = (short) (j + 0);
|
||||
indices[i + 1] = (short) (j + 1);
|
||||
indices[i + 2] = (short) (j + 2);
|
||||
indices[i + 3] = (short) (j + 2);
|
||||
indices[i + 4] = (short) (j + 3);
|
||||
indices[i + 5] = (short) (j + 0);
|
||||
}
|
||||
|
||||
ShortBuffer tmpIndices = mByteBuffer.asShortBuffer();
|
||||
|
||||
tmpIndices.put(indices, 0, len);
|
||||
tmpIndices.flip();
|
||||
|
||||
int[] mVboIds = new int[2];
|
||||
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mVboIds[0]);
|
||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, len * (Short.SIZE / 8),
|
||||
tmpIndices,
|
||||
GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
mIndicesVBO = mVboIds[0];
|
||||
mVerticesVBO = mVboIds[1];
|
||||
}
|
||||
|
||||
boolean drawToTexture(GLMapTile tile) {
|
||||
TextTexture tex = null;
|
||||
|
||||
if (tile.labels.size() == 0)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < mTextures.length; i++) {
|
||||
tex = mTextures[i];
|
||||
if (tex.tile == null)
|
||||
break;
|
||||
if (!tex.tile.isActive)
|
||||
break;
|
||||
|
||||
tex = null;
|
||||
}
|
||||
|
||||
if (tex == null) {
|
||||
Log.d(TAG, "no textures left");
|
||||
return false;
|
||||
}
|
||||
if (tex.tile != null)
|
||||
tex.tile.texture = null;
|
||||
|
||||
// if (debug)
|
||||
// mBitmap.eraseColor(0xaa0000aa);
|
||||
// else
|
||||
mBitmap.eraseColor(Color.TRANSPARENT);
|
||||
|
||||
int pos = 0;
|
||||
float[] buf = tex.vertices;
|
||||
|
||||
float xx = mFontPadX;
|
||||
float yy = 0;
|
||||
float width, height;
|
||||
|
||||
float y = 0;
|
||||
float x = 0;
|
||||
|
||||
int max = tile.labels.size();
|
||||
if (max > MAX_LABELS)
|
||||
max = MAX_LABELS;
|
||||
|
||||
if (debug) {
|
||||
mCanvas.drawLine(debugVertices[0], debugVertices[1], debugVertices[4],
|
||||
debugVertices[5], mPaint);
|
||||
mCanvas.drawLine(debugVertices[0], debugVertices[1], debugVertices[8],
|
||||
debugVertices[9], mPaint);
|
||||
|
||||
mCanvas.drawLine(debugVertices[12], debugVertices[13], debugVertices[4],
|
||||
debugVertices[5], mPaint);
|
||||
mCanvas.drawLine(debugVertices[12], debugVertices[13], debugVertices[8],
|
||||
debugVertices[9], mPaint);
|
||||
}
|
||||
int advanceY = 0;
|
||||
// int advanceX = 0;
|
||||
for (int i = 0; i < max; i++) {
|
||||
TextItem t = tile.labels.get(i);
|
||||
|
||||
height = (int) (t.caption.fontHeight) + 2 * mFontPadY;
|
||||
width = t.width + 2 * mFontPadX;
|
||||
|
||||
if (height > advanceY)
|
||||
advanceY = (int) height;
|
||||
|
||||
if (xx + width > TEXTURE_WIDTH) {
|
||||
xx = mFontPadX;
|
||||
y += advanceY;
|
||||
advanceY = (int) height;
|
||||
}
|
||||
|
||||
yy = y + (height - 1) - t.caption.fontDescent - mFontPadY;
|
||||
|
||||
if (t.caption.stroke != null)
|
||||
mCanvas.drawText(t.text, xx + t.width / 2, yy, t.caption.stroke);
|
||||
|
||||
mCanvas.drawText(t.text, xx + t.width / 2, yy, t.caption.paint);
|
||||
|
||||
// Log.d(TAG, "draw: " + t.text + " at:" + (xx + t.width / 2) + " " + yy + " w:"
|
||||
// + t.width + " " + cellHeight);
|
||||
|
||||
if (width > TEXTURE_WIDTH)
|
||||
width = TEXTURE_WIDTH;
|
||||
|
||||
float halfWidth = width / 2.0f;
|
||||
float halfHeight = height / 2.0f;
|
||||
float x1 = t.x - halfWidth;
|
||||
float y1 = t.y - halfHeight;
|
||||
float x2 = t.x + halfWidth;
|
||||
float y2 = t.y + halfHeight;
|
||||
|
||||
float u1 = xx / TEXTURE_WIDTH;
|
||||
float v1 = y / TEXTURE_HEIGHT;
|
||||
float u2 = u1 + (width / TEXTURE_WIDTH);
|
||||
float v2 = v1 + (height / TEXTURE_HEIGHT);
|
||||
|
||||
buf[pos++] = x1;
|
||||
buf[pos++] = y1;
|
||||
buf[pos++] = u1;
|
||||
buf[pos++] = v2;
|
||||
|
||||
buf[pos++] = x2;
|
||||
buf[pos++] = y1;
|
||||
buf[pos++] = u2;
|
||||
buf[pos++] = v2;
|
||||
|
||||
buf[pos++] = x2;
|
||||
buf[pos++] = y2;
|
||||
buf[pos++] = u2;
|
||||
buf[pos++] = v1;
|
||||
|
||||
buf[pos++] = x1;
|
||||
buf[pos++] = y2;
|
||||
buf[pos++] = u1;
|
||||
buf[pos++] = v1;
|
||||
|
||||
// yy += cellHeight;
|
||||
// x += width;
|
||||
|
||||
xx += width;
|
||||
|
||||
// y += cellHeight;
|
||||
if (y > TEXTURE_HEIGHT) {
|
||||
Log.d(TAG, "reached max labels");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tex.length = pos;
|
||||
tile.texture = tex;
|
||||
tex.tile = tile;
|
||||
// GlUtils.checkGlError("0");
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.id);
|
||||
// GlUtils.checkGlError("1");
|
||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mBitmap, mBitmapFormat,
|
||||
mBitmapType);
|
||||
// GlUtils.checkGlError("2");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String TAG = "TextRenderer";
|
||||
|
||||
void compileTextures() {
|
||||
int offset = 0;
|
||||
TextTexture tex;
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
|
||||
|
||||
mFloatBuffer.clear();
|
||||
|
||||
for (int i = 0; i < mTextures.length; i++) {
|
||||
tex = mTextures[i];
|
||||
if (tex.tile == null || !tex.tile.isActive)
|
||||
continue;
|
||||
|
||||
mFloatBuffer.put(tex.vertices, 0, tex.length);
|
||||
tex.offset = offset;
|
||||
offset += tex.length;
|
||||
}
|
||||
|
||||
mFloatBuffer.flip();
|
||||
// Log.d(TAG, "compileTextures" + mFloatBuffer.remaining() + " " + offset);
|
||||
|
||||
// TODO use sub-bufferdata function
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, offset * (Float.SIZE / 8),
|
||||
mFloatBuffer, GLES20.GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
void beginDraw() {
|
||||
GLES20.glUseProgram(mTextProgram);
|
||||
|
||||
GLES20.glEnableVertexAttribArray(mTextTextureCoordLocation);
|
||||
GLES20.glEnableVertexAttribArray(mTextVertexLocation);
|
||||
|
||||
if (debug) {
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
mFloatBuffer.clear();
|
||||
mFloatBuffer.put(debugVertices, 0, 16);
|
||||
mFloatBuffer.flip();
|
||||
GLES20.glVertexAttribPointer(mTextVertexLocation, 2,
|
||||
GLES20.GL_FLOAT, false, 16, mFloatBuffer);
|
||||
mFloatBuffer.position(2);
|
||||
GLES20.glVertexAttribPointer(mTextTextureCoordLocation, 2,
|
||||
GLES20.GL_FLOAT, false, 16, mFloatBuffer);
|
||||
} else {
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
|
||||
}
|
||||
}
|
||||
|
||||
void endDraw() {
|
||||
|
||||
GLES20.glDisableVertexAttribArray(mTextTextureCoordLocation);
|
||||
GLES20.glDisableVertexAttribArray(mTextVertexLocation);
|
||||
}
|
||||
|
||||
void drawTile(GLMapTile tile, float[] matrix) {
|
||||
|
||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.texture.id);
|
||||
GlUtils.checkGlError("bind");
|
||||
|
||||
GLES20.glUniformMatrix4fv(mTextUVPMatrixLocation, 1, false, matrix, 0);
|
||||
GlUtils.checkGlError("matrix");
|
||||
|
||||
if (debug) {
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
} else {
|
||||
|
||||
GLES20.glVertexAttribPointer(mTextVertexLocation, 2,
|
||||
GLES20.GL_FLOAT, false, 16, tile.texture.offset * 4);
|
||||
|
||||
GLES20.glVertexAttribPointer(mTextTextureCoordLocation, 2,
|
||||
GLES20.GL_FLOAT, false, 16, tile.texture.offset * 4 + 8);
|
||||
|
||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, (tile.texture.length / 16) *
|
||||
INDICES_PER_SPRITE, GLES20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String textVertexShader = ""
|
||||
+ "precision highp float; "
|
||||
+ "attribute vec4 vertex;"
|
||||
+ "attribute vec2 tex_coord;"
|
||||
+ "uniform mat4 mvp;"
|
||||
+ "varying vec2 tex_c;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = mvp * vertex;"
|
||||
+ " tex_c = tex_coord;"
|
||||
+ "}";
|
||||
|
||||
private static String textFragmentShader = ""
|
||||
+ "precision highp float;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ "uniform vec4 col;"
|
||||
+ "varying vec2 tex_c;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = texture2D(tex, tex_c);"
|
||||
+ "}";
|
||||
|
||||
}
|
||||
32
src/org/mapsforge/android/glrenderer/TextTexture.java
Normal file
32
src/org/mapsforge/android/glrenderer/TextTexture.java
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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.mapsforge.android.glrenderer;
|
||||
|
||||
public class TextTexture {
|
||||
|
||||
final float[] vertices;
|
||||
final int id;
|
||||
int length;
|
||||
int offset;
|
||||
GLMapTile tile;
|
||||
|
||||
String[] text;
|
||||
|
||||
TextTexture(int textureID) {
|
||||
vertices = new float[TextRenderer.MAX_LABELS * 16];
|
||||
id = textureID;
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,40 +15,62 @@
|
||||
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
class LayerPool {
|
||||
static private LinkedList<PoolItem> pool = null;
|
||||
static private int count;
|
||||
class VertexPool {
|
||||
private static final int POOL_LIMIT = 8192;
|
||||
|
||||
@SuppressLint("UseValueOf")
|
||||
private static final Boolean lock = new Boolean(true);
|
||||
|
||||
static private PoolItem pool = null;
|
||||
static private int count = 0;
|
||||
|
||||
static void init() {
|
||||
if (pool == null) {
|
||||
pool = new LinkedList<PoolItem>();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static PoolItem get() {
|
||||
synchronized (pool) {
|
||||
synchronized (lock) {
|
||||
|
||||
if (count == 0)
|
||||
return new PoolItem();
|
||||
|
||||
count--;
|
||||
PoolItem it = pool.pop();
|
||||
|
||||
PoolItem it = pool;
|
||||
pool = pool.next;
|
||||
it.used = 0;
|
||||
it.next = null;
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
static void add(LinkedList<PoolItem> items) {
|
||||
synchronized (pool) {
|
||||
int size = items.size();
|
||||
static void add(PoolItem items) {
|
||||
if (items == null)
|
||||
return;
|
||||
|
||||
while (count < 4096 && size-- > 0) {
|
||||
synchronized (lock) {
|
||||
PoolItem last = items;
|
||||
|
||||
// limit pool items
|
||||
while (count < POOL_LIMIT) {
|
||||
if (last.next == null) {
|
||||
break;
|
||||
}
|
||||
last = last.next;
|
||||
count++;
|
||||
pool.add(items.pop());
|
||||
}
|
||||
|
||||
// clear references
|
||||
PoolItem tmp2, tmp = last.next;
|
||||
while (tmp != null) {
|
||||
tmp2 = tmp;
|
||||
tmp = tmp.next;
|
||||
tmp2.next = null;
|
||||
}
|
||||
|
||||
last.next = pool;
|
||||
pool = items;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,7 @@ import org.mapsforge.core.Tile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
@ -59,7 +60,8 @@ public class TouchHandler {
|
||||
mMapView = mapView;
|
||||
mMapMoveDelta = viewConfiguration.getScaledTouchSlop();
|
||||
mActivePointerId = INVALID_POINTER_ID;
|
||||
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener(mMapView));
|
||||
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleListener(
|
||||
mMapView));
|
||||
mGestureDetector = new GestureDetector(new MapGestureDetector(mMapView));
|
||||
}
|
||||
|
||||
@ -90,7 +92,8 @@ public class TouchHandler {
|
||||
boolean scaling = mScaleGestureDetector.isInProgress();
|
||||
if (!scaling && !mMoveThresholdReached) {
|
||||
|
||||
if (Math.abs(moveX) > 3 * mMapMoveDelta || Math.abs(moveY) > 3 * mMapMoveDelta) {
|
||||
if (Math.abs(moveX) > 3 * mMapMoveDelta
|
||||
|| Math.abs(moveY) > 3 * mMapMoveDelta) {
|
||||
// the map movement threshold has been reached
|
||||
// longPressDetector.pressStop();
|
||||
mMoveThresholdReached = true;
|
||||
@ -179,15 +182,19 @@ public class TouchHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private long lastRun = 0;
|
||||
|
||||
/**
|
||||
* @param motionEvent
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public boolean handleMotionEvent(MotionEvent motionEvent) {
|
||||
|
||||
// workaround for a bug in the ScaleGestureDetector, see Android issue
|
||||
// #12976
|
||||
if (motionEvent.getAction() != MotionEvent.ACTION_MOVE || motionEvent.getPointerCount() > 1) {
|
||||
if (motionEvent.getAction() != MotionEvent.ACTION_MOVE
|
||||
|| motionEvent.getPointerCount() > 1) {
|
||||
mScaleGestureDetector.onTouchEvent(motionEvent);
|
||||
}
|
||||
|
||||
@ -197,23 +204,44 @@ public class TouchHandler {
|
||||
// // return true;
|
||||
// }
|
||||
int action = getAction(motionEvent);
|
||||
|
||||
boolean ret = false;
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
return onActionDown(motionEvent);
|
||||
ret = onActionDown(motionEvent);
|
||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||
return onActionMove(motionEvent);
|
||||
ret = onActionMove(motionEvent);
|
||||
} else if (action == MotionEvent.ACTION_UP) {
|
||||
return onActionUp(motionEvent);
|
||||
ret = onActionUp(motionEvent);
|
||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||
return onActionCancel();
|
||||
ret = onActionCancel();
|
||||
// } else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
// return onActionPointerDown(motionEvent);
|
||||
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
||||
return onActionPointerUp(motionEvent);
|
||||
ret = onActionPointerUp(motionEvent);
|
||||
}
|
||||
|
||||
// if (ret) {
|
||||
// Log.d("", "" + );
|
||||
//
|
||||
// // try {
|
||||
// //
|
||||
// // Thread.sleep(10);
|
||||
// // } catch (InterruptedException e) {
|
||||
// // // TODO Auto-generated catch block
|
||||
// // // e.printStackTrace();
|
||||
// // }
|
||||
//
|
||||
// }
|
||||
if (ret) {
|
||||
// throttle input
|
||||
long diff = SystemClock.uptimeMillis() - lastRun;
|
||||
if (diff < 16) {
|
||||
// Log.d("", "" + diff);
|
||||
SystemClock.sleep(16 - diff);
|
||||
}
|
||||
lastRun = SystemClock.uptimeMillis();
|
||||
}
|
||||
// the event was not handled
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
class MapGestureDetector extends SimpleOnGestureListener {
|
||||
@ -254,7 +282,8 @@ public class TouchHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||
float velocityY) {
|
||||
int w = Tile.TILE_SIZE * 20;
|
||||
int h = Tile.TILE_SIZE * 20;
|
||||
mPrevX = 0;
|
||||
@ -265,7 +294,8 @@ public class TouchHandler {
|
||||
mTimer = null;
|
||||
}
|
||||
|
||||
mScroller.fling(0, 0, Math.round(velocityX) / 2, Math.round(velocityY) / 2, -w, w, -h, h);
|
||||
mScroller.fling(0, 0, Math.round(velocityX) / 2, Math.round(velocityY) / 2,
|
||||
-w, w, -h, h);
|
||||
// animate for two seconds
|
||||
mTimer = new CountDownTimer(2000, 20) {
|
||||
@Override
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
package org.mapsforge.android.rendertheme;
|
||||
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
@ -37,14 +38,8 @@ public interface IRenderCallback {
|
||||
*
|
||||
* @param caption
|
||||
* the text to be rendered.
|
||||
* @param verticalOffset
|
||||
* the vertical offset of the caption.
|
||||
* @param paint
|
||||
* the paint to be used for rendering the text.
|
||||
* @param stroke
|
||||
* an optional paint for the text casing (may be null).
|
||||
*/
|
||||
void renderAreaCaption(String caption, float verticalOffset, Paint paint, Paint stroke);
|
||||
void renderAreaCaption(Caption caption);
|
||||
|
||||
/**
|
||||
* Renders an area symbol with the given bitmap.
|
||||
@ -59,14 +54,8 @@ public interface IRenderCallback {
|
||||
*
|
||||
* @param caption
|
||||
* the text to be rendered.
|
||||
* @param verticalOffset
|
||||
* the vertical offset of the caption.
|
||||
* @param paint
|
||||
* the paint to be used for rendering the text.
|
||||
* @param stroke
|
||||
* an optional paint for the text casing (may be null).
|
||||
*/
|
||||
void renderPointOfInterestCaption(String caption, float verticalOffset, Paint paint, Paint stroke);
|
||||
void renderPointOfInterestCaption(Caption caption);
|
||||
|
||||
/**
|
||||
* Renders a point of interest circle with the given parameters.
|
||||
|
||||
@ -140,7 +140,7 @@ public class RenderTheme {
|
||||
public void matchNode(IRenderCallback renderCallback, Tag[] tags, byte zoomLevel) {
|
||||
// List<RenderInstruction> matchingList = matchingListNode;
|
||||
// MatchingCacheKey matchingCacheKey = matchingCacheKeyNode;
|
||||
//
|
||||
|
||||
// if (!changed) {
|
||||
// if (matchingList != null) {
|
||||
// for (int i = 0, n = matchingList.size(); i < n; ++i) {
|
||||
@ -158,11 +158,13 @@ public class RenderTheme {
|
||||
// matchingList.get(i).renderNode(renderCallback, tags);
|
||||
// }
|
||||
// } else {
|
||||
// // cache miss
|
||||
|
||||
// cache miss
|
||||
// matchingList = new ArrayList<RenderInstruction>();
|
||||
// for (int i = 0, n = mRulesList.size(); i < n; ++i) {
|
||||
// mRulesList.get(i).matchNode(renderCallback, tags, zoomLevel, matchingList);
|
||||
// }
|
||||
for (int i = 0, n = mRulesList.size(); i < n; ++i) {
|
||||
mRulesList.get(i).matchNode(renderCallback, tags, zoomLevel);
|
||||
// , matchingList
|
||||
}
|
||||
// matchingCacheNodes.put(matchingCacheKey, matchingList);
|
||||
// }
|
||||
//
|
||||
@ -214,7 +216,7 @@ public class RenderTheme {
|
||||
public synchronized RenderInstruction[] matchWay(IRenderCallback renderCallback,
|
||||
Tag[] tags,
|
||||
byte zoomLevel,
|
||||
boolean closed, boolean changed) {
|
||||
boolean closed, boolean render) {
|
||||
RenderInstruction[] renderInstructions = null;
|
||||
|
||||
LRUCache<MatchingCacheKey, RenderInstruction[]> matchingCache;
|
||||
@ -240,12 +242,6 @@ public class RenderTheme {
|
||||
boolean found = matchingCache.containsKey(matchingCacheKey);
|
||||
if (found) {
|
||||
renderInstructions = matchingCache.get(matchingCacheKey);
|
||||
|
||||
if (renderInstructions != null) {
|
||||
for (int i = 0, n = renderInstructions.length; i < n; i++)
|
||||
renderInstructions[i].renderWay(renderCallback, tags);
|
||||
|
||||
}
|
||||
} else {
|
||||
// cache miss
|
||||
int c = (closed ? Closed.YES : Closed.NO);
|
||||
@ -259,13 +255,17 @@ public class RenderTheme {
|
||||
renderInstructions = new RenderInstruction[matchingList.size()];
|
||||
for (int i = 0, n = matchingList.size(); i < n; ++i) {
|
||||
RenderInstruction renderInstruction = matchingList.get(i);
|
||||
renderInstruction.renderWay(renderCallback, tags);
|
||||
|
||||
renderInstructions[i] = renderInstruction;
|
||||
}
|
||||
}
|
||||
matchingCache.put(matchingCacheKey, renderInstructions);
|
||||
}
|
||||
|
||||
if (render && renderInstructions != null) {
|
||||
for (int i = 0, n = renderInstructions.length; i < n; i++)
|
||||
renderInstructions[i].renderWay(renderCallback, tags);
|
||||
}
|
||||
// mRenderInstructions = renderInstructions;
|
||||
return renderInstructions;
|
||||
}
|
||||
|
||||
@ -5,29 +5,36 @@
|
||||
version="1" map-background="#f0f0f0">
|
||||
|
||||
<!-- ways -->
|
||||
<rule e="way" k="*" v="*">
|
||||
<rule e="way" k="*" v="*" >
|
||||
|
||||
<!-- landuse -->
|
||||
<rule e="way" k="natural" v="grassland|scrub" zoom-min="9">
|
||||
<area fill="#ebf2d2" fade="10" />
|
||||
</rule>
|
||||
|
||||
<!-- landuse base -->
|
||||
<rule e="way" k="landuse" v="*">
|
||||
<rule e="way" k="*" v="farmland|farm">
|
||||
<rule e="way" k="*" v="military">
|
||||
<area fill="#dddddd"/>
|
||||
<line stroke="#666666" stroke-width="1.5" fixed="true"/>
|
||||
</rule>
|
||||
<rule e="way" k="*" v="farmland|farm|orchard|vine_yard|greenhouse_horticulture|plant_nursery">
|
||||
<area fill="#fff8bf" fade="10" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="landuse" v="grass">
|
||||
<area fill="#deecb9" fade="10" />
|
||||
<!-- Steinbruch, Schotter-, Kies-, Sand- und Tongrube -->
|
||||
<rule e="way" k="*" v="quarry">
|
||||
<area fill="#ddddcc" fade="10" />
|
||||
</rule>
|
||||
|
||||
|
||||
<rule e="way" k="*" v="residential|farmyard|retail|commercial">
|
||||
<area fill="#efefeb" fade="10" />
|
||||
</rule>
|
||||
|
||||
<!-- <rule e="way" k="landuse" v="industrial|brownfield|railway"> <area
|
||||
fill="#bcaacd" stroke="#e4e4e4" stroke-width="0.2" /> -->
|
||||
<rule e="way" k="*" v="industrial|railway"> <area
|
||||
fill="#e8e3e4" stroke="#e4e4e4" stroke-width="0.2" fade="10" />
|
||||
</rule>
|
||||
<!--<rule e="way" k="landuse" v="construction|greenfield"> <area fill="#a47c41"
|
||||
stroke="#e4e4e4" stroke-width="0.2" /> </rule> -->
|
||||
<!-- <rule e="way" k="landuse" v="garages"> <area fill="#d6d6e4" /> </rule> -->
|
||||
|
||||
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="outline" v="*">
|
||||
@ -99,15 +106,16 @@
|
||||
</rule>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
<!-- landuse -->
|
||||
<rule e="way" k="landuse" v="*" >
|
||||
<rule e="way" k="landuse" v="*" zoom-min="10">
|
||||
<!-- <rule e="way" k="*" v="landfill|quarry"> <area fill="#e9dd72" stroke="#556b2f"
|
||||
stroke-width="0.2" /> </rule> -->
|
||||
<rule e="way" k="*" v="cemetery">
|
||||
<area fill="#d7e6b0" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="meadow|scrub">
|
||||
<area fill="#deecb9" />
|
||||
<rule e="way" k="*" v="meadow">
|
||||
<area fill="#ebf2d2" fade="10"/>
|
||||
</rule>
|
||||
|
||||
<!-- <rule e="way" k="*" v="village_green|recreation_ground">
|
||||
@ -122,7 +130,12 @@
|
||||
</rule>
|
||||
|
||||
|
||||
<rule e="way" k="leisure|landuse" v="allotments|village_green|recreation_ground|garden|golf_course|dog_park" zoom-min="12">
|
||||
<!-- garden -->
|
||||
<rule e="way" k="leisure" v="golf_course|dog_park" zoom-min="12">
|
||||
<area fill="#e7f7c1" fade="12" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="landuse" v="allotments|village_green|recreation_ground" zoom-min="12">
|
||||
<area fill="#e7f7c1" fade="12" />
|
||||
</rule>
|
||||
|
||||
@ -132,19 +145,35 @@
|
||||
<area fill="#d7e6b0" fade="12" />
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
|
||||
<rule e="way" k="natural|landuse" v="forest|wood" zoom-min="9">
|
||||
<!-- <area fill="#BCCBB0" fade="10" /> -->
|
||||
<!-- <rule e="way" k="*" v="*" zoom-max="11"> -->
|
||||
<area fill="#d3dec8" fade="9" />
|
||||
<!-- </rule> -->
|
||||
<!-- <rule e="way" k="*" v="*" zoom-min="12">
|
||||
<area fill="#cde2bc" fade="12" />
|
||||
</rule> -->
|
||||
<!-- <area fill="#87a670" fade="10" /> -->
|
||||
|
||||
|
||||
<rule e="way" k="natural|" v="*">
|
||||
<rule e="way" k="*" v="wood">
|
||||
<rule e="way" k="*" v="*" zoom-max="12">
|
||||
<area fill="#ebefe5" fade="7" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="*" zoom-min="11">
|
||||
<area fill="#d3dec8" fade="12" />
|
||||
</rule>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
|
||||
<rule e="way" k="landuse" v="*">
|
||||
<rule e="way" k="*" v="forest">
|
||||
<rule e="way" k="*" v="*" zoom-max="12">
|
||||
<area fill="#ebefe5" fade="7" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="*" zoom-min="11">
|
||||
<area fill="#d3dec8" fade="12" />
|
||||
</rule>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
<!-- keep grass above forest:wood and leisure:park! -->
|
||||
<rule e="way" k="landuse" v="grass">
|
||||
<area fill="#ebf2d2" fade="10" />
|
||||
</rule>
|
||||
|
||||
|
||||
<!-- amenity -->
|
||||
<rule e="way" k="amenity" v="*">
|
||||
@ -181,7 +210,7 @@
|
||||
<rule e="way" k="*" zoom-min="12" v="heath">
|
||||
<area fill="#ffffc0" fade="12" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="marsh|wetland">
|
||||
<rule e="way" k="*" v="marsh|wetland|mud">
|
||||
<area fill="#deecb9" fade="12" />
|
||||
</rule>
|
||||
</rule>
|
||||
@ -190,14 +219,23 @@
|
||||
<!-- leisure -->
|
||||
<rule e="way" k="leisure" v="*" zoom-min="13">
|
||||
|
||||
<!-- playground| -->
|
||||
|
||||
<rule e="way" k="*" v="stadium" zoom-min="14">>
|
||||
<line stroke="#c9c3c1" stroke-width="0.6" fixed="true" stroke-linecap="butt" />
|
||||
<area fill="#e9e6e3" fade="15" />
|
||||
</rule>
|
||||
|
||||
<!-- sollte unter playing field sein -->
|
||||
<rule e="way" k="*" zoom_min="14" v="sports_centre|water_park">
|
||||
<rule e="way" k="*" zoom-min="14" v="sports_centre|water_park">
|
||||
<area fill="#daefdb" fade="12" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="*" zoom-min="15">
|
||||
<rule e="way" k="*" v="*" zoom-min="14">
|
||||
<rule e="way" k="*" v="playground|miniature_golf">
|
||||
<area fill="#f4f4de" />
|
||||
<line stroke="#fbdbc8" stroke-width="0.6" fixed="true"
|
||||
stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="playing_fields|pitch">
|
||||
<area fill="#f4f4de" />
|
||||
<line stroke="#dbdbc8" stroke-width="0.6" fixed="true"
|
||||
@ -235,10 +273,10 @@
|
||||
<line stroke="#b4cbdc" stroke-width="0.275" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="waterway" v="river" zoom-min="12">
|
||||
<line stroke="#b4cbdc" stroke-width="1.0" stroke-linecap="butt" />
|
||||
<line stroke="#b4cbdc" stroke-width="1.3" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="waterway" v="river" zoom-max="11">
|
||||
<line stroke="#b4cbdc" stroke-width="1.0" stroke-linecap="butt"
|
||||
<line stroke="#b4cbdc" stroke-width="1.3" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
</rule>
|
||||
<rule e="way" k="waterway" v="riverbank|dock">
|
||||
@ -346,6 +384,8 @@
|
||||
</rule> -->
|
||||
</rule>
|
||||
|
||||
|
||||
|
||||
<rule e="way" k="outline" v="*">
|
||||
<rule e="way" k="*" v="1">
|
||||
<outline stroke="#909090" />
|
||||
@ -371,30 +411,30 @@
|
||||
<rule e="way" k="*" v="secondary|primary_link" zoom-min="9">
|
||||
<!-- <line stroke="#eeee4a" stroke-width="1.8" stroke-linecap="butt"
|
||||
fixed="true" /> -->
|
||||
<line stroke="#f2df6d" stroke-width="1.9" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
<line stroke="#f2df6d" stroke-width="1.8" stroke-linecap="butt"
|
||||
fixed="true" fade="9"/>
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="trunk_link|motorway_link" zoom-min="8">
|
||||
<line stroke="#fed6a3" stroke-width="2.0" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
<line stroke="#fed6a3" stroke-width="1.8" stroke-linecap="butt"
|
||||
fixed="true" fade="8"/>
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="primary" zoom-min="6">
|
||||
<rule e="way" k="*" v="primary" zoom-min="5">
|
||||
<!-- <line stroke="#eeee4a" stroke-width="1.4" stroke-linecap="butt"
|
||||
fixed="true" /> -->
|
||||
<line stroke="#f2df6d" stroke-width="2.0" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
<line stroke="#f2df6d" stroke-width="1.8" stroke-linecap="butt"
|
||||
fixed="true" fade="5"/>
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="trunk" zoom-min="7">
|
||||
<rule e="way" k="*" v="trunk" zoom-min="5">
|
||||
<line stroke="#fed6a3" stroke-width="2.0" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
fixed="true" fade="5"/>
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="motorway">
|
||||
<line stroke="#eec693" stroke-width="2.4" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
<line stroke="#eec693" stroke-width="2.2" stroke-linecap="butt"
|
||||
fixed="true" fade="4"/>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -403,11 +443,11 @@
|
||||
<rule e="way" k="*" v="*" zoom-min="15">
|
||||
|
||||
<rule e="way" k="*" v="steps">
|
||||
<line stroke="#f1f0f4" stroke-width="0.35" outline="2"
|
||||
<line stroke="#f1f0f4" stroke-width="0.25" outline="2"
|
||||
stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="track|footway|path|cycleway" zoom-min="16">
|
||||
<line stroke="#c1bcb6" stroke-width="0.30" stroke-linecap="butt" />
|
||||
<line stroke="#c1bcb6" stroke-width="0.20" stroke-linecap="butt" />
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -426,7 +466,7 @@
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="construction">
|
||||
<line stroke="#d0d0d0" stroke-width="1.3" outline="1" />
|
||||
<line stroke="#d0d0d0" stroke-width="1.2" outline="1" />
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -434,10 +474,10 @@
|
||||
|
||||
<rule e="way" k="*" v="residential|road|unclassified|living_street">
|
||||
<rule e="way" k="bridge" v="yes|true">
|
||||
<line stroke="#ffffff" stroke-width="1.3" outline="2" stroke-linecap="butt" />
|
||||
<line stroke="#ffffff" stroke-width="1.2" outline="2" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="bridge" v="~|no|false">
|
||||
<line stroke="#ffffff" stroke-width="1.3" outline="1" />
|
||||
<line stroke="#ffffff" stroke-width="1.2" outline="1" />
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -558,11 +598,11 @@
|
||||
</rule>
|
||||
|
||||
<!-- railway casings and cores -->
|
||||
<rule e="way" k="railway" v="tram">
|
||||
<rule e="way" k="railway" v="tram" zoom-min="14">
|
||||
<line stroke="#8c8f8c" stroke-width="0.8" fixed="true" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="railway" v="light_rail|subway|narrow_gauge">
|
||||
<rule e="way" k="railway" v="light_rail|subway|narrow_gauge" zoom-min="14">
|
||||
<line stroke="#a0a0a0" stroke-width="0.8" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
|
||||
@ -579,6 +619,12 @@
|
||||
<line stroke="#bbbbcc" stroke-width="0.6" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
</rule>
|
||||
|
||||
<!-- whatever railway:spur means ... -->
|
||||
<rule e="way" k="railway" v="disused|spur|abandoned|preserved" >
|
||||
<line stroke="#cccccc" stroke-width="0.6" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
</rule>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -634,6 +680,15 @@
|
||||
<caption k="name" font-style="bold" font-size="10" fill="#000000"
|
||||
stroke="#ffffff" stroke-width="2.0" />
|
||||
</rule>
|
||||
<rule e="way" k="debug" v="area">
|
||||
<line stroke="#ff0000" stroke-width="1.2" fixed="true" stroke-linecap="butt" />
|
||||
<area fill="#880000ff"/>
|
||||
<caption k="name" font-size="15" fill="#ffffff" stroke="#000000" stroke-width="2.0"/>
|
||||
</rule>
|
||||
<rule e="way" k="debug" v="way">
|
||||
<line stroke="#00ffff" stroke-width="1.5" fixed="true" stroke-linecap="butt" />
|
||||
<caption k="name" font-size="15" fill="#ffffff" stroke="#000000" stroke-width="2.0"/>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
<rule e="node" k="*" v="*">
|
||||
@ -642,6 +697,10 @@
|
||||
<circle r="1.5" fill="#909090" />
|
||||
</rule>
|
||||
|
||||
<rule e="node" k="debug" v="*" >
|
||||
<caption k="name" font-size="12" fill="#0000ff" />
|
||||
</rule>
|
||||
|
||||
|
||||
<!-- highway -->
|
||||
<!-- <rule e="node" k="highway" v="*"> <rule e="node" k="highway" v="turning_circle">
|
||||
@ -671,12 +730,12 @@
|
||||
<caption k="name" font-style="bold" font-size="20" fill="#000000"
|
||||
stroke="#ffffff" stroke-width="2.0" />
|
||||
</rule>
|
||||
<rule e="node" k="*" v="city" zoom-max="14">
|
||||
<caption k="name" font-style="bold" font-size="25" fill="#000000"
|
||||
<rule e="node" k="*" v="city">
|
||||
<caption k="name" font-style="bold" font-size="20" fill="#000000"
|
||||
stroke="#ffffff" stroke-width="2.0" />
|
||||
</rule>
|
||||
<rule e="node" k="*" v="country" zoom-max="6">
|
||||
<caption k="name" font-style="bold" font-size="25" fill="#000000"
|
||||
<rule e="node" k="*" v="country" zoom-max="7">
|
||||
<caption k="name" font-size="20" fill="#000000"
|
||||
stroke="#ffffff" stroke-width="2.0" />
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -42,7 +42,8 @@ public final class Area implements RenderInstruction {
|
||||
* @throws IOException
|
||||
* if an I/O error occurs while reading a resource.
|
||||
*/
|
||||
public static Area create(String elementName, Attributes attributes, int level) throws IOException {
|
||||
public static Area create(String elementName, Attributes attributes, int level)
|
||||
throws IOException {
|
||||
String src = null;
|
||||
int fill = Color.BLACK;
|
||||
int stroke = Color.TRANSPARENT;
|
||||
@ -73,7 +74,8 @@ public final class Area implements RenderInstruction {
|
||||
|
||||
private static void validate(float strokeWidth) {
|
||||
if (strokeWidth < 0) {
|
||||
throw new IllegalArgumentException("stroke-width must not be negative: " + strokeWidth);
|
||||
throw new IllegalArgumentException("stroke-width must not be negative: "
|
||||
+ strokeWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,22 +98,24 @@ public final class Area implements RenderInstruction {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final int color;
|
||||
public final float color[];
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final int fade;
|
||||
|
||||
private Area(String src, int fill, int stroke, float strokeWidth, int fade, int level) throws IOException {
|
||||
private Area(String src, int fill, int stroke, float strokeWidth, int fade, int level)
|
||||
throws IOException {
|
||||
super();
|
||||
|
||||
Shader shader = BitmapUtils.createBitmapShader(src);
|
||||
|
||||
if (fill == Color.TRANSPARENT) {
|
||||
paintFill = null;
|
||||
} else {
|
||||
paintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paintFill.setShader(shader);
|
||||
if (src != null) {
|
||||
Shader shader = BitmapUtils.createBitmapShader(src);
|
||||
paintFill.setShader(shader);
|
||||
}
|
||||
paintFill.setStyle(Style.FILL);
|
||||
paintFill.setColor(fill);
|
||||
paintFill.setStrokeCap(Cap.ROUND);
|
||||
@ -125,7 +129,12 @@ public final class Area implements RenderInstruction {
|
||||
paintOutline.setColor(stroke);
|
||||
paintOutline.setStrokeCap(Cap.ROUND);
|
||||
}
|
||||
color = fill;
|
||||
color = new float[4];
|
||||
color[0] = (fill >> 16 & 0xff) / 255.0f;
|
||||
color[1] = (fill >> 8 & 0xff) / 255.0f;
|
||||
color[2] = (fill >> 0 & 0xff) / 255.0f;
|
||||
color[3] = (fill >> 24 & 0xff) / 255.0f;
|
||||
|
||||
this.strokeWidth = strokeWidth;
|
||||
this.fade = fade;
|
||||
this.level = level;
|
||||
|
||||
@ -24,8 +24,10 @@ import org.xml.sax.Attributes;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.FontMetrics;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.FloatMath;
|
||||
|
||||
/**
|
||||
* Represents a text label on the map.
|
||||
@ -78,41 +80,54 @@ public final class Caption implements RenderInstruction {
|
||||
return new Caption(textKey, dy, typeface, fontSize, fill, stroke, strokeWidth);
|
||||
}
|
||||
|
||||
private static void validate(String elementName, String textKey, float fontSize, float strokeWidth) {
|
||||
private static void validate(String elementName, String textKey, float fontSize,
|
||||
float strokeWidth) {
|
||||
if (textKey == null) {
|
||||
throw new IllegalArgumentException("missing attribute k for element: " + elementName);
|
||||
throw new IllegalArgumentException("missing attribute k for element: "
|
||||
+ elementName);
|
||||
} else if (fontSize < 0) {
|
||||
throw new IllegalArgumentException("font-size must not be negative: " + fontSize);
|
||||
throw new IllegalArgumentException("font-size must not be negative: "
|
||||
+ fontSize);
|
||||
} else if (strokeWidth < 0) {
|
||||
throw new IllegalArgumentException("stroke-width must not be negative: " + strokeWidth);
|
||||
throw new IllegalArgumentException("stroke-width must not be negative: "
|
||||
+ strokeWidth);
|
||||
}
|
||||
}
|
||||
|
||||
private final float mDy;
|
||||
private final float mFontSize;
|
||||
private final Paint mPaint;
|
||||
private final Paint mStroke;
|
||||
private final String mTextKey;
|
||||
public final float dy;
|
||||
public float fontSize;
|
||||
public final Paint paint;
|
||||
public final Paint stroke;
|
||||
public final String textKey;
|
||||
public final float fontHeight;
|
||||
public final float fontDescent;
|
||||
|
||||
private Caption(String textKey, float dy, Typeface typeface, float fontSize, int fill, int stroke, float strokeWidth) {
|
||||
private Caption(String textKey, float dy, Typeface typeface, float fontSize,
|
||||
int fillColor, int strokeColor, float strokeWidth) {
|
||||
super();
|
||||
|
||||
mTextKey = textKey;
|
||||
mDy = dy;
|
||||
this.textKey = textKey.intern();
|
||||
this.dy = dy;
|
||||
this.fontSize = fontSize;
|
||||
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setTextAlign(Align.LEFT);
|
||||
mPaint.setTypeface(typeface);
|
||||
mPaint.setColor(fill);
|
||||
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setTextAlign(Align.CENTER);
|
||||
paint.setTypeface(typeface);
|
||||
paint.setColor(fillColor);
|
||||
|
||||
mStroke = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mStroke.setStyle(Style.STROKE);
|
||||
mStroke.setTextAlign(Align.LEFT);
|
||||
mStroke.setTypeface(typeface);
|
||||
mStroke.setColor(stroke);
|
||||
mStroke.setStrokeWidth(strokeWidth);
|
||||
stroke = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
stroke.setStyle(Style.STROKE);
|
||||
stroke.setTextAlign(Align.CENTER);
|
||||
stroke.setTypeface(typeface);
|
||||
stroke.setColor(strokeColor);
|
||||
stroke.setStrokeWidth(strokeWidth);
|
||||
|
||||
mFontSize = fontSize;
|
||||
paint.setTextSize(fontSize);
|
||||
stroke.setTextSize(fontSize);
|
||||
|
||||
FontMetrics fm = paint.getFontMetrics();
|
||||
fontHeight = FloatMath.ceil(Math.abs(fm.bottom) + Math.abs(fm.top));
|
||||
fontDescent = FloatMath.ceil(Math.abs(fm.descent));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,12 +137,12 @@ public final class Caption implements RenderInstruction {
|
||||
|
||||
@Override
|
||||
public void renderNode(IRenderCallback renderCallback, Tag[] tags) {
|
||||
renderCallback.renderPointOfInterestCaption(mTextKey, mDy, mPaint, mStroke);
|
||||
renderCallback.renderPointOfInterestCaption(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderWay(IRenderCallback renderCallback, Tag[] tags) {
|
||||
renderCallback.renderAreaCaption(mTextKey, mDy, mPaint, mStroke);
|
||||
renderCallback.renderAreaCaption(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -137,7 +152,7 @@ public final class Caption implements RenderInstruction {
|
||||
|
||||
@Override
|
||||
public void scaleTextSize(float scaleFactor) {
|
||||
mPaint.setTextSize(mFontSize * scaleFactor);
|
||||
mStroke.setTextSize(mFontSize * scaleFactor);
|
||||
paint.setTextSize(fontSize * scaleFactor);
|
||||
stroke.setTextSize(fontSize * scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ public final class Line implements RenderInstruction {
|
||||
float[] strokeDasharray = null;
|
||||
Cap strokeLinecap = Cap.ROUND;
|
||||
int outline = -1;
|
||||
// int fade = -1;
|
||||
int fade = -1;
|
||||
boolean fixed = false;
|
||||
|
||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
||||
@ -75,7 +75,7 @@ public final class Line implements RenderInstruction {
|
||||
} else if ("outline".equals(name)) {
|
||||
outline = Integer.parseInt(value);
|
||||
} else if ("fade".equals(name)) {
|
||||
// fade = Integer.parseInt(value);
|
||||
fade = Integer.parseInt(value);
|
||||
} else if ("fixed".equals(name)) {
|
||||
fixed = Boolean.parseBoolean(value);
|
||||
} else {
|
||||
@ -85,7 +85,7 @@ public final class Line implements RenderInstruction {
|
||||
|
||||
validate(strokeWidth);
|
||||
return new Line(src, stroke, strokeWidth, strokeDasharray, strokeLinecap, level,
|
||||
outline, fixed);
|
||||
outline, fixed, fade);
|
||||
}
|
||||
|
||||
private static void validate(float strokeWidth) {
|
||||
@ -123,7 +123,7 @@ public final class Line implements RenderInstruction {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final int color;
|
||||
public final float color[];
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -134,9 +134,11 @@ public final class Line implements RenderInstruction {
|
||||
*/
|
||||
public final boolean fixed;
|
||||
|
||||
public final int fade;
|
||||
|
||||
private Line(String src, int stroke, float strokeWidth, float[] strokeDasharray,
|
||||
Cap strokeLinecap, int level,
|
||||
int outline, boolean fixed)
|
||||
int outline, boolean fixed, int fade)
|
||||
throws IOException {
|
||||
super();
|
||||
|
||||
@ -151,11 +153,18 @@ public final class Line implements RenderInstruction {
|
||||
}
|
||||
paint.setStrokeCap(strokeLinecap);
|
||||
round = (strokeLinecap == Cap.ROUND);
|
||||
this.color = stroke;
|
||||
|
||||
color = new float[4];
|
||||
color[0] = (stroke >> 16 & 0xff) / 255.0f;
|
||||
color[1] = (stroke >> 8 & 0xff) / 255.0f;
|
||||
color[2] = (stroke >> 0 & 0xff) / 255.0f;
|
||||
color[3] = (stroke >> 24 & 0xff) / 255.0f;
|
||||
|
||||
this.strokeWidth = strokeWidth;
|
||||
this.level = level;
|
||||
this.outline = outline;
|
||||
this.fixed = fixed;
|
||||
this.fade = fade;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -22,6 +22,7 @@ import org.mapsforge.android.mapgenerator.MapGeneratorJob;
|
||||
import org.mapsforge.android.rendertheme.IRenderCallback;
|
||||
import org.mapsforge.android.rendertheme.RenderTheme;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Area;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Caption;
|
||||
import org.mapsforge.android.rendertheme.renderinstruction.Line;
|
||||
import org.mapsforge.core.Tag;
|
||||
import org.mapsforge.core.Tile;
|
||||
@ -218,8 +219,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAreaCaption(String textKey, float verticalOffset, Paint paint,
|
||||
Paint stroke) {
|
||||
public void renderAreaCaption(Caption caption) {
|
||||
// mapDatabase.readTag(caption);
|
||||
// if (caption.value != null) {
|
||||
// float[] centerPosition = GeometryUtils
|
||||
@ -241,7 +241,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPointOfInterest(byte layer, int latitude, int longitude, Tag[] tags) {
|
||||
public void renderPointOfInterest(byte layer, float latitude, float longitude,
|
||||
Tag[] tags) {
|
||||
mDrawingLayer = mWays[getValidLayer(layer)];
|
||||
mPoiX = scaleLongitude(longitude);
|
||||
mPoiY = scaleLatitude(latitude);
|
||||
@ -249,8 +250,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderPointOfInterestCaption(String textKey, float verticalOffset,
|
||||
Paint paint, Paint stroke) {
|
||||
public void renderPointOfInterestCaption(Caption caption) {
|
||||
// mapDatabase.readTag(caption);
|
||||
// if (caption.value != null) {
|
||||
// nodes.add(new PointTextContainer(caption.value, poiX, poiY + verticalOffset, paint, stroke));
|
||||
@ -298,7 +298,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
// private byte mPrevLayer = 0;
|
||||
|
||||
@Override
|
||||
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, int[] wayLengths,
|
||||
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, short[] wayLengths,
|
||||
boolean changed) {
|
||||
// if (mCoords == null)
|
||||
// mCoords = mMapDatabase.getCoordinates();
|
||||
@ -526,4 +526,10 @@ public class MapGenerator implements IMapGenerator, IRenderCallback,
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkWay(Tag[] tags, boolean closed) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ public class GlUtils {
|
||||
|
||||
int program = GLES20.glCreateProgram();
|
||||
if (program != 0) {
|
||||
checkGlError("glCreateProgram");
|
||||
GLES20.glAttachShader(program, vertexShader);
|
||||
checkGlError("glAttachShader");
|
||||
GLES20.glAttachShader(program, pixelShader);
|
||||
|
||||
@ -587,9 +587,11 @@ public class TileMap extends MapActivity { // implements ActionBar.OnNavigationL
|
||||
preferences.getBoolean("drawTileCoordinates", false);
|
||||
boolean disablePolygons =
|
||||
preferences.getBoolean("disablePolygons", false);
|
||||
boolean drawUnmatchedWays =
|
||||
preferences.getBoolean("drawUnmatchedWays", false);
|
||||
|
||||
DebugSettings debugSettings = new DebugSettings(drawTileCoordinates,
|
||||
drawTileFrames, disablePolygons);
|
||||
drawTileFrames, disablePolygons, drawUnmatchedWays);
|
||||
|
||||
mMapView.setDebugSettings(debugSettings);
|
||||
|
||||
|
||||
@ -58,11 +58,28 @@ public class Tag {
|
||||
|
||||
public Tag(String tag) {
|
||||
int splitPosition = tag.indexOf(KEY_VALUE_SEPARATOR);
|
||||
if (splitPosition < 0) {
|
||||
System.out.println("TAG:" + tag);
|
||||
}
|
||||
this.key = tag.substring(0, splitPosition).intern();
|
||||
this.value = tag.substring(splitPosition + 1).intern();
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
public Tag(String tag, boolean hashValue) {
|
||||
int splitPosition = tag.indexOf(KEY_VALUE_SEPARATOR);
|
||||
if (splitPosition < 0) {
|
||||
System.out.println("TAG:" + tag);
|
||||
}
|
||||
this.key = tag.substring(0, splitPosition).intern();
|
||||
if (!hashValue)
|
||||
this.value = tag.substring(splitPosition + 1);
|
||||
else
|
||||
this.value = tag.substring(splitPosition + 1).intern();
|
||||
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* the key of the tag.
|
||||
@ -75,6 +92,12 @@ public class Tag {
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
public Tag(String key, String value, boolean intern) {
|
||||
this.key = (key == null ? null : key);
|
||||
this.value = (value == null ? null : value);
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
|
||||
@ -27,7 +27,7 @@ public class Tile {
|
||||
/**
|
||||
* Width and height of a map tile in pixel.
|
||||
*/
|
||||
public static final int TILE_SIZE = 256;
|
||||
public static int TILE_SIZE = 256;
|
||||
|
||||
/**
|
||||
* Size of a single uncompressed map tile bitmap in bytes.
|
||||
|
||||
@ -36,8 +36,10 @@ public interface IMapDatabase {
|
||||
* the tile to read.
|
||||
* @param mapDatabaseCallback
|
||||
* the callback which handles the extracted map elements.
|
||||
* @return true if successful
|
||||
*/
|
||||
public abstract void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback);
|
||||
public abstract QueryResult executeQuery(Tile tile,
|
||||
IMapDatabaseCallback mapDatabaseCallback);
|
||||
|
||||
/**
|
||||
* @return the metadata for the current map file.
|
||||
|
||||
@ -33,7 +33,7 @@ public interface IMapDatabaseCallback {
|
||||
* @param tags
|
||||
* the tags of the node.
|
||||
*/
|
||||
void renderPointOfInterest(byte layer, int latitude, int longitude, Tag[] tags);
|
||||
void renderPointOfInterest(byte layer, float latitude, float longitude, Tag[] tags);
|
||||
|
||||
/**
|
||||
* Renders water background for the current tile.
|
||||
@ -54,5 +54,9 @@ public interface IMapDatabaseCallback {
|
||||
* @param changed
|
||||
* tags have changed since last call (just an optional hint)
|
||||
*/
|
||||
void renderWay(byte layer, Tag[] tags, float[] wayNodes, int[] wayLength, boolean changed);
|
||||
void renderWay(byte layer, Tag[] tags, float[] wayNodes, short[] wayLength,
|
||||
boolean changed);
|
||||
|
||||
boolean checkWay(Tag[] tags, boolean closed);
|
||||
|
||||
}
|
||||
|
||||
22
src/org/mapsforge/database/QueryResult.java
Normal file
22
src/org/mapsforge/database/QueryResult.java
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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.mapsforge.database;
|
||||
|
||||
public enum QueryResult {
|
||||
SUCCESS,
|
||||
FAILED,
|
||||
TILE_NOT_FOUND,
|
||||
DELAYED,
|
||||
}
|
||||
@ -24,6 +24,7 @@ import org.mapsforge.database.FileOpenResult;
|
||||
import org.mapsforge.database.IMapDatabase;
|
||||
import org.mapsforge.database.IMapDatabaseCallback;
|
||||
import org.mapsforge.database.MapFileInfo;
|
||||
import org.mapsforge.database.QueryResult;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -33,9 +34,11 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
private final static String PROJECTION = "Mercator";
|
||||
private float[] mCoords = new float[20];
|
||||
private int[] mIndex = new int[2];
|
||||
private short[] mIndex = new short[2];
|
||||
// private Tag[] mTags = { new Tag("boundary", "administrative"), new Tag("admin_level", "2") };
|
||||
private Tag[] mTags = { new Tag("natural", "water") };
|
||||
private Tag[] mNameTags;
|
||||
|
||||
private final MapFileInfo mMapInfo =
|
||||
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
|
||||
new Byte((byte) 0), null, PROJECTION, 0, 0, 0, "de", "yo!", "by me");
|
||||
@ -48,7 +51,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
// private static double HALF_PI = Math.PI / 2;
|
||||
|
||||
@Override
|
||||
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
|
||||
long cx = tile.pixelX + (Tile.TILE_SIZE >> 1);
|
||||
long cy = tile.pixelY + (Tile.TILE_SIZE >> 1);
|
||||
@ -140,6 +143,17 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
mIndex[1] = 10;
|
||||
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true);
|
||||
|
||||
lon1 = (float) MercatorProjection.pixelXToLongitude(cx, tile.zoomLevel) * 1000000;
|
||||
lat1 = (float) MercatorProjection.pixelXToLongitude(cx, tile.zoomLevel) * 1000000;
|
||||
|
||||
mNameTags = new Tag[2];
|
||||
mNameTags[0] = new Tag("place", "city");
|
||||
mNameTags[1] = new Tag("name", "check one check two, YO!");
|
||||
mapDatabaseCallback.renderPointOfInterest((byte) 0, (int) lat1, (int) lon1,
|
||||
mNameTags);
|
||||
|
||||
return QueryResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -26,6 +26,7 @@ import org.mapsforge.core.Tile;
|
||||
import org.mapsforge.database.FileOpenResult;
|
||||
import org.mapsforge.database.IMapDatabase;
|
||||
import org.mapsforge.database.IMapDatabaseCallback;
|
||||
import org.mapsforge.database.QueryResult;
|
||||
import org.mapsforge.database.mapfile.header.MapFileHeader;
|
||||
import org.mapsforge.database.mapfile.header.MapFileInfo;
|
||||
import org.mapsforge.database.mapfile.header.SubFileParameter;
|
||||
@ -203,9 +204,9 @@ public class MapDatabase implements IMapDatabase {
|
||||
* org.mapsforge.map.reader.MapDatabaseCallback)
|
||||
*/
|
||||
@Override
|
||||
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
if (sMapFileHeader == null)
|
||||
return;
|
||||
return QueryResult.FAILED;
|
||||
|
||||
if (mIntBuffer == null)
|
||||
mIntBuffer = new int[MAXIMUM_WAY_NODES_SEQUENCE_LENGTH * 2];
|
||||
@ -223,7 +224,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
if (subFileParameter == null) {
|
||||
LOG.warning("no sub-file for zoom level: "
|
||||
+ queryParameters.queryZoomLevel);
|
||||
return;
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
QueryCalculations.calculateBaseTiles(queryParameters, tile, subFileParameter);
|
||||
@ -231,7 +232,9 @@ public class MapDatabase implements IMapDatabase {
|
||||
processBlocks(mapDatabaseCallback, queryParameters, subFileParameter);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.SEVERE, null, e);
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
return QueryResult.SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -580,6 +583,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
// Log.d("MapDatabase", "read POI");
|
||||
|
||||
// get the POI latitude offset (VBE-S)
|
||||
int latitude = mTileLatitude + mReadBuffer.readSignedInt();
|
||||
|
||||
@ -610,12 +615,19 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
// check if the POI has a name
|
||||
if ((featureByte & POI_FEATURE_NAME) != 0) {
|
||||
mReadBuffer.getPositionAndSkip();
|
||||
// int pos = mReadBuffer.getPositionAndSkip();
|
||||
String str = mReadBuffer.readUTF8EncodedString();
|
||||
|
||||
Tag[] tmp = tags;
|
||||
tags = new Tag[tmp.length + 1];
|
||||
System.arraycopy(tmp, 0, tags, 0, tmp.length);
|
||||
tags[tags.length - 1] = new Tag("name", str, false);
|
||||
}
|
||||
|
||||
// check if the POI has a house number
|
||||
if ((featureByte & POI_FEATURE_HOUSE_NUMBER) != 0) {
|
||||
mReadBuffer.getPositionAndSkip();
|
||||
// mReadBuffer.getPositionAndSkip();
|
||||
String str = mReadBuffer.readUTF8EncodedString();
|
||||
}
|
||||
|
||||
// check if the POI has an elevation
|
||||
@ -632,7 +644,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int[] processWayDataBlock(boolean doubleDeltaEncoding) {
|
||||
private short[] processWayDataBlock(boolean doubleDeltaEncoding) {
|
||||
// get and check the number of way coordinate blocks (VBE-U)
|
||||
int numBlocks = mReadBuffer.readUnsignedInt();
|
||||
if (numBlocks < 1 || numBlocks > Short.MAX_VALUE) {
|
||||
@ -640,7 +652,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
return null;
|
||||
}
|
||||
|
||||
int[] wayLengths = new int[numBlocks];
|
||||
short[] wayLengths = new short[numBlocks];
|
||||
|
||||
mWayNodePosition = 0;
|
||||
|
||||
@ -663,7 +675,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
} else {
|
||||
len = decodeWayNodesSingleDelta(len);
|
||||
}
|
||||
wayLengths[coordinateBlock] = len;
|
||||
wayLengths[coordinateBlock] = (short) len;
|
||||
}
|
||||
|
||||
return wayLengths;
|
||||
@ -907,7 +919,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
|
||||
for (int wayDataBlock = 0; wayDataBlock < wayDataBlocks; ++wayDataBlock) {
|
||||
int[] wayLengths = processWayDataBlock(featureWayDoubleDeltaEncoding);
|
||||
short[] wayLengths = processWayDataBlock(featureWayDoubleDeltaEncoding);
|
||||
if (wayLengths == null)
|
||||
return false;
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ import org.mapsforge.database.FileOpenResult;
|
||||
import org.mapsforge.database.IMapDatabase;
|
||||
import org.mapsforge.database.IMapDatabaseCallback;
|
||||
import org.mapsforge.database.MapFileInfo;
|
||||
import org.mapsforge.database.QueryResult;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@ -65,35 +66,36 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
// private static final String URL = "http://city.informatik.uni-bremen.de:8020/test/%d/%d/%d.osmtile";
|
||||
private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/test/%d/%d/%d.osmtile";
|
||||
// private static final String URL = "http://city.informatik.uni-bremen.de/osmstache/gis2/%d/%d/%d.osmtile";
|
||||
private static final Header encodingHeader =
|
||||
new BasicHeader("Accept-Encoding", "gzip");
|
||||
|
||||
private static volatile HashMap<String, Tag> tagHash = new HashMap<String, Tag>(100);
|
||||
|
||||
private Tag[] curTags = new Tag[1000];
|
||||
private Tag[] curTags = new Tag[250];
|
||||
private int mCurTagCnt;
|
||||
|
||||
// private AndroidHttpClient mClient;
|
||||
private HttpClient mClient;
|
||||
private IMapDatabaseCallback mMapGenerator;
|
||||
private float mScaleFactor;
|
||||
private HttpGet mRequest = null;
|
||||
|
||||
@Override
|
||||
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
mCanceled = false;
|
||||
|
||||
if (mClient == null)
|
||||
createClient();
|
||||
// Log.d(TAG, "get tile >> : " + tile);
|
||||
|
||||
String url = String.format(URL, Integer.valueOf(tile.zoomLevel),
|
||||
Long.valueOf(tile.tileX), Long.valueOf(tile.tileY));
|
||||
|
||||
HttpGet getRequest = new HttpGet(url);
|
||||
getRequest.addHeader(encodingHeader);
|
||||
|
||||
mRequest = getRequest;
|
||||
mMapGenerator = mapDatabaseCallback;
|
||||
mCurTagCnt = 0;
|
||||
// using variable coordinate scalefactor to take advantage of
|
||||
// variable byte encoded integers
|
||||
|
||||
// using variable coordinate scalefactor to take advantage of varint
|
||||
mScaleFactor = 1 / 100f;
|
||||
if (tile.zoomLevel < 12)
|
||||
mScaleFactor = (float) Math.pow(2, (12 - tile.zoomLevel)) / 100f;
|
||||
@ -101,22 +103,16 @@ public class MapDatabase implements IMapDatabase {
|
||||
try {
|
||||
HttpResponse response = mClient.execute(getRequest);
|
||||
final int statusCode = response.getStatusLine().getStatusCode();
|
||||
final HttpEntity entity = response.getEntity();
|
||||
|
||||
if (statusCode != HttpStatus.SC_OK) {
|
||||
Log.d(TAG, "Http response " + statusCode);
|
||||
return;
|
||||
entity.consumeContent();
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
final HttpEntity entity = response.getEntity();
|
||||
if (entity == null) {
|
||||
Log.d(TAG, "Somethings wrong? - no entity " + statusCode);
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream is = null;
|
||||
GZIPInputStream zis = null;
|
||||
try {
|
||||
// is = AndroidHttpClient.getUngzippedContent(entity);
|
||||
|
||||
is = entity.getContent();
|
||||
zis = new GZIPInputStream(is);
|
||||
|
||||
@ -131,12 +127,19 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
} catch (SocketException ex) {
|
||||
Log.d(TAG, "Socket exception: " + ex.getMessage());
|
||||
return QueryResult.FAILED;
|
||||
} catch (SocketTimeoutException ex) {
|
||||
Log.d(TAG, "Socket exception: " + ex.getMessage());
|
||||
Log.d(TAG, "Socket Timeout exception: " + ex.getMessage());
|
||||
return QueryResult.FAILED;
|
||||
} catch (Exception ex) {
|
||||
getRequest.abort();
|
||||
ex.printStackTrace();
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
mRequest = null;
|
||||
// Log.d(TAG, "get tile << : " + tile);
|
||||
|
||||
return QueryResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -163,7 +166,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
HttpConnectionParams.setConnectionTimeout(params, 10 * 1000);
|
||||
HttpConnectionParams.setSoTimeout(params, 60 * 1000);
|
||||
HttpConnectionParams.setSocketBufferSize(params, 8192);
|
||||
HttpConnectionParams.setSocketBufferSize(params, 16384);
|
||||
mClient = new DefaultHttpClient(params);
|
||||
HttpClientParams.setRedirecting(params, false);
|
||||
SchemeRegistry schemeRegistry = new SchemeRegistry();
|
||||
@ -190,7 +193,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final int BUFFER_SIZE = 65536;
|
||||
private static final int BUFFER_SIZE = 65536 * 2;
|
||||
|
||||
private final byte[] buffer = new byte[BUFFER_SIZE];
|
||||
private int bufferPos;
|
||||
@ -200,14 +203,21 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
private static final int TAG_TILE_TAGS = 1;
|
||||
private static final int TAG_TILE_WAYS = 2;
|
||||
private static final int TAG_TILE_NODES = 3;
|
||||
private static final int TAG_WAY_TAGS = 1;
|
||||
private static final int TAG_WAY_INDEX = 2;
|
||||
private static final int TAG_WAY_COORDS = 3;
|
||||
private static final int TAG_WAY_LAYER = 4;
|
||||
private static final int TAG_TILE_POLY = 3;
|
||||
private static final int TAG_TILE_NODES = 4;
|
||||
private static final int TAG_WAY_TAGS = 11;
|
||||
private static final int TAG_WAY_INDEX = 12;
|
||||
private static final int TAG_WAY_COORDS = 13;
|
||||
private static final int TAG_WAY_LAYER = 21;
|
||||
private static final int TAG_WAY_NUM_TAGS = 1;
|
||||
private static final int TAG_WAY_NUM_INDICES = 2;
|
||||
private static final int TAG_WAY_NUM_COORDS = 3;
|
||||
|
||||
// private static final int TAG_NODE_TAGS = 1;
|
||||
// private static final int TAG_NODE_COORDS = 2;
|
||||
private static final int TAG_NODE_TAGS = 11;
|
||||
private static final int TAG_NODE_COORDS = 12;
|
||||
private static final int TAG_NODE_LAYER = 21;
|
||||
private static final int TAG_NODE_NUM_TAGS = 1;
|
||||
private static final int TAG_NODE_NUM_COORDS = 2;
|
||||
|
||||
private boolean decode(InputStream is) throws IOException {
|
||||
inputStream = is;
|
||||
@ -228,7 +238,11 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
|
||||
case TAG_TILE_WAYS:
|
||||
decodeTileWays();
|
||||
decodeTileWays(false);
|
||||
break;
|
||||
|
||||
case TAG_TILE_POLY:
|
||||
decodeTileWays(true);
|
||||
break;
|
||||
|
||||
case TAG_TILE_NODES:
|
||||
@ -248,16 +262,23 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
Tag tag = tagHash.get(tagString);
|
||||
if (tag == null) {
|
||||
tag = new Tag(tagString);
|
||||
// Log.d(TAG, "tag:" + tagString);
|
||||
if (tagString.equals("name="))
|
||||
tag = new Tag(tagString, false);
|
||||
else
|
||||
tag = new Tag(tagString);
|
||||
|
||||
tagHash.put(tagString, tag);
|
||||
}
|
||||
curTags[mCurTagCnt++] = tag;
|
||||
// FIXME ...
|
||||
if (mCurTagCnt < 250)
|
||||
curTags[mCurTagCnt++] = tag;
|
||||
|
||||
// Log.d(TAG, "tag:" + tag);
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileWays() throws IOException {
|
||||
private boolean decodeTileWays(boolean polygon) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
int end = bytesRead + bytes;
|
||||
@ -265,6 +286,11 @@ public class MapDatabase implements IMapDatabase {
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
int layer = 0;
|
||||
Tag[] tags = null;
|
||||
short[] index = null;
|
||||
|
||||
boolean skip = false;
|
||||
boolean fail = false;
|
||||
|
||||
while (bytesRead < end) {
|
||||
// read tag and wire type
|
||||
@ -275,54 +301,56 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
int tag = (val >> 3);
|
||||
// int wireType = val & 7;
|
||||
|
||||
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
||||
int cnt;
|
||||
|
||||
switch (tag) {
|
||||
case TAG_WAY_TAGS:
|
||||
tagCnt = decodeWayTags();
|
||||
tags = decodeWayTags(tagCnt);
|
||||
break;
|
||||
|
||||
case TAG_WAY_INDEX:
|
||||
indexCnt = decodeWayIndices();
|
||||
index = decodeWayIndices(indexCnt);
|
||||
break;
|
||||
|
||||
case TAG_WAY_COORDS:
|
||||
coordCnt = decodeWayCoordinates();
|
||||
cnt = decodeWayCoordinates(skip);
|
||||
if (cnt != coordCnt) {
|
||||
Log.d(TAG, "EEEK wrong number of coordintes");
|
||||
fail = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_WAY_LAYER:
|
||||
layer = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_TAGS:
|
||||
tagCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_INDICES:
|
||||
indexCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_WAY_NUM_COORDS:
|
||||
coordCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.d(TAG, "invalid type for way: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (indexCnt == 0 || tagCnt == 0)
|
||||
if (fail || index == null || tags == null || indexCnt == 0 || tagCnt == 0) {
|
||||
Log.d(TAG, "..." + index + " " + tags + " " + indexCnt + " " + coordCnt + " "
|
||||
+ tagCnt);
|
||||
return false;
|
||||
|
||||
int[] index = new int[indexCnt];
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < indexCnt; i++) {
|
||||
index[i] = tmpIndices[i] * 2;
|
||||
sum += index[i];
|
||||
}
|
||||
|
||||
Tag[] tags = new Tag[tagCnt];
|
||||
for (int i = 0; i < tagCnt; i++)
|
||||
tags[i] = curTags[tmpTags[i]];
|
||||
|
||||
float[] coords = tmpCoords;
|
||||
int pos = 0;
|
||||
|
||||
if (coordCnt != sum) {
|
||||
Log.d(TAG, "way length is wrong " + coordCnt + " " + sum);
|
||||
return false;
|
||||
}
|
||||
|
||||
float z = mScaleFactor;
|
||||
for (int j = 0, m = indexCnt; j < m; j++) {
|
||||
float lastX = 0;
|
||||
@ -332,23 +360,86 @@ public class MapDatabase implements IMapDatabase {
|
||||
lastX = coords[pos] = (coords[pos] * z) + lastX;
|
||||
lastY = coords[pos + 1] = (coords[pos + 1] * z) + lastY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mMapGenerator.renderWay((byte) layer, tags, coords, index, true);
|
||||
mMapGenerator.renderWay((byte) layer, tags, coords, index, polygon);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean decodeTileNodes() throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
Log.d(TAG, "way nodes " + bytes);
|
||||
|
||||
// Log.d(TAG, "decode nodes " + bytes);
|
||||
|
||||
int end = bytesRead + bytes;
|
||||
int tagCnt = 0;
|
||||
int coordCnt = 0;
|
||||
byte layer = 0;
|
||||
Tag[] tags = null;
|
||||
|
||||
while (bytesRead < end) {
|
||||
// read tag and wire type
|
||||
int val = decodeVarint32();
|
||||
if (val == 0)
|
||||
break;
|
||||
|
||||
int tag = (val >> 3);
|
||||
// int wireType = val & 7;
|
||||
// Log.d(TAG, "way " + tag + " " + wireType + " bytes:" + bytes);
|
||||
int cnt;
|
||||
|
||||
switch (tag) {
|
||||
case TAG_NODE_TAGS:
|
||||
tags = decodeWayTags(tagCnt);
|
||||
break;
|
||||
|
||||
case TAG_NODE_COORDS:
|
||||
cnt = decodeNodeCoordinates(coordCnt, layer, tags);
|
||||
if (cnt != coordCnt) {
|
||||
Log.d(TAG, "EEEK wrong number of coordintes");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAG_NODE_LAYER:
|
||||
layer = (byte) decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_NODE_NUM_TAGS:
|
||||
tagCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
case TAG_NODE_NUM_COORDS:
|
||||
coordCnt = decodeVarint32();
|
||||
break;
|
||||
|
||||
default:
|
||||
Log.d(TAG, "invalid type for node: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int decodeNodeCoordinates(int numNodes, byte layer, Tag[] tags)
|
||||
throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
readBuffer(bytes);
|
||||
int cnt = 0;
|
||||
int end = bufferPos + bytes;
|
||||
|
||||
// read repeated sint32
|
||||
while (bufferPos < end && cnt < numNodes) {
|
||||
float lon = decodeZigZag32(decodeVarint32()) * mScaleFactor;
|
||||
float lat = decodeZigZag32(decodeVarint32()) * mScaleFactor;
|
||||
mMapGenerator.renderPointOfInterest(layer, lat, lon, tags);
|
||||
cnt += 2;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
private int MAX_WAY_COORDS = 32768;
|
||||
private int MAX_WAY_INDICES = 1000;
|
||||
private int[] tmpTags = new int[32];
|
||||
private int[] tmpIndices = new int[MAX_WAY_INDICES];
|
||||
private float[] tmpCoords = new float[MAX_WAY_COORDS];
|
||||
|
||||
// private boolean ensureBufferSize(int size) throws IOException {
|
||||
@ -358,47 +449,62 @@ public class MapDatabase implements IMapDatabase {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
private int decodeWayTags() throws IOException {
|
||||
private Tag[] decodeWayTags(int tagCnt) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
// Log.d(TAG, "way tags: " + bytes);
|
||||
|
||||
Tag[] tags = new Tag[tagCnt];
|
||||
|
||||
int cnt = 0;
|
||||
int end = bytesRead + bytes;
|
||||
int max = curTags.length;
|
||||
|
||||
while (bytesRead < end)
|
||||
tmpTags[cnt++] = decodeVarint32();
|
||||
while (bytesRead < end) {
|
||||
int tagNum = decodeVarint32();
|
||||
|
||||
return cnt;
|
||||
if (tagNum < 0 || cnt == tagCnt)
|
||||
continue;
|
||||
|
||||
if (tagNum < Tags.MAX)
|
||||
tags[cnt++] = Tags.tags[tagNum];
|
||||
else {
|
||||
tagNum -= Tags.LIMIT;
|
||||
if (tagNum >= 0 && tagNum < max) {
|
||||
// Log.d(TAG, "variable tag: " + curTags[tagNum]);
|
||||
tags[cnt++] = curTags[tagNum];
|
||||
}
|
||||
}
|
||||
// else DEBUG...
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
private int decodeWayIndices() throws IOException {
|
||||
private short[] decodeWayIndices(int indexCnt) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
// Log.d(TAG, "way indices: " + bytes);
|
||||
|
||||
short[] index = new short[indexCnt];
|
||||
|
||||
int cnt = 0;
|
||||
int end = bytesRead + bytes;
|
||||
|
||||
while (bytesRead < end) {
|
||||
int val = decodeVarint32();
|
||||
if (cnt >= MAX_WAY_INDICES) {
|
||||
|
||||
MAX_WAY_INDICES += 128;
|
||||
Log.d(TAG, "increase indices array " + MAX_WAY_INDICES);
|
||||
int[] tmp = new int[MAX_WAY_INDICES];
|
||||
System.arraycopy(tmpIndices, 0, tmp, 0, cnt);
|
||||
tmpIndices = tmp;
|
||||
}
|
||||
|
||||
tmpIndices[cnt++] = val;
|
||||
if (cnt < indexCnt)
|
||||
index[cnt++] = (short) (val * 2);
|
||||
// else DEBUG...
|
||||
|
||||
}
|
||||
return cnt;
|
||||
return index;
|
||||
}
|
||||
|
||||
private int decodeWayCoordinates() throws IOException {
|
||||
private int decodeWayCoordinates(boolean skip) throws IOException {
|
||||
int bytes = decodeVarint32();
|
||||
|
||||
readBuffer(bytes);
|
||||
if (skip) {
|
||||
bufferPos += bytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pos = bufferPos;
|
||||
int end = pos + bytes;
|
||||
@ -511,7 +617,18 @@ public class MapDatabase implements IMapDatabase {
|
||||
buffer[bufferSize - 1] = 0; // FIXME is this needed?
|
||||
break;
|
||||
}
|
||||
|
||||
bufferSize += len;
|
||||
|
||||
// if (len == 0)
|
||||
// try {
|
||||
// wait(50);
|
||||
// } catch (InterruptedException e) {
|
||||
// // just waiting for data
|
||||
// }
|
||||
|
||||
if (mCanceled)
|
||||
throw new IOException("... canceld?");
|
||||
}
|
||||
|
||||
// Log.d(TAG, "needed " + size + " pos " + bufferPos + ", size "
|
||||
@ -614,8 +731,12 @@ public class MapDatabase implements IMapDatabase {
|
||||
@Override
|
||||
public void cancel() {
|
||||
mCanceled = true;
|
||||
mClient.getConnectionManager().shutdown();
|
||||
mClient = null;
|
||||
if (mRequest != null) {
|
||||
mRequest.abort();
|
||||
mRequest = null;
|
||||
}
|
||||
// mClient.getConnectionManager().shutdown();
|
||||
// mClient = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
958
src/org/mapsforge/database/pbmap/Tags.java
Normal file
958
src/org/mapsforge/database/pbmap/Tags.java
Normal file
@ -0,0 +1,958 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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.mapsforge.database.pbmap;
|
||||
|
||||
import org.mapsforge.core.Tag;
|
||||
|
||||
public class Tags {
|
||||
public final static int MAX = 654;
|
||||
public final static int LIMIT = 1024;
|
||||
|
||||
private static final String s_limited = "limited".intern();
|
||||
private static final String s_chain = "chain".intern();
|
||||
private static final String s_viaduct = "viaduct".intern();
|
||||
private static final String s_department_store = "department_store".intern();
|
||||
private static final String s_factory = "factory".intern();
|
||||
private static final String s_recreation_ground = "recreation_ground".intern();
|
||||
private static final String s_nature_reserve = "nature_reserve".intern();
|
||||
private static final String s_apartment = "apartment".intern();
|
||||
private static final String s_preserved = "preserved".intern();
|
||||
private static final String s_stationery = "stationery".intern();
|
||||
private static final String s_gravel = "gravel".intern();
|
||||
private static final String s_hill = "hill".intern();
|
||||
private static final String s_water_well = "water_well".intern();
|
||||
private static final String s_garden = "garden".intern();
|
||||
private static final String s_permissive = "permissive".intern();
|
||||
private static final String s_deli = "deli".intern();
|
||||
private static final String s_industrial_retail = "industrial;retail".intern();
|
||||
private static final String s_city_wall = "city_wall".intern();
|
||||
private static final String s_artwork = "artwork".intern();
|
||||
private static final String s_chapel = "chapel".intern();
|
||||
private static final String s_school = "school".intern();
|
||||
private static final String s_caravan_site = "caravan_site".intern();
|
||||
private static final String s_reservoir_watershed = "reservoir_watershed".intern();
|
||||
private static final String s_local_authority = "local_authority".intern();
|
||||
private static final String s_miniature_golf = "miniature_golf".intern();
|
||||
private static final String s_bus_stop = "bus_stop".intern();
|
||||
private static final String s_convenience = "convenience".intern();
|
||||
private static final String s_kissing_gate = "kissing_gate".intern();
|
||||
private static final String s_subway = "subway".intern();
|
||||
private static final String s_cutline = "cutline".intern();
|
||||
private static final String s_disused = "disused".intern();
|
||||
private static final String s_clothes = "clothes".intern();
|
||||
private static final String s_bicycle = "bicycle".intern();
|
||||
private static final String s_meadow = "meadow".intern();
|
||||
private static final String s_fence = "fence".intern();
|
||||
private static final String s_video = "video".intern();
|
||||
private static final String s_monorail = "monorail".intern();
|
||||
private static final String s_clock = "clock".intern();
|
||||
private static final String s_dirt = "dirt".intern();
|
||||
private static final String s_border_control = "border_control".intern();
|
||||
private static final String s_access = "access".intern();
|
||||
private static final String s_public = "public".intern();
|
||||
private static final String s_fast_food = "fast_food".intern();
|
||||
private static final String s_transportation = "transportation".intern();
|
||||
private static final String s_commercial = "commercial".intern();
|
||||
private static final String s_water = "water".intern();
|
||||
private static final String s_beacon = "beacon".intern();
|
||||
private static final String s_trunk = "trunk".intern();
|
||||
private static final String s_path = "path".intern();
|
||||
private static final String s_bicycle_rental = "bicycle_rental".intern();
|
||||
private static final String s_miniature = "miniature".intern();
|
||||
private static final String s_car_parts = "car_parts".intern();
|
||||
private static final String s_light_rail = "light_rail".intern();
|
||||
private static final String s_military = "military".intern();
|
||||
private static final String s_bog = "bog".intern();
|
||||
private static final String s_hiking = "hiking".intern();
|
||||
private static final String s_lift_gate = "lift_gate".intern();
|
||||
private static final String s_private = "private".intern();
|
||||
private static final String s_county = "county".intern();
|
||||
private static final String s_secondary_link = "secondary_link".intern();
|
||||
private static final String s_marker = "marker".intern();
|
||||
private static final String s_islet = "islet".intern();
|
||||
private static final String s_holding_position = "holding_position".intern();
|
||||
private static final String s_tertiary = "tertiary".intern();
|
||||
private static final String s_water_park = "water_park".intern();
|
||||
private static final String s_stream = "stream".intern();
|
||||
private static final String s_hospital = "hospital".intern();
|
||||
private static final String s_destination = "destination".intern();
|
||||
private static final String s_MDF = "MDF".intern();
|
||||
private static final String s_sports = "sports".intern();
|
||||
private static final String s_vineyard = "vineyard".intern();
|
||||
private static final String s_music = "music".intern();
|
||||
private static final String s_6 = "6".intern();
|
||||
private static final String s_entrance = "entrance".intern();
|
||||
private static final String s_beauty = "beauty".intern();
|
||||
private static final String s_give_way = "give_way".intern();
|
||||
private static final String s_kiosk = "kiosk".intern();
|
||||
private static final String s_stone = "stone".intern();
|
||||
private static final String s_grass_paver = "grass_paver".intern();
|
||||
private static final String s_deciduous = "deciduous".intern();
|
||||
private static final String s_train = "train".intern();
|
||||
private static final String s_organic = "organic".intern();
|
||||
private static final String s_farmyard = "farmyard".intern();
|
||||
private static final String s_riverbank = "riverbank".intern();
|
||||
private static final String s_doityourself = "doityourself".intern();
|
||||
private static final String s_town = "town".intern();
|
||||
private static final String s_dog_park = "dog_park".intern();
|
||||
private static final String s_village_green = "village_green".intern();
|
||||
private static final String s_tunnel = "tunnel".intern();
|
||||
private static final String s_car = "car".intern();
|
||||
private static final String s_roof = "roof".intern();
|
||||
private static final String s_mall = "mall".intern();
|
||||
private static final String s_ferry_terminal = "ferry_terminal".intern();
|
||||
private static final String s_cave_entrance = "cave_entrance".intern();
|
||||
private static final String s_detached = "detached".intern();
|
||||
private static final String s_concrete_plates = "concrete:plates".intern();
|
||||
private static final String s_public_building = "public_building".intern();
|
||||
private static final String s_buffer_stop = "buffer_stop".intern();
|
||||
private static final String s_lock = "lock".intern();
|
||||
private static final String s_dolphin = "dolphin".intern();
|
||||
private static final String s_taxiway = "taxiway".intern();
|
||||
private static final String s_hunting_stand = "hunting_stand".intern();
|
||||
private static final String s_estate_agent = "estate_agent".intern();
|
||||
private static final String s_station = "station".intern();
|
||||
private static final String s_car_repair = "car_repair".intern();
|
||||
private static final String s_dyke = "dyke".intern();
|
||||
private static final String s_hangar = "hangar".intern();
|
||||
private static final String s_information = "information".intern();
|
||||
private static final String s_1 = "1".intern();
|
||||
private static final String s_forest = "forest".intern();
|
||||
private static final String s_gate = "gate".intern();
|
||||
private static final String s_beach = "beach".intern();
|
||||
private static final String s_laundry = "laundry".intern();
|
||||
private static final String s_speed_camera = "speed_camera".intern();
|
||||
private static final String s_staircase = "staircase".intern();
|
||||
private static final String s_farm = "farm".intern();
|
||||
private static final String s_stop = "stop".intern();
|
||||
private static final String s_bump_gate = "bump_gate".intern();
|
||||
private static final String s_motorway = "motorway".intern();
|
||||
private static final String s_water_tower = "water_tower".intern();
|
||||
private static final String s_abutters = "abutters".intern();
|
||||
private static final String s_driving_school = "driving_school".intern();
|
||||
private static final String s_natural = "natural".intern();
|
||||
private static final String s_orchard = "orchard".intern();
|
||||
private static final String s_wheelchair = "wheelchair".intern();
|
||||
private static final String s_swimming_pool = "swimming_pool".intern();
|
||||
private static final String s_switch = "switch".intern();
|
||||
private static final String s_block = "block".intern();
|
||||
private static final String s_turnstile = "turnstile".intern();
|
||||
private static final String s_camp_site = "camp_site".intern();
|
||||
private static final String s_shoes = "shoes".intern();
|
||||
private static final String s_reservoir = "reservoir".intern();
|
||||
private static final String s_pebblestone = "pebblestone".intern();
|
||||
private static final String s_stile = "stile".intern();
|
||||
private static final String s_embassy = "embassy".intern();
|
||||
private static final String s_postal_code = "postal_code".intern();
|
||||
private static final String s_retaining_wall = "retaining_wall".intern();
|
||||
private static final String s_bridleway = "bridleway".intern();
|
||||
private static final String s_pitch = "pitch".intern();
|
||||
private static final String s_agricultural = "agricultural".intern();
|
||||
private static final String s_post_office = "post_office".intern();
|
||||
private static final String s_parking_fuel = "parking;fuel".intern();
|
||||
private static final String s_bureau_de_change = "bureau_de_change".intern();
|
||||
private static final String s_mini_roundabout = "mini_roundabout".intern();
|
||||
private static final String s_hov = "hov".intern();
|
||||
private static final String s_police = "police".intern();
|
||||
private static final String s_courthouse = "courthouse".intern();
|
||||
private static final String s_raceway = "raceway".intern();
|
||||
private static final String s_kindergarten = "kindergarten".intern();
|
||||
private static final String s_attraction = "attraction".intern();
|
||||
private static final String s_marsh = "marsh".intern();
|
||||
private static final String s_reservoir_covered = "reservoir_covered".intern();
|
||||
private static final String s_petroleum_well = "petroleum_well".intern();
|
||||
private static final String s_silo = "silo".intern();
|
||||
private static final String s_toys = "toys".intern();
|
||||
private static final String s_apron = "apron".intern();
|
||||
private static final String s_halt = "halt".intern();
|
||||
private static final String s_dam = "dam".intern();
|
||||
private static final String s_golf_course = "golf_course".intern();
|
||||
private static final String s_detour = "detour".intern();
|
||||
private static final String s_tree_row = "tree_row".intern();
|
||||
private static final String s_copyshop = "copyshop".intern();
|
||||
private static final String s_milestone = "milestone".intern();
|
||||
private static final String s_foot = "foot".intern();
|
||||
private static final String s_tourism = "tourism".intern();
|
||||
private static final String s_bank = "bank".intern();
|
||||
private static final String s_dry_cleaning = "dry_cleaning".intern();
|
||||
private static final String s_tram = "tram".intern();
|
||||
private static final String s_trolleybus = "trolleybus".intern();
|
||||
private static final String s_university = "university".intern();
|
||||
private static final String s_hampshire_gate = "hampshire_gate".intern();
|
||||
private static final String s_embankment = "embankment".intern();
|
||||
private static final String s_rock = "rock".intern();
|
||||
private static final String s_crossing = "crossing".intern();
|
||||
private static final String s_volcano = "volcano".intern();
|
||||
private static final String s_greengrocer = "greengrocer".intern();
|
||||
private static final String s_kerb = "kerb".intern();
|
||||
private static final String s_waste_disposal = "waste_disposal".intern();
|
||||
private static final String s_grave_yard = "grave_yard".intern();
|
||||
private static final String s_coniferous = "coniferous".intern();
|
||||
private static final String s_house = "house".intern();
|
||||
private static final String s_books = "books".intern();
|
||||
private static final String s_neighbourhood = "neighbourhood".intern();
|
||||
private static final String s_hostel = "hostel".intern();
|
||||
private static final String s_alcohol = "alcohol".intern();
|
||||
private static final String s_restricted = "restricted".intern();
|
||||
private static final String s_motel = "motel".intern();
|
||||
private static final String s_sand = "sand".intern();
|
||||
private static final String s_fishmonger = "fishmonger".intern();
|
||||
private static final String s_fountain = "fountain".intern();
|
||||
private static final String s_playground = "playground".intern();
|
||||
private static final String s_7 = "7".intern();
|
||||
private static final String s_parking_aisle = "parking_aisle".intern();
|
||||
private static final String s_protected_area = "protected_area".intern();
|
||||
private static final String s_electronics = "electronics".intern();
|
||||
private static final String s_Paved = "Paved".intern();
|
||||
private static final String s_highway = "highway".intern();
|
||||
private static final String s_fine_gravel = "fine_gravel".intern();
|
||||
private static final String s_barrier = "barrier".intern();
|
||||
private static final String s_hairdresser = "hairdresser".intern();
|
||||
private static final String s_post_box = "post_box".intern();
|
||||
private static final String s_pub = "pub".intern();
|
||||
private static final String s_coastline = "coastline".intern();
|
||||
private static final String s_marina = "marina".intern();
|
||||
private static final String s_reedbed = "reedbed".intern();
|
||||
private static final String s_biergarten = "biergarten".intern();
|
||||
private static final String s_dismantled = "dismantled".intern();
|
||||
private static final String s_farmland = "farmland".intern();
|
||||
private static final String s_yard = "yard".intern();
|
||||
private static final String s_route = "route".intern();
|
||||
private static final String s_atm = "atm".intern();
|
||||
private static final String s_place = "place".intern();
|
||||
private static final String s_bus_station = "bus_station".intern();
|
||||
private static final String s_retail = "retail".intern();
|
||||
private static final String s_industrial = "industrial".intern();
|
||||
private static final String s_municipality = "municipality".intern();
|
||||
private static final String s_primary = "primary".intern();
|
||||
private static final String s_nursing_home = "nursing_home".intern();
|
||||
private static final String s_florist = "florist".intern();
|
||||
private static final String s_ditch = "ditch".intern();
|
||||
private static final String s_national_park = "national_park".intern();
|
||||
private static final String s_city = "city".intern();
|
||||
private static final String s_confectionery = "confectionery".intern();
|
||||
private static final String s_service = "service".intern();
|
||||
private static final String s_unknown = "unknown".intern();
|
||||
private static final String s_cycle_barrier = "cycle_barrier".intern();
|
||||
private static final String s_elevator = "elevator".intern();
|
||||
private static final String s_2 = "2".intern();
|
||||
private static final String s_car_rental = "car_rental".intern();
|
||||
private static final String s_flagpole = "flagpole".intern();
|
||||
private static final String s_cabin = "cabin".intern();
|
||||
private static final String s_paved = "paved".intern();
|
||||
private static final String s_guest_house = "guest_house".intern();
|
||||
private static final String s_mobile_phone = "mobile_phone".intern();
|
||||
private static final String s_lot = "lot".intern();
|
||||
private static final String s_quarry = "quarry".intern();
|
||||
private static final String s_train_station = "train_station".intern();
|
||||
private static final String s_hotel = "hotel".intern();
|
||||
private static final String s_park = "park".intern();
|
||||
private static final String s_hut = "hut".intern();
|
||||
private static final String s_dentist = "dentist".intern();
|
||||
private static final String s_doctors = "doctors".intern();
|
||||
private static final String s_greenhouse = "greenhouse".intern();
|
||||
private static final String s_11 = "11".intern();
|
||||
private static final String s_10 = "10".intern();
|
||||
private static final String s_theme_park = "theme_park".intern();
|
||||
private static final String s_tree = "tree".intern();
|
||||
private static final String s_shower = "shower".intern();
|
||||
private static final String s_siding = "siding".intern();
|
||||
private static final String s_aeroway = "aeroway".intern();
|
||||
private static final String s_emergency_access_point = "emergency_access_point"
|
||||
.intern();
|
||||
private static final String s_watermill = "watermill".intern();
|
||||
private static final String s_college = "college".intern();
|
||||
private static final String s_landuse = "landuse".intern();
|
||||
private static final String s_tracktype = "tracktype".intern();
|
||||
private static final String s_ferry = "ferry".intern();
|
||||
private static final String s_bridge = "bridge".intern();
|
||||
private static final String s_vacant = "vacant".intern();
|
||||
private static final String s_cattle_grid = "cattle_grid".intern();
|
||||
private static final String s_brownfield = "brownfield".intern();
|
||||
private static final String s_allotments = "allotments".intern();
|
||||
private static final String s_alley = "alley".intern();
|
||||
private static final String s_pedestrian = "pedestrian".intern();
|
||||
private static final String s_borough = "borough".intern();
|
||||
private static final String s_bare_rock = "bare_rock".intern();
|
||||
private static final String s_motorcycle = "motorcycle".intern();
|
||||
private static final String s_bakery = "bakery".intern();
|
||||
private static final String s_zoo = "zoo".intern();
|
||||
private static final String s_scree = "scree".intern();
|
||||
private static final String s_fire_station = "fire_station".intern();
|
||||
private static final String s_theatre = "theatre".intern();
|
||||
private static final String s_track = "track".intern();
|
||||
private static final String s_reinforced_slope = "reinforced_slope".intern();
|
||||
private static final String s_slipway = "slipway".intern();
|
||||
private static final String s_mangrove = "mangrove".intern();
|
||||
private static final String s_aerodrome = "aerodrome".intern();
|
||||
private static final String s_byway = "byway".intern();
|
||||
private static final String s_metal = "metal".intern();
|
||||
private static final String s_swamp = "swamp".intern();
|
||||
private static final String s_construction = "construction".intern();
|
||||
private static final String s_grassland = "grassland".intern();
|
||||
private static final String s_shop = "shop".intern();
|
||||
private static final String s_soakhole = "soakhole".intern();
|
||||
private static final String s_asphalt = "asphalt".intern();
|
||||
private static final String s_social_facility = "social_facility".intern();
|
||||
private static final String s_isolated_dwelling = "isolated_dwelling".intern();
|
||||
private static final String s_hamlet = "hamlet".intern();
|
||||
private static final String s_picnic_table = "picnic_table".intern();
|
||||
private static final String s_artificial = "artificial".intern();
|
||||
private static final String s_earth = "earth".intern();
|
||||
private static final String s_grit_bin = "grit_bin".intern();
|
||||
private static final String s_ground = "ground".intern();
|
||||
private static final String s_groyne = "groyne".intern();
|
||||
private static final String s_office = "office".intern();
|
||||
private static final String s_state = "state".intern();
|
||||
private static final String s_terminal = "terminal".intern();
|
||||
private static final String s_wood = "wood".intern();
|
||||
private static final String s_fuel = "fuel".intern();
|
||||
private static final String s_8 = "8".intern();
|
||||
private static final String s_garden_centre = "garden_centre".intern();
|
||||
private static final String s_horse_riding = "horse_riding".intern();
|
||||
private static final String s_viewpoint = "viewpoint".intern();
|
||||
private static final String s_designated = "designated".intern();
|
||||
private static final String s_leisure = "leisure".intern();
|
||||
private static final String s_waste_basket = "waste_basket".intern();
|
||||
private static final String s_hifi = "hifi".intern();
|
||||
private static final String s_hedge = "hedge".intern();
|
||||
private static final String s_spur = "spur".intern();
|
||||
private static final String s_chimney = "chimney".intern();
|
||||
private static final String s_secondary = "secondary".intern();
|
||||
private static final String s_rest_area = "rest_area".intern();
|
||||
private static final String s_bar = "bar".intern();
|
||||
private static final String s_bay = "bay".intern();
|
||||
private static final String s_common = "common".intern();
|
||||
private static final String s_river = "river".intern();
|
||||
private static final String s_ruins = "ruins".intern();
|
||||
private static final String s_terrace = "terrace".intern();
|
||||
private static final String s_art = "art".intern();
|
||||
private static final String s_residental = "residental".intern();
|
||||
private static final String s_newsagent = "newsagent".intern();
|
||||
private static final String s_turntable = "turntable".intern();
|
||||
private static final String s_computer = "computer".intern();
|
||||
private static final String s_wetland = "wetland".intern();
|
||||
private static final String s_driveway = "driveway".intern();
|
||||
private static final String s_parking = "parking".intern();
|
||||
private static final String s_compacted = "compacted".intern();
|
||||
private static final String s_barn = "barn".intern();
|
||||
private static final String s_alpine_hut = "alpine_hut".intern();
|
||||
private static final String s_wire_fence = "wire_fence".intern();
|
||||
private static final String s_unpaved = "unpaved".intern();
|
||||
private static final String s_dormitory = "dormitory".intern();
|
||||
private static final String s_mud = "mud".intern();
|
||||
private static final String s_3 = "3".intern();
|
||||
private static final String s_semi = "semi".intern();
|
||||
private static final String s_boundary = "boundary".intern();
|
||||
private static final String s_field_boundary = "field_boundary".intern();
|
||||
private static final String s_beverages = "beverages".intern();
|
||||
private static final String s_supermarket = "supermarket".intern();
|
||||
private static final String s_store = "store".intern();
|
||||
private static final String s_restaurant = "restaurant".intern();
|
||||
private static final String s_region = "region".intern();
|
||||
private static final String s_variety_store = "variety_store".intern();
|
||||
private static final String s_saltmarsh = "saltmarsh".intern();
|
||||
private static final String s_landform = "landform".intern();
|
||||
private static final String s_helipad = "helipad".intern();
|
||||
private static final String s_railway = "railway".intern();
|
||||
private static final String s_greenhouse_horticulture = "greenhouse_horticulture"
|
||||
.intern();
|
||||
private static final String s_wall = "wall".intern();
|
||||
private static final String s_recycling = "recycling".intern();
|
||||
private static final String s_passing_place = "passing_place".intern();
|
||||
private static final String s_church = "church".intern();
|
||||
private static final String s_pharmacy = "pharmacy".intern();
|
||||
private static final String s_lighthouse = "lighthouse".intern();
|
||||
private static final String s_platform = "platform".intern();
|
||||
private static final String s_cinema = "cinema".intern();
|
||||
private static final String s_political = "political".intern();
|
||||
private static final String s_stadium = "stadium".intern();
|
||||
private static final String s_basin = "basin".intern();
|
||||
private static final String s_gasometer = "gasometer".intern();
|
||||
private static final String s_bicycle_parking = "bicycle_parking".intern();
|
||||
private static final String s_bbq = "bbq".intern();
|
||||
private static final String s_incline_steep = "incline_steep".intern();
|
||||
private static final String s_drinking_water = "drinking_water".intern();
|
||||
private static final String s_living_street = "living_street".intern();
|
||||
private static final String s_chalet = "chalet".intern();
|
||||
private static final String s_narrow_gauge = "narrow_gauge".intern();
|
||||
private static final String s_prison = "prison".intern();
|
||||
private static final String s_mine = "mine".intern();
|
||||
private static final String s_level_crossing = "level_crossing".intern();
|
||||
private static final String s_water_works = "water_works".intern();
|
||||
private static final String s_street_lamp = "street_lamp".intern();
|
||||
private static final String s_main = "main".intern();
|
||||
private static final String s_tank = "tank".intern();
|
||||
private static final String s_abandoned = "abandoned".intern();
|
||||
private static final String s_ski = "ski".intern();
|
||||
private static final String s_runway = "runway".intern();
|
||||
private static final String s_parking_space = "parking_space".intern();
|
||||
private static final String s_dirt_sand = "dirt/sand".intern();
|
||||
private static final String s_salt_pond = "salt_pond".intern();
|
||||
private static final String s_hedge_bank = "hedge_bank".intern();
|
||||
private static final String s_amenity = "amenity".intern();
|
||||
private static final String s_telephone = "telephone".intern();
|
||||
private static final String s_surface = "surface".intern();
|
||||
private static final String s_travel_agency = "travel_agency".intern();
|
||||
private static final String s_hardware = "hardware".intern();
|
||||
private static final String s_wastewater_plant = "wastewater_plant".intern();
|
||||
private static final String s_waterway = "waterway".intern();
|
||||
private static final String s_butcher = "butcher".intern();
|
||||
private static final String s_surveillance = "surveillance".intern();
|
||||
private static final String s_Dirt_Sand = "Dirt/Sand".intern();
|
||||
private static final String s_9 = "9".intern();
|
||||
private static final String s_windmill = "windmill".intern();
|
||||
private static final String s_picnic_site = "picnic_site".intern();
|
||||
private static final String s_rail = "rail".intern();
|
||||
private static final String s_cement = "cement".intern();
|
||||
private static final String s_sauna = "sauna".intern();
|
||||
private static final String s_suburb = "suburb".intern();
|
||||
private static final String s_waterfall = "waterfall".intern();
|
||||
private static final String s_bunker = "bunker".intern();
|
||||
private static final String s_ice_cream = "ice_cream".intern();
|
||||
private static final String s_culvert = "culvert".intern();
|
||||
private static final String s_drain = "drain".intern();
|
||||
private static final String s_dock = "dock".intern();
|
||||
private static final String s_glasshouse = "glasshouse".intern();
|
||||
private static final String s_no = "no".intern();
|
||||
private static final String s_well = "well".intern();
|
||||
private static final String s_wet_meadow = "wet_meadow".intern();
|
||||
private static final String s_concrete = "concrete".intern();
|
||||
private static final String s_dismount = "dismount".intern();
|
||||
private static final String s_vending_machine = "vending_machine".intern();
|
||||
private static final String s_oneway = "oneway".intern();
|
||||
private static final String s_taxi = "taxi".intern();
|
||||
private static final String s_outdoor = "outdoor".intern();
|
||||
private static final String s_proposed = "proposed".intern();
|
||||
private static final String s_sally_port = "sally_port".intern();
|
||||
private static final String s_photo = "photo".intern();
|
||||
private static final String s_plant_nursery = "plant_nursery".intern();
|
||||
private static final String s_clinic = "clinic".intern();
|
||||
private static final String s_fishing = "fishing".intern();
|
||||
private static final String s_yes = "yes".intern();
|
||||
private static final String s_turning_circle = "turning_circle".intern();
|
||||
private static final String s_toilets = "toilets".intern();
|
||||
private static final String s_guard_rail = "guard_rail".intern();
|
||||
private static final String s_townhall = "townhall".intern();
|
||||
private static final String s_community_centre = "community_centre".intern();
|
||||
private static final String s_residential = "residential".intern();
|
||||
private static final String s_cemetery = "cemetery".intern();
|
||||
private static final String s_survey_point = "survey_point".intern();
|
||||
private static final String s_bench = "bench".intern();
|
||||
private static final String s_4 = "4".intern();
|
||||
private static final String s_bollard = "bollard".intern();
|
||||
private static final String s_sports_centre = "sports_centre".intern();
|
||||
private static final String s_paving_stones_30 = "paving_stones:30".intern();
|
||||
private static final String s_administrative = "administrative".intern();
|
||||
private static final String s_Building = "Building".intern();
|
||||
private static final String s_customers = "customers".intern();
|
||||
private static final String s_emergency = "emergency".intern();
|
||||
private static final String s_motorway_junction = "motorway_junction".intern();
|
||||
private static final String s_grade1 = "grade1".intern();
|
||||
private static final String s_grade3 = "grade3".intern();
|
||||
private static final String s_grade2 = "grade2".intern();
|
||||
private static final String s_grade5 = "grade5".intern();
|
||||
private static final String s_grade4 = "grade4".intern();
|
||||
private static final String s_lock_gate = "lock_gate".intern();
|
||||
private static final String s_furniture = "furniture".intern();
|
||||
private static final String s_place_of_worship = "place_of_worship".intern();
|
||||
private static final String s_optician = "optician".intern();
|
||||
private static final String s_gift = "gift".intern();
|
||||
private static final String s_parking_entrance = "parking_entrance".intern();
|
||||
private static final String s_garage = "garage".intern();
|
||||
private static final String s_tram_stop = "tram_stop".intern();
|
||||
private static final String s_steps = "steps".intern();
|
||||
private static final String s_tower = "tower".intern();
|
||||
private static final String s_works = "works".intern();
|
||||
private static final String s_shed = "shed".intern();
|
||||
private static final String s_car_sharing = "car_sharing".intern();
|
||||
private static final String s_apartments = "apartments".intern();
|
||||
private static final String s_spring = "spring".intern();
|
||||
private static final String s_village = "village".intern();
|
||||
private static final String s_library = "library".intern();
|
||||
private static final String s_emergency_access = "emergency_access".intern();
|
||||
private static final String s_home = "home".intern();
|
||||
private static final String s_farm_auxiliary = "farm_auxiliary".intern();
|
||||
private static final String s_primary_link = "primary_link".intern();
|
||||
private static final String s_toll_booth = "toll_booth".intern();
|
||||
private static final String s_jewelry = "jewelry".intern();
|
||||
private static final String s_pet = "pet".intern();
|
||||
private static final String s_veterinary = "veterinary".intern();
|
||||
private static final String s_man_made = "man_made".intern();
|
||||
private static final String s_motorway_link = "motorway_link".intern();
|
||||
private static final String s_offices = "offices".intern();
|
||||
private static final String s_power = "power".intern();
|
||||
private static final String s_weir = "weir".intern();
|
||||
private static final String s_unsurfaced = "unsurfaced".intern();
|
||||
private static final String s_tertiary_link = "tertiary_link".intern();
|
||||
private static final String s_trunk_link = "trunk_link".intern();
|
||||
private static final String s_tyres = "tyres".intern();
|
||||
private static final String s_paving_stones = "paving_stones".intern();
|
||||
private static final String s_pipeline = "pipeline".intern();
|
||||
private static final String s_census = "census".intern();
|
||||
private static final String s_incline = "incline".intern();
|
||||
private static final String s_footway = "footway".intern();
|
||||
private static final String s_drive_through = "drive-through".intern();
|
||||
private static final String s_island = "island".intern();
|
||||
private static final String s_monitoring_station = "monitoring_station".intern();
|
||||
private static final String s_nightclub = "nightclub".intern();
|
||||
private static final String s_unclassified = "unclassified".intern();
|
||||
private static final String s_aquaculture = "aquaculture".intern();
|
||||
private static final String s_mixed = "mixed".intern();
|
||||
private static final String s_road = "road".intern();
|
||||
private static final String s_greenfield = "greenfield".intern();
|
||||
private static final String s_breakwater = "breakwater".intern();
|
||||
private static final String s_services = "services".intern();
|
||||
private static final String s_railway_crossing = "railway_crossing".intern();
|
||||
private static final String s_residentiel1 = "residentiel1".intern();
|
||||
private static final String s_canal = "canal".intern();
|
||||
private static final String s__1 = "-1".intern();
|
||||
private static final String s_ridge = "ridge".intern();
|
||||
private static final String s_fabric = "fabric".intern();
|
||||
private static final String s_museum = "museum".intern();
|
||||
private static final String s_communications_tower = "communications_tower".intern();
|
||||
private static final String s_semi_detached = "semi-detached".intern();
|
||||
private static final String s_conservation = "conservation".intern();
|
||||
private static final String s_way = "way".intern();
|
||||
private static final String s_wood_fence = "wood_fence".intern();
|
||||
private static final String s_manufacture = "manufacture".intern();
|
||||
private static final String s_admin_level = "admin_level".intern();
|
||||
private static final String s_building_concrete = "building_concrete".intern();
|
||||
private static final String s_bus = "bus".intern();
|
||||
private static final String s_collapsed = "collapsed".intern();
|
||||
private static final String s_ford = "ford".intern();
|
||||
private static final String s_delivery = "delivery".intern();
|
||||
private static final String s_garages = "garages".intern();
|
||||
private static final String s_funeral_directors = "funeral_directors".intern();
|
||||
private static final String s_land = "land".intern();
|
||||
private static final String s_interlock = "interlock".intern();
|
||||
private static final String s_reef = "reef".intern();
|
||||
private static final String s_crane = "crane".intern();
|
||||
private static final String s_true = "true".intern();
|
||||
private static final String s_storage_tank = "storage_tank".intern();
|
||||
private static final String s_official = "official".intern();
|
||||
private static final String s_subway_entrance = "subway_entrance".intern();
|
||||
private static final String s_mtb = "mtb".intern();
|
||||
private static final String s_grass = "grass".intern();
|
||||
private static final String s_marketplace = "marketplace".intern();
|
||||
private static final String s_rapids = "rapids".intern();
|
||||
private static final String s_car_wash = "car_wash".intern();
|
||||
private static final String s_general = "general".intern();
|
||||
private static final String s_cafe = "cafe".intern();
|
||||
private static final String s_locality = "locality".intern();
|
||||
private static final String s_glacier = "glacier".intern();
|
||||
private static final String s_storage = "storage".intern();
|
||||
private static final String s_cycleway = "cycleway".intern();
|
||||
private static final String s_forestry = "forestry".intern();
|
||||
private static final String s_field = "field".intern();
|
||||
private static final String s_5 = "5".intern();
|
||||
private static final String s_arts_centre = "arts_centre".intern();
|
||||
private static final String s_warehouse = "warehouse".intern();
|
||||
private static final String s_chemist = "chemist".intern();
|
||||
private static final String s_pier = "pier".intern();
|
||||
private static final String s_scrub = "scrub".intern();
|
||||
private static final String s_shelter = "shelter".intern();
|
||||
private static final String s_emergency_phone = "emergency_phone".intern();
|
||||
private static final String s_tidalflat = "tidalflat".intern();
|
||||
private static final String s_cobblestone = "cobblestone".intern();
|
||||
private static final String s_fell = "fell".intern();
|
||||
private static final String s_peak = "peak".intern();
|
||||
private static final String s_charging_station = "charging_station".intern();
|
||||
private static final String s_cliff = "cliff".intern();
|
||||
private static final String s_building = "building".intern();
|
||||
private static final String s_fire_hydrant = "fire_hydrant".intern();
|
||||
private static final String s_traffic_signals = "traffic_signals".intern();
|
||||
private static final String s_heath = "heath".intern();
|
||||
private static final String s_landfill = "landfill".intern();
|
||||
private static final String s_mast = "mast".intern();
|
||||
private static final String s_boutique = "boutique".intern();
|
||||
private static final String s_boat_storage = "boat_storage".intern();
|
||||
|
||||
public final static Tag[] tags = {
|
||||
|
||||
new Tag(s_building, s_yes, true), new Tag(s_highway, s_residential, true),
|
||||
new Tag(s_highway, s_service, true), new Tag(s_waterway, s_stream, true),
|
||||
new Tag(s_highway, s_unclassified, true), new Tag(s_highway, s_track, true),
|
||||
new Tag(s_oneway, s_yes, true), new Tag(s_natural, s_water, true),
|
||||
new Tag(s_highway, s_footway, true), new Tag(s_access, s_private, true),
|
||||
new Tag(s_highway, s_tertiary, true), new Tag(s_highway, s_path, true),
|
||||
new Tag(s_highway, s_secondary, true), new Tag(s_landuse, s_forest, true),
|
||||
new Tag(s_bridge, s_yes, true), new Tag(s_natural, s_tree, true),
|
||||
new Tag(s_surface, s_paved, true), new Tag(s_natural, s_wood, true),
|
||||
new Tag(s_highway, s_primary, true), new Tag(s_landuse, s_grass, true),
|
||||
new Tag(s_landuse, s_residential, true), new Tag(s_surface, s_unpaved, true),
|
||||
new Tag(s_highway, s_bus_stop, true), new Tag(s_surface, s_asphalt, true),
|
||||
new Tag(s_bicycle, s_yes, true), new Tag(s_amenity, s_parking, true),
|
||||
new Tag(s_place, s_locality, true), new Tag(s_railway, s_rail, true),
|
||||
new Tag(s_service, s_parking_aisle, true),
|
||||
new Tag(s_boundary, s_administrative, true),
|
||||
new Tag(s_building, s_house, true), new Tag(s_place, s_village, true),
|
||||
new Tag(s_natural, s_coastline, true), new Tag(s_tracktype, s_grade2, true),
|
||||
new Tag(s_oneway, s_no, true), new Tag(s_service, s_driveway, true),
|
||||
new Tag(s_highway, s_turning_circle, true), new Tag(s_place, s_hamlet, true),
|
||||
new Tag(s_natural, s_wetland, true), new Tag(s_tracktype, s_grade3, true),
|
||||
new Tag(s_waterway, s_river, true), new Tag(s_highway, s_cycleway, true),
|
||||
new Tag(s_barrier, s_fence, true), new Tag(s_building, s_residential, true),
|
||||
new Tag(s_amenity, s_school, true), new Tag(s_highway, s_crossing, true),
|
||||
new Tag(s_admin_level, s_8, true), new Tag(s_highway, s_trunk, true),
|
||||
new Tag(s_amenity, s_place_of_worship, true),
|
||||
new Tag(s_landuse, s_farmland, true), new Tag(s_tracktype, s_grade1, true),
|
||||
new Tag(s_highway, s_road, true), new Tag(s_landuse, s_farm, true),
|
||||
new Tag(s_surface, s_gravel, true), new Tag(s_landuse, s_meadow, true),
|
||||
new Tag(s_highway, s_motorway, true),
|
||||
new Tag(s_highway, s_traffic_signals, true),
|
||||
new Tag(s_building, s_hut, true), new Tag(s_highway, s_motorway_link, true),
|
||||
new Tag(s_tracktype, s_grade4, true), new Tag(s_barrier, s_gate, true),
|
||||
new Tag(s_highway, s_living_street, true), new Tag(s_bicycle, s_no, true),
|
||||
new Tag(s_leisure, s_pitch, true), new Tag(s_tunnel, s_yes, true),
|
||||
new Tag(s_surface, s_ground, true), new Tag(s_highway, s_steps, true),
|
||||
new Tag(s_natural, s_land, true), new Tag(s_man_made, s_survey_point, true),
|
||||
new Tag(s_tracktype, s_grade5, true), new Tag(s_waterway, s_ditch, true),
|
||||
new Tag(s_leisure, s_park, true), new Tag(s_amenity, s_restaurant, true),
|
||||
new Tag(s_barrier, s_wall, true), new Tag(s_waterway, s_riverbank, true),
|
||||
new Tag(s_amenity, s_bench, true), new Tag(s_building, s_garage, true),
|
||||
new Tag(s_natural, s_scrub, true), new Tag(s_highway, s_pedestrian, true),
|
||||
new Tag(s_natural, s_peak, true), new Tag(s_building, s_entrance, true),
|
||||
new Tag(s_landuse, s_reservoir, true), new Tag(s_access, s_yes, true),
|
||||
new Tag(s_bicycle, s_designated, true),
|
||||
new Tag(s_leisure, s_swimming_pool, true),
|
||||
new Tag(s_landuse, s_farmyard, true),
|
||||
new Tag(s_railway, s_level_crossing, true),
|
||||
new Tag(s_building, s_apartments, true), new Tag(s_surface, s_grass, true),
|
||||
new Tag(s_wheelchair, s_yes, true), new Tag(s_service, s_alley, true),
|
||||
new Tag(s_landuse, s_industrial, true), new Tag(s_amenity, s_fuel, true),
|
||||
new Tag(s_surface, s_dirt, true), new Tag(s_highway, s_trunk_link, true),
|
||||
new Tag(s_waterway, s_drain, true), new Tag(s_barrier, s_hedge, true),
|
||||
new Tag(s_amenity, s_grave_yard, true),
|
||||
new Tag(s_tourism, s_information, true),
|
||||
new Tag(s_shop, s_supermarket, true),
|
||||
new Tag(s_highway, s_primary_link, true), new Tag(s_wood, s_deciduous, true),
|
||||
new Tag(s_leisure, s_playground, true), new Tag(s_building, s_roof, true),
|
||||
new Tag(s_building, s_industrial, true),
|
||||
new Tag(s_amenity, s_post_box, true), new Tag(s_waterway, s_canal, true),
|
||||
new Tag(s_barrier, s_bollard, true), new Tag(s_leisure, s_garden, true),
|
||||
new Tag(s_wood, s_mixed, true), new Tag(s_landuse, s_cemetery, true),
|
||||
new Tag(s_landuse, s_orchard, true), new Tag(s_shop, s_convenience, true),
|
||||
new Tag(s_access, s_permissive, true), new Tag(s_surface, s_concrete, true),
|
||||
new Tag(s_surface, s_paving_stones, true), new Tag(s_service, s_spur, true),
|
||||
new Tag(s_building, s_garages, true), new Tag(s_amenity, s_bank, true),
|
||||
new Tag(s_tourism, s_hotel, true), new Tag(s_access, s_no, true),
|
||||
new Tag(s_amenity, s_fast_food, true), new Tag(s_man_made, s_pier, true),
|
||||
new Tag(s_amenity, s_kindergarten, true),
|
||||
new Tag(s_access, s_agricultural, true),
|
||||
new Tag(s_surface, s_cobblestone, true), new Tag(s_wheelchair, s_no, true),
|
||||
new Tag(s_amenity, s_cafe, true), new Tag(s_amenity, s_hospital, true),
|
||||
new Tag(s_amenity, s_post_office, true),
|
||||
new Tag(s_amenity, s_public_building, true),
|
||||
new Tag(s_amenity, s_recycling, true),
|
||||
new Tag(s_highway, s_street_lamp, true), new Tag(s_man_made, s_tower, true),
|
||||
new Tag(s_waterway, s_dam, true), new Tag(s_amenity, s_pub, true),
|
||||
new Tag(s_wood, s_coniferous, true), new Tag(s_access, s_destination, true),
|
||||
new Tag(s_admin_level, s_6, true), new Tag(s_landuse, s_commercial, true),
|
||||
new Tag(s_amenity, s_pharmacy, true), new Tag(s_railway, s_abandoned, true),
|
||||
new Tag(s_service, s_yard, true), new Tag(s_place, s_island, true),
|
||||
new Tag(s_oneway, s__1, true), new Tag(s_landuse, s_quarry, true),
|
||||
new Tag(s_landuse, s_vineyard, true),
|
||||
new Tag(s_highway, s_motorway_junction, true),
|
||||
new Tag(s_railway, s_station, true), new Tag(s_landuse, s_allotments, true),
|
||||
new Tag(s_barrier, s_lift_gate, true), new Tag(s_admin_level, s_10, true),
|
||||
new Tag(s_amenity, s_telephone, true), new Tag(s_place, s_town, true),
|
||||
new Tag(s_man_made, s_cutline, true), new Tag(s_place, s_suburb, true),
|
||||
new Tag(s_aeroway, s_taxiway, true), new Tag(s_wheelchair, s_limited, true),
|
||||
new Tag(s_highway, s_secondary_link, true),
|
||||
new Tag(s_leisure, s_sports_centre, true),
|
||||
new Tag(s_amenity, s_bicycle_parking, true),
|
||||
new Tag(s_surface, s_sand, true), new Tag(s_highway, s_stop, true),
|
||||
new Tag(s_man_made, s_works, true), new Tag(s_landuse, s_retail, true),
|
||||
new Tag(s_amenity, s_fire_station, true), new Tag(s_service, s_siding, true),
|
||||
new Tag(s_amenity, s_toilets, true), new Tag(s_bench, s_yes, true),
|
||||
new Tag(s_oneway, s_1, true), new Tag(s_surface, s_compacted, true),
|
||||
new Tag(s_landuse, s_basin, true), new Tag(s_amenity, s_police, true),
|
||||
new Tag(s_railway, s_tram, true), new Tag(s_route, s_road, true),
|
||||
new Tag(s_natural, s_cliff, true), new Tag(s_highway, s_construction, true),
|
||||
new Tag(s_aeroway, s_aerodrome, true), new Tag(s_entrance, s_yes, true),
|
||||
new Tag(s_man_made, s_storage_tank, true), new Tag(s_amenity, s_atm, true),
|
||||
new Tag(s_tourism, s_attraction, true), new Tag(s_route, s_bus, true),
|
||||
new Tag(s_shop, s_bakery, true), new Tag(s_tourism, s_viewpoint, true),
|
||||
new Tag(s_amenity, s_swimming_pool, true), new Tag(s_natural, s_beach, true),
|
||||
new Tag(s_tourism, s_picnic_site, true), new Tag(s_oneway, s_true, true),
|
||||
new Tag(s_highway, s_bridleway, true), new Tag(s_tourism, s_camp_site, true),
|
||||
new Tag(s_abutters, s_residential, true),
|
||||
new Tag(s_leisure, s_nature_reserve, true),
|
||||
new Tag(s_amenity, s_drinking_water, true), new Tag(s_shop, s_clothes, true),
|
||||
new Tag(s_natural, s_heath, true),
|
||||
new Tag(s_highway, s_mini_roundabout, true),
|
||||
new Tag(s_landuse, s_construction, true),
|
||||
new Tag(s_amenity, s_waste_basket, true),
|
||||
new Tag(s_railway, s_platform, true), new Tag(s_amenity, s_townhall, true),
|
||||
new Tag(s_shop, s_hairdresser, true), new Tag(s_amenity, s_shelter, true),
|
||||
new Tag(s_admin_level, s_9, true),
|
||||
new Tag(s_building, s_farm_auxiliary, true),
|
||||
new Tag(s_amenity, s_library, true), new Tag(s_building, s_detached, true),
|
||||
new Tag(s_admin_level, s_4, true), new Tag(s_landuse, s_village_green, true),
|
||||
new Tag(s_barrier, s_stile, true), new Tag(s_landuse, s_garages, true),
|
||||
new Tag(s_amenity, s_bar, true), new Tag(s_railway, s_buffer_stop, true),
|
||||
new Tag(s_wetland, s_marsh, true), new Tag(s_tourism, s_museum, true),
|
||||
new Tag(s_barrier, s_cycle_barrier, true), new Tag(s_route, s_bicycle, true),
|
||||
new Tag(s_railway, s_tram_stop, true),
|
||||
new Tag(s_amenity, s_parking_space, true),
|
||||
new Tag(s_barrier, s_retaining_wall, true),
|
||||
new Tag(s_landuse, s_recreation_ground, true),
|
||||
new Tag(s_amenity, s_university, true),
|
||||
new Tag(s_highway, s_tertiary_link, true),
|
||||
new Tag(s_building, s_terrace, true), new Tag(s_shop, s_car_repair, true),
|
||||
new Tag(s_amenity, s_hunting_stand, true),
|
||||
new Tag(s_amenity, s_fountain, true), new Tag(s_man_made, s_pipeline, true),
|
||||
new Tag(s_wetland, s_swamp, true), new Tag(s_shop, s_car, true),
|
||||
new Tag(s_bench, s_no, true), new Tag(s_tunnel, s_culvert, true),
|
||||
new Tag(s_building, s_school, true), new Tag(s_barrier, s_entrance, true),
|
||||
new Tag(s_railway, s_disused, true), new Tag(s_railway, s_crossing, true),
|
||||
new Tag(s_building, s_church, true),
|
||||
new Tag(s_amenity, s_social_facility, true), new Tag(s_natural, s_bay, true),
|
||||
new Tag(s_shop, s_kiosk, true), new Tag(s_amenity, s_vending_machine, true),
|
||||
new Tag(s_route, s_hiking, true), new Tag(s_natural, s_spring, true),
|
||||
new Tag(s_leisure, s_common, true), new Tag(s_railway, s_switch, true),
|
||||
new Tag(s_waterway, s_rapids, true), new Tag(s_admin_level, s_7, true),
|
||||
new Tag(s_leisure, s_stadium, true), new Tag(s_leisure, s_track, true),
|
||||
new Tag(s_place, s_isolated_dwelling, true), new Tag(s_place, s_islet, true),
|
||||
new Tag(s_waterway, s_weir, true), new Tag(s_amenity, s_doctors, true),
|
||||
new Tag(s_access, s_designated, true),
|
||||
new Tag(s_landuse, s_conservation, true),
|
||||
new Tag(s_waterway, s_artificial, true),
|
||||
new Tag(s_amenity, s_bus_station, true),
|
||||
new Tag(s_leisure, s_golf_course, true),
|
||||
new Tag(s_shop, s_doityourself, true), new Tag(s_building, s_service, true),
|
||||
new Tag(s_tourism, s_guest_house, true), new Tag(s_aeroway, s_runway, true),
|
||||
new Tag(s_place, s_city, true), new Tag(s_railway, s_subway, true),
|
||||
new Tag(s_man_made, s_wastewater_plant, true),
|
||||
new Tag(s_building, s_commercial, true), new Tag(s_railway, s_halt, true),
|
||||
new Tag(s_amenity, s_emergency_phone, true),
|
||||
new Tag(s_building, s_retail, true), new Tag(s_barrier, s_block, true),
|
||||
new Tag(s_leisure, s_recreation_ground, true),
|
||||
new Tag(s_access, s_forestry, true), new Tag(s_amenity, s_college, true),
|
||||
new Tag(s_highway, s_platform, true), new Tag(s_access, s_unknown, true),
|
||||
new Tag(s_man_made, s_water_tower, true),
|
||||
new Tag(s_surface, s_pebblestone, true), new Tag(s_bridge, s_viaduct, true),
|
||||
new Tag(s_shop, s_butcher, true), new Tag(s_shop, s_florist, true),
|
||||
new Tag(s_boundary, s_landuse, true), new Tag(s_aeroway, s_helipad, true),
|
||||
new Tag(s_building, s_hangar, true), new Tag(s_natural, s_glacier, true),
|
||||
new Tag(s_highway, s_proposed, true), new Tag(s_shop, s_mall, true),
|
||||
new Tag(s_barrier, s_toll_booth, true),
|
||||
new Tag(s_amenity, s_fire_hydrant, true),
|
||||
new Tag(s_building, s_manufacture, true), new Tag(s_building, s_farm, true),
|
||||
new Tag(s_surface, s_wood, true), new Tag(s_amenity, s_car_wash, true),
|
||||
new Tag(s_amenity, s_dentist, true), new Tag(s_natural, s_marsh, true),
|
||||
new Tag(s_man_made, s_surveillance, true), new Tag(s_shop, s_bicycle, true),
|
||||
new Tag(s_route, s_foot, true), new Tag(s_amenity, s_theatre, true),
|
||||
new Tag(s_building, s_office, true), new Tag(s_railway, s_light_rail, true),
|
||||
new Tag(s_man_made, s_petroleum_well, true),
|
||||
new Tag(s_amenity, s_taxi, true), new Tag(s_building, s_greenhouse, true),
|
||||
new Tag(s_landuse, s_brownfield, true),
|
||||
new Tag(s_bicycle, s_permissive, true), new Tag(s_admin_level, s_2, true),
|
||||
new Tag(s_aeroway, s_apron, true), new Tag(s_building, s_cabin, true),
|
||||
new Tag(s_amenity, s_cinema, true), new Tag(s_access, s_customers, true),
|
||||
new Tag(s_tourism, s_motel, true), new Tag(s_railway, s_narrow_gauge, true),
|
||||
new Tag(s_amenity, s_marketplace, true), new Tag(s_shop, s_furniture, true),
|
||||
new Tag(s_entrance, s_staircase, true), new Tag(s_tourism, s_artwork, true),
|
||||
new Tag(s_natural, s_grassland, true), new Tag(s_shop, s_books, true),
|
||||
new Tag(s_admin_level, s_5, true), new Tag(s_man_made, s_groyne, true),
|
||||
new Tag(s_waterway, s_lock_gate, true),
|
||||
new Tag(s_highway, s_emergency_access_point, true),
|
||||
new Tag(s_natural, s_sand, true), new Tag(s_landuse, s_military, true),
|
||||
new Tag(s_boundary, s_protected_area, true),
|
||||
new Tag(s_amenity, s_community_centre, true),
|
||||
new Tag(s_barrier, s_kissing_gate, true),
|
||||
new Tag(s_highway, s_speed_camera, true),
|
||||
new Tag(s_boundary, s_national_park, true),
|
||||
new Tag(s_railway, s_subway_entrance, true),
|
||||
new Tag(s_man_made, s_silo, true), new Tag(s_shop, s_alcohol, true),
|
||||
new Tag(s_highway, s_give_way, true), new Tag(s_leisure, s_slipway, true),
|
||||
new Tag(s_shop, s_electronics, true), new Tag(s_bicycle, s_dismount, true),
|
||||
new Tag(s_leisure, s_marina, true), new Tag(s_entrance, s_main, true),
|
||||
new Tag(s_boundary, s_postal_code, true),
|
||||
new Tag(s_landuse, s_greenhouse_horticulture, true),
|
||||
new Tag(s_highway, s_milestone, true),
|
||||
new Tag(s_natural, s_cave_entrance, true),
|
||||
new Tag(s_landuse, s_landfill, true), new Tag(s_shop, s_chemist, true),
|
||||
new Tag(s_shop, s_shoes, true), new Tag(s_barrier, s_cattle_grid, true),
|
||||
new Tag(s_landuse, s_railway, true), new Tag(s_tourism, s_hostel, true),
|
||||
new Tag(s_tourism, s_chalet, true), new Tag(s_place, s_county, true),
|
||||
new Tag(s_shop, s_department_store, true), new Tag(s_highway, s_ford, true),
|
||||
new Tag(s_natural, s_scree, true), new Tag(s_landuse, s_greenfield, true),
|
||||
new Tag(s_amenity, s_nursing_home, true),
|
||||
new Tag(s_barrier, s_wire_fence, true),
|
||||
new Tag(s_access, s_restricted, true),
|
||||
new Tag(s_man_made, s_reservoir_covered, true),
|
||||
new Tag(s_amenity, s_bicycle_rental, true), new Tag(s_man_made, s_MDF, true),
|
||||
new Tag(s_man_made, s_water_well, true), new Tag(s_landuse, s_field, true),
|
||||
new Tag(s_landuse, s_wood, true), new Tag(s_shop, s_hardware, true),
|
||||
new Tag(s_tourism, s_alpine_hut, true), new Tag(s_natural, s_tree_row, true),
|
||||
new Tag(s_tourism, s_caravan_site, true), new Tag(s_bridge, s_no, true),
|
||||
new Tag(s_wetland, s_bog, true), new Tag(s_amenity, s_courthouse, true),
|
||||
new Tag(s_route, s_ferry, true), new Tag(s_barrier, s_city_wall, true),
|
||||
new Tag(s_amenity, s_veterinary, true), new Tag(s_shop, s_jewelry, true),
|
||||
new Tag(s_building, s_transportation, true),
|
||||
new Tag(s_amenity, s_arts_centre, true),
|
||||
new Tag(s_bicycle, s_official, true), new Tag(s_shop, s_optician, true),
|
||||
new Tag(s_shop, s_yes, true), new Tag(s_building, s_collapsed, true),
|
||||
new Tag(s_shop, s_garden_centre, true), new Tag(s_man_made, s_chimney, true),
|
||||
new Tag(s_man_made, s_mine, true), new Tag(s_bench, s_unknown, true),
|
||||
new Tag(s_railway, s_preserved, true), new Tag(s_building, s_public, true),
|
||||
new Tag(s_amenity, s_ferry_terminal, true),
|
||||
new Tag(s_highway, s_raceway, true), new Tag(s_natural, s_rock, true),
|
||||
new Tag(s_tunnel, s_no, true), new Tag(s_building, s_university, true),
|
||||
new Tag(s_shop, s_beverages, true),
|
||||
new Tag(s_amenity, s_waste_disposal, true),
|
||||
new Tag(s_building, s_warehouse, true),
|
||||
new Tag(s_leisure, s_water_park, true), new Tag(s_shop, s_gift, true),
|
||||
new Tag(s_place, s_farm, true), new Tag(s_wetland, s_tidalflat, true),
|
||||
new Tag(s_waterway, s_waterfall, true), new Tag(s_man_made, s_dolphin, true),
|
||||
new Tag(s_service, s_drive_through, true),
|
||||
new Tag(s_amenity, s_nightclub, true), new Tag(s_building, s_shed, true),
|
||||
new Tag(s_shop, s_greengrocer, true), new Tag(s_natural, s_fell, true),
|
||||
new Tag(s_wetland, s_wet_meadow, true), new Tag(s_aeroway, s_gate, true),
|
||||
new Tag(s_shop, s_computer, true), new Tag(s_man_made, s_lighthouse, true),
|
||||
new Tag(s_wetland, s_reedbed, true), new Tag(s_man_made, s_breakwater, true),
|
||||
new Tag(s_surface, s_Dirt_Sand, true), new Tag(s_barrier, s_ditch, true),
|
||||
new Tag(s_barrier, s_yes, true), new Tag(s_amenity, s_biergarten, true),
|
||||
new Tag(s_shop, s_mobile_phone, true), new Tag(s_route, s_mtb, true),
|
||||
new Tag(s_amenity, s_grit_bin, true), new Tag(s_amenity, s_bbq, true),
|
||||
new Tag(s_shop, s_sports, true), new Tag(s_barrier, s_wood_fence, true),
|
||||
new Tag(s_entrance, s_home, true), new Tag(s_shop, s_laundry, true),
|
||||
new Tag(s_man_made, s_gasometer, true),
|
||||
new Tag(s_barrier, s_embankment, true), new Tag(s_shop, s_toys, true),
|
||||
new Tag(s_wetland, s_saltmarsh, true), new Tag(s_waterway, s_soakhole, true),
|
||||
new Tag(s_shop, s_travel_agency, true),
|
||||
new Tag(s_man_made, s_water_works, true), new Tag(s_route, s_railway, true),
|
||||
new Tag(s_amenity, s_prison, true), new Tag(s_highway, s_rest_area, true),
|
||||
new Tag(s_shop, s_stationery, true), new Tag(s_admin_level, s_11, true),
|
||||
new Tag(s_building, s_train_station, true),
|
||||
new Tag(s_building, s_storage_tank, true),
|
||||
new Tag(s_man_made, s_windmill, true), new Tag(s_shop, s_beauty, true),
|
||||
new Tag(s_building, s_semi, true), new Tag(s_highway, s_services, true),
|
||||
new Tag(s_bicycle, s_private, true), new Tag(s_route, s_ski, true),
|
||||
new Tag(s_service, s_emergency_access, true),
|
||||
new Tag(s_building, s_factory, true),
|
||||
new Tag(s_man_made, s_reinforced_slope, true),
|
||||
new Tag(s_amenity, s_car_sharing, true), new Tag(s_surface, s_earth, true),
|
||||
new Tag(s_shop, s_hifi, true), new Tag(s_amenity, s_car_rental, true),
|
||||
new Tag(s_barrier, s_hedge_bank, true),
|
||||
new Tag(s_shop, s_confectionery, true), new Tag(s_aeroway, s_terminal, true),
|
||||
new Tag(s_highway, s_passing_place, true),
|
||||
new Tag(s_building, s_building, true), new Tag(s_man_made, s_dyke, true),
|
||||
new Tag(s_building, s_construction, true), new Tag(s_building, s_shop, true),
|
||||
new Tag(s_natural, s_reef, true), new Tag(s_landuse, s_aquaculture, true),
|
||||
new Tag(s_shop, s_dry_cleaning, true), new Tag(s_amenity, s_embassy, true),
|
||||
new Tag(s_shop, s_newsagent, true), new Tag(s_landuse, s_salt_pond, true),
|
||||
new Tag(s_railway, s_spur, true), new Tag(s_wheelchair, s_unknown, true),
|
||||
new Tag(s_tourism, s_zoo, true), new Tag(s_man_made, s_waterway, true),
|
||||
new Tag(s_surface, s_fine_gravel, true), new Tag(s_shop, s_motorcycle, true),
|
||||
new Tag(s_building, s_Building, true),
|
||||
new Tag(s_railway, s_construction, true),
|
||||
new Tag(s_place, s_neighbourhood, true), new Tag(s_route, s_train, true),
|
||||
new Tag(s_building, s_no, true), new Tag(s_natural, s_mud, true),
|
||||
new Tag(s_place, s_region, true),
|
||||
new Tag(s_landuse, s_reservoir_watershed, true),
|
||||
new Tag(s_boundary, s_marker, true), new Tag(s_man_made, s_beacon, true),
|
||||
new Tag(s_shop, s_outdoor, true), new Tag(s_access, s_public, true),
|
||||
new Tag(s_abutters, s_industrial, true), new Tag(s_building, s_barn, true),
|
||||
new Tag(s_leisure, s_picnic_table, true),
|
||||
new Tag(s_building, s_hospital, true), new Tag(s_access, s_official, true),
|
||||
new Tag(s_shop, s_variety_store, true), new Tag(s_man_made, s_crane, true),
|
||||
new Tag(s_amenity, s_parking_fuel, true), new Tag(s_route, s_tram, true),
|
||||
new Tag(s_tourism, s_theme_park, true), new Tag(s_shop, s_pet, true),
|
||||
new Tag(s_building, s_kindergarten, true),
|
||||
new Tag(s_man_made, s_storage, true), new Tag(s_man_made, s_mast, true),
|
||||
new Tag(s_amenity, s_parking_entrance, true),
|
||||
new Tag(s_amenity, s_clock, true),
|
||||
new Tag(s_landuse, s_industrial_retail, true),
|
||||
new Tag(s_shop, s_video, true), new Tag(s_access, s_delivery, true),
|
||||
new Tag(s_amenity, s_driving_school, true), new Tag(s_service, s_yes, true),
|
||||
new Tag(s_natural, s_bare_rock, true), new Tag(s_building, s_chapel, true),
|
||||
new Tag(s_natural, s_volcano, true), new Tag(s_waterway, s_dock, true),
|
||||
new Tag(s_building, s_dormitory, true),
|
||||
new Tag(s_amenity, s_boat_storage, true), new Tag(s_man_made, s_tank, true),
|
||||
new Tag(s_man_made, s_flagpole, true),
|
||||
new Tag(s_surface, s_grass_paver, true), new Tag(s_shop, s_organic, true),
|
||||
new Tag(s_natural, s_landform, true), new Tag(s_highway, s_unsurfaced, true),
|
||||
new Tag(s_route, s_power, true), new Tag(s_surface, s_mud, true),
|
||||
new Tag(s_building, s_building_concrete, true),
|
||||
new Tag(s_abutters, s_retail, true), new Tag(s_building, s_store, true),
|
||||
new Tag(s_shop, s_vacant, true), new Tag(s_leisure, s_miniature_golf, true),
|
||||
new Tag(s_man_made, s_monitoring_station, true),
|
||||
new Tag(s_natural, s_waterfall, true), new Tag(s_aeroway, s_hangar, true),
|
||||
new Tag(s_shop, s_boutique, true), new Tag(s_route, s_detour, true),
|
||||
new Tag(s_building, s_way, true), new Tag(s_railway, s_stop, true),
|
||||
new Tag(s_amenity, s_ice_cream, true), new Tag(s_building, s_storage, true),
|
||||
new Tag(s_shop, s_car_parts, true), new Tag(s_natural, s_ridge, true),
|
||||
new Tag(s_shop, s_tyres, true), new Tag(s_railway, s_dismantled, true),
|
||||
new Tag(s_amenity, s_shop, true), new Tag(s_landuse, s_plant_nursery, true),
|
||||
new Tag(s_building, s_residentiel1, true),
|
||||
new Tag(s_barrier, s_field_boundary, true),
|
||||
new Tag(s_barrier, s_border_control, true),
|
||||
new Tag(s_surface, s_Paved, true), new Tag(s_barrier, s_sally_port, true),
|
||||
new Tag(s_amenity, s_bureau_de_change, true),
|
||||
new Tag(s_leisure, s_fishing, true),
|
||||
new Tag(s_amenity, s_charging_station, true),
|
||||
new Tag(s_building, s_supermarket, true), new Tag(s_highway, s_stile, true),
|
||||
new Tag(s_amenity, s_sauna, true), new Tag(s_place, s_municipality, true),
|
||||
new Tag(s_building, s_hotel, true), new Tag(s_surface, s_metal, true),
|
||||
new Tag(s_highway, s_incline_steep, true),
|
||||
new Tag(s_shop, s_estate_agent, true), new Tag(s_natural, s_grass, true),
|
||||
new Tag(s_shop, s_pharmacy, true),
|
||||
new Tag(s_surface, s_concrete_plates, true),
|
||||
new Tag(s_shop, s_copyshop, true),
|
||||
new Tag(s_surface, s_paving_stones_30, true),
|
||||
new Tag(s_surface, s_interlock, true), new Tag(s_access, s_hov, true),
|
||||
new Tag(s_highway, s_elevator, true),
|
||||
new Tag(s_boundary, s_local_authority, true),
|
||||
new Tag(s_man_made, s_communications_tower, true),
|
||||
new Tag(s_shop, s_deli, true), new Tag(s_barrier, s_turnstile, true),
|
||||
new Tag(s_building, s_offices, true), new Tag(s_building, s_bunker, true),
|
||||
new Tag(s_natural, s_stone, true),
|
||||
new Tag(s_railway, s_railway_crossing, true),
|
||||
new Tag(s_leisure, s_dog_park, true),
|
||||
new Tag(s_building, s_semi_detached, true),
|
||||
new Tag(s_man_made, s_watermill, true), new Tag(s_route, s_trolleybus, true),
|
||||
new Tag(s_admin_level, s_3, true), new Tag(s_building, s_block, true),
|
||||
new Tag(s_barrier, s_guard_rail, true), new Tag(s_bicycle, s_unknown, true),
|
||||
new Tag(s_highway, s_abandoned, true), new Tag(s_surface, s_dirt_sand, true),
|
||||
new Tag(s_barrier, s_chain, true), new Tag(s_barrier, s_bump_gate, true),
|
||||
new Tag(s_building, s_residental, true), new Tag(s_surface, s_cement, true),
|
||||
new Tag(s_man_made, s_embankment, true), new Tag(s_building, s_ruins, true),
|
||||
new Tag(s_highway, s_incline, true), new Tag(s_abutters, s_commercial, true),
|
||||
new Tag(s_barrier, s_hampshire_gate, true), new Tag(s_shop, s_music, true),
|
||||
new Tag(s_shop, s_funeral_directors, true),
|
||||
new Tag(s_wetland, s_mangrove, true), new Tag(s_place, s_borough, true),
|
||||
new Tag(s_building, s_apartment, true), new Tag(s_boundary, s_census, true),
|
||||
new Tag(s_barrier, s_kerb, true), new Tag(s_building, s_glasshouse, true),
|
||||
new Tag(s_aeroway, s_holding_position, true),
|
||||
new Tag(s_shop, s_general, true), new Tag(s_building, s_tank, true),
|
||||
new Tag(s_railway, s_monorail, true), new Tag(s_service, s_parking, true),
|
||||
new Tag(s_place, s_state, true), new Tag(s_railway, s_proposed, true),
|
||||
new Tag(s_shop, s_art, true), new Tag(s_natural, s_hill, true),
|
||||
new Tag(s_railway, s_turntable, true), new Tag(s_tourism, s_cabin, true),
|
||||
new Tag(s_shop, s_photo, true), new Tag(s_boundary, s_lot, true),
|
||||
new Tag(s_shop, s_fishmonger, true), new Tag(s_amenity, s_clinic, true),
|
||||
new Tag(s_boundary, s_political, true), new Tag(s_man_made, s_well, true),
|
||||
new Tag(s_highway, s_byway, true), new Tag(s_leisure, s_horse_riding, true),
|
||||
new Tag(s_service, s_bus, true), new Tag(s_building, s_tower, true),
|
||||
new Tag(s_entrance, s_service, true), new Tag(s_shop, s_fabric, true),
|
||||
new Tag(s_railway, s_miniature, true), new Tag(s_abutters, s_mixed, true),
|
||||
new Tag(s_surface, s_stone, true), new Tag(s_access, s_emergency, true),
|
||||
new Tag(s_landuse, s_mine, true), new Tag(s_amenity, s_shower, true),
|
||||
new Tag(s_waterway, s_lock, true)
|
||||
};
|
||||
}
|
||||
@ -33,13 +33,18 @@ import org.mapsforge.database.FileOpenResult;
|
||||
import org.mapsforge.database.IMapDatabase;
|
||||
import org.mapsforge.database.IMapDatabaseCallback;
|
||||
import org.mapsforge.database.MapFileInfo;
|
||||
import org.mapsforge.database.QueryResult;
|
||||
import org.postgresql.PGConnection;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MapDatabase implements IMapDatabase {
|
||||
private final static String TAG = "MapDatabase";
|
||||
|
||||
private static final String QUERY = "SELECT tags, geom FROM __get_tile(?,?,?)";
|
||||
|
||||
private final float mScale = 1; // 1000000.0f;
|
||||
@ -47,7 +52,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
private int mCoordPos = 0;
|
||||
private int mIndexPos = 0;
|
||||
private float[] mCoords = new float[100000];
|
||||
private int[] mIndex = new int[10000];
|
||||
private short[] mIndex = new short[10000];
|
||||
|
||||
private Tag[] mTags;
|
||||
|
||||
@ -66,7 +71,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
private boolean connect() {
|
||||
Connection conn = null;
|
||||
String dburl = "jdbc:postgresql://city.informatik.uni-bremen.de:5432/gis";
|
||||
String dburl = "jdbc:postgresql://city.informatik.uni-bremen.de:5432/gis-2.0";
|
||||
|
||||
Properties dbOpts = new Properties();
|
||||
dbOpts.setProperty("user", "osm");
|
||||
@ -97,44 +102,45 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
public QueryResult executeQuery(Tile tile, IMapDatabaseCallback mapDatabaseCallback) {
|
||||
if (connection == null) {
|
||||
if (!connect())
|
||||
return;
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
ResultSet r;
|
||||
|
||||
try {
|
||||
prepQuery.setLong(1, tile.pixelX);
|
||||
prepQuery.setLong(2, tile.pixelY);
|
||||
prepQuery.setLong(1, tile.tileX * 256);
|
||||
prepQuery.setLong(2, tile.tileY * 256);
|
||||
prepQuery.setInt(3, tile.zoomLevel);
|
||||
System.out.println("" + prepQuery.toString());
|
||||
Log.d(TAG, "" + prepQuery.toString());
|
||||
prepQuery.execute();
|
||||
r = prepQuery.getResultSet();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
connection = null;
|
||||
return;
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
|
||||
byte[] b = null;
|
||||
PGHStore h = null;
|
||||
|
||||
int cnt = 0;
|
||||
try {
|
||||
while (r != null && r.next()) {
|
||||
mIndexPos = 0;
|
||||
mCoordPos = 0;
|
||||
|
||||
cnt++;
|
||||
try {
|
||||
Object obj = r.getObject(1);
|
||||
h = null;
|
||||
|
||||
if (obj instanceof PGHStore)
|
||||
h = (PGHStore) obj;
|
||||
else
|
||||
else {
|
||||
Log.d(TAG, "no tags: skip way");
|
||||
continue;
|
||||
|
||||
}
|
||||
b = r.getBytes(2);
|
||||
|
||||
} catch (SQLException e) {
|
||||
@ -142,15 +148,16 @@ public class MapDatabase implements IMapDatabase {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
if (b == null) {
|
||||
// Log.d(TAG, "no geometry: skip way");
|
||||
continue;
|
||||
|
||||
}
|
||||
mTags = new Tag[h.size()];
|
||||
|
||||
int i = 0;
|
||||
for (Entry<String, String> t : h.entrySet()) {
|
||||
if (t.getKey() == null) {
|
||||
System.out.println("no KEY !!! ");
|
||||
Log.d(TAG, "no KEY !!! ");
|
||||
break;
|
||||
}
|
||||
Tag tag = tagHash.get(t);
|
||||
@ -164,18 +171,27 @@ public class MapDatabase implements IMapDatabase {
|
||||
if (i < mTags.length)
|
||||
continue;
|
||||
|
||||
parse(b);
|
||||
if (mIndexPos == 0)
|
||||
boolean polygon = parse(b);
|
||||
if (mIndexPos == 0) {
|
||||
Log.d(TAG, "no index: skip way");
|
||||
continue;
|
||||
} else if (mIndexPos == 1) {
|
||||
mapDatabaseCallback.renderPointOfInterest((byte) 0, mCoords[1],
|
||||
mCoords[0], mTags);
|
||||
} else {
|
||||
|
||||
int[] idx = new int[mIndexPos];
|
||||
System.arraycopy(mIndex, 0, idx, 0, mIndexPos);
|
||||
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, idx, true);
|
||||
short[] idx = new short[mIndexPos];
|
||||
System.arraycopy(mIndex, 0, idx, 0, mIndexPos);
|
||||
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, idx, polygon);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
connection = null;
|
||||
return QueryResult.FAILED;
|
||||
}
|
||||
// Log.d(TAG, "rows: " + cnt);
|
||||
return QueryResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -237,11 +253,11 @@ public class MapDatabase implements IMapDatabase {
|
||||
* @param value
|
||||
* ...
|
||||
*/
|
||||
private void parse(byte[] value) {
|
||||
parseGeometry(valueGetterForEndian(value));
|
||||
private boolean parse(byte[] value) {
|
||||
return parseGeometry(valueGetterForEndian(value));
|
||||
}
|
||||
|
||||
private void parseGeometry(ValueGetter data) {
|
||||
private boolean parseGeometry(ValueGetter data) {
|
||||
byte endian = data.getByte(); // skip and test endian flag
|
||||
if (endian != data.endian) {
|
||||
throw new IllegalArgumentException("Endian inconsistency!");
|
||||
@ -255,7 +271,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
boolean haveS = (typeword & 0x20000000) != 0;
|
||||
|
||||
// int srid = Geometry.UNKNOWN_SRID;
|
||||
|
||||
boolean polygon = false;
|
||||
if (haveS) {
|
||||
// srid = Geometry.parseSRID(data.getInt());
|
||||
data.getInt();
|
||||
@ -269,6 +285,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
case Geometry.POLYGON:
|
||||
parsePolygon(data, haveZ, haveM);
|
||||
polygon = true;
|
||||
break;
|
||||
case Geometry.MULTIPOINT:
|
||||
parseMultiPoint(data);
|
||||
@ -278,6 +295,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
break;
|
||||
case Geometry.MULTIPOLYGON:
|
||||
parseMultiPolygon(data);
|
||||
polygon = true;
|
||||
break;
|
||||
case Geometry.GEOMETRYCOLLECTION:
|
||||
parseCollection(data);
|
||||
@ -288,14 +306,16 @@ public class MapDatabase implements IMapDatabase {
|
||||
// if (srid != Geometry.UNKNOWN_SRID) {
|
||||
// result.setSrid(srid);
|
||||
// }
|
||||
return polygon;
|
||||
}
|
||||
|
||||
private static void parsePoint(ValueGetter data, boolean haveZ, boolean haveM) {
|
||||
private void parsePoint(ValueGetter data, boolean haveZ, boolean haveM) {
|
||||
// double X = data.getDouble();
|
||||
// double Y = data.getDouble();
|
||||
data.getDouble();
|
||||
data.getDouble();
|
||||
|
||||
mCoords[0] = (float) (data.getDouble() * mScale);
|
||||
mCoords[1] = (float) (data.getDouble() * mScale);
|
||||
mIndex[0] = 2;
|
||||
mIndexPos = 1;
|
||||
if (haveZ)
|
||||
data.getDouble();
|
||||
|
||||
@ -341,7 +361,7 @@ public class MapDatabase implements IMapDatabase {
|
||||
if (haveM)
|
||||
data.getDouble();
|
||||
}
|
||||
mIndex[mIndexPos++] = count * 2;
|
||||
mIndex[mIndexPos++] = (short) (count * 2);
|
||||
}
|
||||
|
||||
private void parsePolygon(ValueGetter data, boolean haveZ, boolean haveM) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user