started work on labeling
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user