switch to ShortBuffer for half-float, shader tweaks,..
This commit is contained in:
parent
5da8c6ed0d
commit
f977fec1ae
@ -125,7 +125,8 @@ public class MapView extends GLSurfaceView {
|
||||
super(context, attributeSet);
|
||||
|
||||
if (!(context instanceof MapActivity)) {
|
||||
throw new IllegalArgumentException("context is not an instance of MapActivity");
|
||||
throw new IllegalArgumentException(
|
||||
"context is not an instance of MapActivity");
|
||||
}
|
||||
setWillNotDraw(true);
|
||||
setWillNotCacheDrawing(true);
|
||||
@ -138,7 +139,8 @@ public class MapView extends GLSurfaceView {
|
||||
mMapController = new MapController(this);
|
||||
|
||||
// mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.POSTGIS_READER);
|
||||
mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.MAP_READER);
|
||||
mMapDatabase = MapDatabaseFactory
|
||||
.createMapDatabase(MapDatabaseInternal.MAP_READER);
|
||||
|
||||
mMapViewPosition = new MapViewPosition(this);
|
||||
mMapScaleBar = new MapScaleBar(this);
|
||||
@ -327,7 +329,8 @@ public class MapView extends GLSurfaceView {
|
||||
* the new center point of the map.
|
||||
*/
|
||||
public void setCenter(GeoPoint geoPoint) {
|
||||
MapPosition mapPosition = new MapPosition(geoPoint, mMapViewPosition.getZoomLevel(), 1);
|
||||
MapPosition mapPosition = new MapPosition(geoPoint,
|
||||
mMapViewPosition.getZoomLevel(), 1);
|
||||
setCenterAndZoom(mapPosition);
|
||||
}
|
||||
|
||||
@ -566,16 +569,22 @@ public class MapView extends GLSurfaceView {
|
||||
protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// find out how big the zoom controls should be
|
||||
mMapZoomControls.measure(
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST),
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST));
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec),
|
||||
MeasureSpec.AT_MOST),
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
|
||||
MeasureSpec.AT_MOST));
|
||||
|
||||
// make sure that MapView is big enough to display the zoom controls
|
||||
setMeasuredDimension(Math.max(MeasureSpec.getSize(widthMeasureSpec), mMapZoomControls.getMeasuredWidth()),
|
||||
Math.max(MeasureSpec.getSize(heightMeasureSpec), mMapZoomControls.getMeasuredHeight()));
|
||||
setMeasuredDimension(
|
||||
Math.max(MeasureSpec.getSize(widthMeasureSpec),
|
||||
mMapZoomControls.getMeasuredWidth()),
|
||||
Math.max(MeasureSpec.getSize(heightMeasureSpec),
|
||||
mMapZoomControls.getMeasuredHeight()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
|
||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
||||
int oldHeight) {
|
||||
mMapWorker.pause();
|
||||
mMapWorker.awaitPausing();
|
||||
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
||||
@ -605,7 +614,8 @@ public class MapView extends GLSurfaceView {
|
||||
* @return the maximum possible zoom level.
|
||||
*/
|
||||
byte getMaximumPossibleZoomLevel() {
|
||||
return (byte) Math.min(mMapZoomControls.getZoomLevelMax(), mMapGenerator.getZoomLevelMax());
|
||||
return (byte) Math.min(mMapZoomControls.getZoomLevelMax(),
|
||||
mMapGenerator.getZoomLevelMax());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -615,8 +625,9 @@ public class MapView extends GLSurfaceView {
|
||||
if (!mMapViewPosition.isValid()) {
|
||||
return false;
|
||||
} else if (!mMapGenerator.requiresInternetConnection()
|
||||
&& (!mMapDatabase.hasOpenFile() || !mMapDatabase.getMapFileInfo().boundingBox.contains(getMapPosition()
|
||||
.getMapCenter()))) {
|
||||
&& (!mMapDatabase.hasOpenFile() || !mMapDatabase.getMapFileInfo().boundingBox
|
||||
.contains(getMapPosition()
|
||||
.getMapCenter()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -624,7 +635,8 @@ public class MapView extends GLSurfaceView {
|
||||
}
|
||||
|
||||
byte limitZoomLevel(byte zoom) {
|
||||
return (byte) Math.max(Math.min(zoom, getMaximumPossibleZoomLevel()), mMapZoomControls.getZoomLevelMin());
|
||||
return (byte) Math.max(Math.min(zoom, getMaximumPossibleZoomLevel()),
|
||||
mMapZoomControls.getZoomLevelMin());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -222,11 +222,13 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
|
||||
mWays = wayLength;
|
||||
|
||||
if (!firstMatch && prevClosed == closed && !changed) {
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags, mCurrentTile.zoomLevel,
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0),
|
||||
closed, false);
|
||||
} else {
|
||||
prevClosed = closed;
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags, mCurrentTile.zoomLevel,
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0),
|
||||
closed, true);
|
||||
}
|
||||
|
||||
@ -268,6 +270,9 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
|
||||
@Override
|
||||
public void renderWay(Line line) {
|
||||
|
||||
// if (prevClosed && !mProjected)
|
||||
// return;
|
||||
|
||||
projectToTile(false);
|
||||
|
||||
LineLayer outlineLayer = null;
|
||||
@ -304,7 +309,7 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
|
||||
if (!mDebugDrawPolygons)
|
||||
return;
|
||||
|
||||
// if (!projectToTile(mCurrentTile.zoomLevel < 13))
|
||||
// if (!projectToTile(mCurrentTile.zoomLevel < 14))
|
||||
if (!projectToTile(false))
|
||||
return;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ package org.mapsforge.android.glrenderer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
@ -56,7 +57,8 @@ class LineLayers {
|
||||
}
|
||||
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder());
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
|
||||
ByteOrder.nativeOrder());
|
||||
fbuf = bbuf.asFloatBuffer();
|
||||
} else {
|
||||
fbuf.position(0);
|
||||
@ -87,8 +89,8 @@ class LineLayers {
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
ByteBuffer compileLayerData(ByteBuffer buf) {
|
||||
ByteBuffer sbuf = buf;
|
||||
ShortBuffer compileLayerData(ShortBuffer buf) {
|
||||
ShortBuffer sbuf = buf;
|
||||
|
||||
array = new LineLayer[layers.size()];
|
||||
|
||||
@ -98,14 +100,16 @@ class LineLayers {
|
||||
size += l.verticesCnt * NUM_VERTEX_FLOATS;
|
||||
}
|
||||
|
||||
if (buf == null || buf.capacity() < size * 2) {
|
||||
sbuf = ByteBuffer.allocateDirect(size * 2).order(ByteOrder.nativeOrder());
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 2).order(
|
||||
ByteOrder.nativeOrder());
|
||||
sbuf = bbuf.asShortBuffer();
|
||||
} else {
|
||||
sbuf.position(0);
|
||||
}
|
||||
int pos = 0;
|
||||
|
||||
byte[] data = new byte[PoolItem.SIZE * 2];
|
||||
short[] data = new short[PoolItem.SIZE];
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
LineLayer l = array[i];
|
||||
@ -115,7 +119,7 @@ class LineLayers {
|
||||
for (int k = 0, m = l.pool.size(); k < m; k++) {
|
||||
PoolItem item = l.pool.get(k);
|
||||
PoolItem.toHalfFloat(item, data);
|
||||
sbuf.put(data, 0, item.used * 2);
|
||||
sbuf.put(data, 0, item.used);
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -88,7 +88,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
private long mTileX, mTileY;
|
||||
|
||||
private FloatBuffer floatBuffer = null;
|
||||
private ByteBuffer byteBuffer = null;
|
||||
// private ByteBuffer byteBuffer = null;
|
||||
private ShortBuffer shortBuffer = null;
|
||||
|
||||
boolean useHalfFloat = false;
|
||||
|
||||
@ -125,7 +126,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
private int gLineTexturePositionHandle;
|
||||
private int gLineColorHandle;
|
||||
private int gLineMatrixHandle;
|
||||
private int gLineWidthHandle;
|
||||
private int gLineModeHandle;
|
||||
|
||||
private int gPolygonProgram;
|
||||
@ -325,7 +325,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
newTiles.tiles[tiles++] = tile;
|
||||
|
||||
if (!tile.isDrawn && !tile.isLoading) {
|
||||
MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator, mJobParameter, mDebugSettings);
|
||||
MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator,
|
||||
mJobParameter, mDebugSettings);
|
||||
mJobList.add(job);
|
||||
}
|
||||
}
|
||||
@ -395,8 +396,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
byte zoomLevel = mMapPosition.zoomLevel;
|
||||
float scale = mMapPosition.scale;
|
||||
|
||||
double x = MercatorProjection.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(), zoomLevel);
|
||||
double y = MercatorProjection.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), zoomLevel);
|
||||
double x = MercatorProjection.longitudeToPixelX(
|
||||
mMapPosition.geoPoint.getLongitude(), zoomLevel);
|
||||
double y = MercatorProjection.latitudeToPixelY(
|
||||
mMapPosition.geoPoint.getLatitude(), zoomLevel);
|
||||
|
||||
long tileX = MercatorProjection.pixelXToTileX(x, zoomLevel);
|
||||
long tileY = MercatorProjection.pixelYToTileY(y, zoomLevel);
|
||||
@ -459,8 +462,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
blend = false;
|
||||
}
|
||||
|
||||
GLES20.glUniform4f(gPolygonColorHandle, (color >> 16 & 0xff) / 255f * alpha, (color >> 8 & 0xff) / 255f
|
||||
* alpha, (color & 0xff) / 255f * alpha, alpha);
|
||||
GLES20.glUniform4f(gPolygonColorHandle,
|
||||
(color >> 16 & 0xff) / 255f * alpha,
|
||||
(color >> 8 & 0xff) / 255f * alpha,
|
||||
(color & 0xff) / 255f * alpha, alpha);
|
||||
|
||||
// set stencil buffer mask used to draw this layer
|
||||
GLES20.glStencilFunc(GLES20.GL_EQUAL, 0xff, 1 << c);
|
||||
@ -486,10 +491,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||
|
||||
if (useHalfFloat) {
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2, OES_HALF_FLOAT, false, 0,
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
OES_HALF_FLOAT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
} else {
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2, GLES20.GL_FLOAT, false, 0,
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
GLES20.GL_FLOAT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
}
|
||||
|
||||
@ -531,11 +538,11 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
else {
|
||||
// clear stencilbuffer
|
||||
GLES20.glStencilMask(0xFF);
|
||||
GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
// GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
// clear stencilbuffer (tile region)
|
||||
// GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
|
||||
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
// stencil op for stencil method polygon drawing
|
||||
@ -554,7 +561,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
|
||||
// modify alpha channel
|
||||
float s = (mDrawScale < 1.3f ? 1.3f : mDrawScale);
|
||||
colors[cnt] = (colors[cnt] & 0xffffff) | (byte) ((s - 1) * 0xff) << 24;
|
||||
colors[cnt] = (colors[cnt] & 0xffffff)
|
||||
| (byte) ((s - 1) * 0xff) << 24;
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,16 +596,20 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.id);
|
||||
|
||||
if (useHalfFloat) {
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT, false, 8,
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
|
||||
false, 8,
|
||||
LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT, false, 8,
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
|
||||
false, 8,
|
||||
LINE_VERTICES_DATA_TEX_OFFSET >> 1);
|
||||
} else {
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, GLES20.GL_FLOAT, false, 16,
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, GLES20.GL_FLOAT,
|
||||
false, 16,
|
||||
LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, GLES20.GL_FLOAT, false, 16,
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, GLES20.GL_FLOAT,
|
||||
false, 16,
|
||||
LINE_VERTICES_DATA_TEX_OFFSET);
|
||||
}
|
||||
|
||||
@ -629,6 +641,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
// 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];
|
||||
|
||||
@ -637,14 +650,16 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
drawOutlines = l.isOutline;
|
||||
drawFixed = l.isFixed;
|
||||
if (drawFixed) {
|
||||
GLES20.glUniform1i(gLineModeHandle, 2);
|
||||
GLES20.glUniform1f(gLineWidthHandle, fdiv);
|
||||
GLES20.glUniform2f(gLineModeHandle, 0.4f, fdiv);
|
||||
// GLES20.glUniform1f(gLineWidthHandle, fdiv);
|
||||
} else if (drawOutlines) {
|
||||
GLES20.glUniform1i(gLineModeHandle, 1);
|
||||
GLES20.glUniform1f(gLineWidthHandle, wdiv);
|
||||
GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
|
||||
// GLES20.glUniform1i(gLineModeHandle, 1);
|
||||
// GLES20.glUniform1f(gLineWidthHandle, wdiv);
|
||||
} else {
|
||||
GLES20.glUniform1i(gLineModeHandle, 0);
|
||||
GLES20.glUniform1f(gLineWidthHandle, wdiv * 0.95f);
|
||||
GLES20.glUniform2f(gLineModeHandle, 0, wdiv * 0.95f);
|
||||
// GLES20.glUniform1i(gLineModeHandle, 0);
|
||||
// GLES20.glUniform1f(gLineWidthHandle, wdiv * 0.95f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -659,7 +674,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
} else {
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
||||
}
|
||||
// cnt += l.verticesCnt;
|
||||
}
|
||||
// GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
|
||||
// float[] c = { 1, 0, 0, 1 };
|
||||
// GLES20.glUniform4fv(gLineColorHandle, 1, c, 0);
|
||||
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, cnt);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -754,7 +774,15 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private int uploadCnt;
|
||||
|
||||
private boolean uploadTileData(GLMapTile tile) {
|
||||
// not sure about this, but seems it fixes some flickering when
|
||||
// multiple tiles are uploaded in one go. but if this is really
|
||||
// the issue tiles should stay corrupted..
|
||||
if (uploadCnt++ > 0)
|
||||
GLES20.glFinish();
|
||||
|
||||
if (tile.lineVBO == null) {
|
||||
// Upload line data to vertex buffer object
|
||||
synchronized (mVBOs) {
|
||||
@ -766,7 +794,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
if (useHalfFloat)
|
||||
byteBuffer = tile.lineLayers.compileLayerData(byteBuffer);
|
||||
shortBuffer = tile.lineLayers.compileLayerData(shortBuffer);
|
||||
else
|
||||
floatBuffer = tile.lineLayers.compileLayerData(floatBuffer);
|
||||
|
||||
@ -778,10 +806,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
|
||||
if (useHalfFloat) {
|
||||
tile.lineVBO.size = tile.lineLayers.size * SHORT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size, byteBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
||||
} else {
|
||||
tile.lineVBO.size = tile.lineLayers.size * FLOAT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size, floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
mBufferMemoryUsage += tile.lineVBO.size;
|
||||
@ -791,7 +821,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
|
||||
if (useHalfFloat)
|
||||
byteBuffer = tile.polygonLayers.compileLayerData(byteBuffer);
|
||||
shortBuffer = tile.polygonLayers.compileLayerData(shortBuffer);
|
||||
else
|
||||
floatBuffer = tile.polygonLayers.compileLayerData(floatBuffer);
|
||||
|
||||
@ -804,10 +834,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
|
||||
if (useHalfFloat) {
|
||||
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size, byteBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
||||
} else {
|
||||
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size, floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
}
|
||||
mBufferMemoryUsage += tile.polygonVBO.size;
|
||||
|
||||
@ -835,7 +867,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glStencilMask(0xFF);
|
||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
GLES20.glFlush();
|
||||
synchronized (this) {
|
||||
mDrawX = mCurX;
|
||||
mDrawY = mCurY;
|
||||
@ -854,14 +886,16 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLMapTile[] tiles = curTiles.tiles;
|
||||
|
||||
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
|
||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / (1024 * 1024) + "MB");
|
||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / (1024 * 1024)
|
||||
+ "MB");
|
||||
synchronized (mVBOs) {
|
||||
for (VertexBufferObject vbo : mVBOs) {
|
||||
if (vbo.size == 0)
|
||||
continue;
|
||||
mBufferMemoryUsage -= vbo.size;
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
|
||||
GLES20.GL_STATIC_DRAW);
|
||||
vbo.size = 0;
|
||||
|
||||
}
|
||||
@ -869,6 +903,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
Log.d(TAG, " > " + mBufferMemoryUsage / (1024 * 1024) + "MB");
|
||||
}
|
||||
|
||||
uploadCnt = 0;
|
||||
|
||||
// check visible tiles, set tile clip scissors, upload new vertex data
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
GLMapTile tile = tiles[i];
|
||||
@ -880,7 +916,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
uploadTileData(tile);
|
||||
|
||||
if (timing)
|
||||
Log.d(TAG, "buffer upload took: " + (SystemClock.uptimeMillis() - start));
|
||||
Log.d(TAG, "buffer upload took: "
|
||||
+ (SystemClock.uptimeMillis() - start));
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -901,6 +938,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
// GLES20.glFinish();
|
||||
|
||||
if (timing)
|
||||
clear_time = (SystemClock.uptimeMillis() - start);
|
||||
@ -930,7 +968,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glFinish();
|
||||
poly_time = (SystemClock.uptimeMillis() - start);
|
||||
}
|
||||
|
||||
// GLES20.glFlush();
|
||||
// Draw lines
|
||||
GLES20.glEnable(GLES20.GL_BLEND);
|
||||
GLES20.glUseProgram(gLineProgram);
|
||||
@ -946,11 +984,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
if (timing) {
|
||||
GLES20.glFinish();
|
||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " " + clear_time + " " + poly_time);
|
||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
|
||||
+ clear_time + " " + poly_time);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1002,10 +1041,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// Set up the program for rendering lines
|
||||
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader, Shaders.gLineFragmentShader);
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
Shaders.gLineFragmentShader);
|
||||
if (gLineProgram == 0) {
|
||||
Log.e(TAG, "trying simple line program.");
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader, Shaders.gLineFragmentShaderSimple);
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
Shaders.gLineFragmentShaderSimple);
|
||||
if (gLineProgram == 0) {
|
||||
Log.e(TAG, "Could not create line program.");
|
||||
return;
|
||||
@ -1020,20 +1061,22 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
Log.d(TAG, "Extensions: " + ext);
|
||||
|
||||
gLineMatrixHandle = GLES20.glGetUniformLocation(gLineProgram, "u_center");
|
||||
gLineWidthHandle = GLES20.glGetUniformLocation(gLineProgram, "u_width");
|
||||
gLineModeHandle = GLES20.glGetUniformLocation(gLineProgram, "u_mode");
|
||||
gLineColorHandle = GLES20.glGetUniformLocation(gLineProgram, "u_color");
|
||||
gLineVertexPositionHandle = GLES20.glGetAttribLocation(gLineProgram, "a_position");
|
||||
gLineVertexPositionHandle = GLES20
|
||||
.glGetAttribLocation(gLineProgram, "a_position");
|
||||
gLineTexturePositionHandle = GLES20.glGetAttribLocation(gLineProgram, "a_st");
|
||||
|
||||
// Set up the program for rendering polygons
|
||||
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader, Shaders.gPolygonFragmentShader);
|
||||
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
|
||||
Shaders.gPolygonFragmentShader);
|
||||
if (gPolygonProgram == 0) {
|
||||
Log.e(TAG, "Could not create polygon program.");
|
||||
return;
|
||||
}
|
||||
gPolygonMatrixHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_center");
|
||||
gPolygonVertexPositionHandle = GLES20.glGetAttribLocation(gPolygonProgram, "a_position");
|
||||
gPolygonVertexPositionHandle = GLES20.glGetAttribLocation(gPolygonProgram,
|
||||
"a_position");
|
||||
gPolygonColorHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_color");
|
||||
|
||||
GLES20.glUseProgram(gPolygonProgram);
|
||||
|
||||
@ -16,11 +16,14 @@ package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
class PolygonLayer extends Layer {
|
||||
int fadeLevel;
|
||||
private boolean first = true;
|
||||
private float originX;
|
||||
private float originY;
|
||||
|
||||
// private boolean first = true;
|
||||
// private float originX;
|
||||
// private float originY;
|
||||
|
||||
PolygonLayer(int layer, int color, int fade) {
|
||||
super(layer, color);
|
||||
@ -34,11 +37,11 @@ class PolygonLayer extends Layer {
|
||||
|
||||
verticesCnt += length / 2 + 2;
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
originX = points[pos];
|
||||
originY = points[pos + 1];
|
||||
}
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// originX = points[pos];
|
||||
// originY = points[pos + 1];
|
||||
// }
|
||||
|
||||
float[] curVertices = curItem.vertices;
|
||||
int outPos = curItem.used;
|
||||
@ -48,8 +51,8 @@ class PolygonLayer extends Layer {
|
||||
outPos = 0;
|
||||
}
|
||||
|
||||
curVertices[outPos++] = originX;
|
||||
curVertices[outPos++] = originY;
|
||||
curVertices[outPos++] = Tile.TILE_SIZE >> 1;
|
||||
curVertices[outPos++] = Tile.TILE_SIZE >> 1;
|
||||
|
||||
int remaining = length;
|
||||
int inPos = pos;
|
||||
@ -74,7 +77,7 @@ class PolygonLayer extends Layer {
|
||||
curVertices = getNextItem();
|
||||
outPos = 0;
|
||||
}
|
||||
|
||||
// Float.intBitsToFloat(bits)
|
||||
curVertices[outPos++] = points[pos + 0];
|
||||
curVertices[outPos++] = points[pos + 1];
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ 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.FastMath;
|
||||
import org.mapsforge.core.Tile;
|
||||
@ -25,10 +26,11 @@ import android.util.SparseArray;
|
||||
|
||||
class PolygonLayers {
|
||||
private static final int NUM_VERTEX_FLOATS = 2;
|
||||
private static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
|
||||
private 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 byte[] mByteFillCoords = null;
|
||||
private static short[] mByteFillCoords = null;
|
||||
|
||||
private SparseArray<PolygonLayer> layers;
|
||||
|
||||
@ -68,7 +70,8 @@ class PolygonLayers {
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder());
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
|
||||
ByteOrder.nativeOrder());
|
||||
// Log.d("GLMap", "allocate buffer " + size);
|
||||
fbuf = bbuf.asFloatBuffer();
|
||||
} else {
|
||||
@ -100,8 +103,8 @@ class PolygonLayers {
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
ByteBuffer compileLayerData(ByteBuffer buf) {
|
||||
ByteBuffer bbuf = buf;
|
||||
ShortBuffer compileLayerData(ShortBuffer buf) {
|
||||
ShortBuffer sbuf = buf;
|
||||
|
||||
array = new PolygonLayer[layers.size()];
|
||||
|
||||
@ -113,27 +116,29 @@ class PolygonLayers {
|
||||
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
if (buf == null || buf.capacity() < size * 2) {
|
||||
bbuf = ByteBuffer.allocateDirect(size * 2).order(ByteOrder.nativeOrder());
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 2).order(
|
||||
ByteOrder.nativeOrder());
|
||||
sbuf = bbuf.asShortBuffer();
|
||||
} else {
|
||||
bbuf.position(0);
|
||||
sbuf.position(0);
|
||||
}
|
||||
|
||||
byte[] data = new byte[PoolItem.SIZE * 2];
|
||||
short[] data = new short[PoolItem.SIZE];
|
||||
|
||||
if (mByteFillCoords == null) {
|
||||
mByteFillCoords = new byte[16];
|
||||
mByteFillCoords = new short[8];
|
||||
FastMath.convertFloatToHalf(mFillCoords[0], mByteFillCoords, 0);
|
||||
FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 2);
|
||||
FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 4);
|
||||
FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 6);
|
||||
FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 8);
|
||||
FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 10);
|
||||
FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 12);
|
||||
FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 14);
|
||||
FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 1);
|
||||
FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 2);
|
||||
FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 3);
|
||||
FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 4);
|
||||
FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 5);
|
||||
FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 6);
|
||||
FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 7);
|
||||
}
|
||||
|
||||
bbuf.put(mByteFillCoords, 0, 16);
|
||||
sbuf.put(mByteFillCoords, 0, 8);
|
||||
int pos = 4;
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
@ -142,7 +147,7 @@ class PolygonLayers {
|
||||
for (int k = 0, m = l.pool.size(); k < m; k++) {
|
||||
PoolItem item = l.pool.get(k);
|
||||
PoolItem.toHalfFloat(item, data);
|
||||
bbuf.put(data, 0, item.used * 2);
|
||||
sbuf.put(data, 0, item.used);
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
@ -152,11 +157,11 @@ class PolygonLayers {
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
bbuf.position(0);
|
||||
sbuf.position(0);
|
||||
|
||||
// not needed for drawing
|
||||
layers = null;
|
||||
|
||||
return bbuf;
|
||||
return sbuf;
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,74 +15,79 @@
|
||||
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
// TODO use byte[] for half-float, not converting on compilation (in glThread)
|
||||
|
||||
class PoolItem {
|
||||
final float[] vertices;
|
||||
// final byte[] vertices;
|
||||
int used;
|
||||
|
||||
PoolItem() {
|
||||
vertices = new float[SIZE];
|
||||
// vertices = new byte[SIZE];
|
||||
used = 0;
|
||||
}
|
||||
|
||||
static int SIZE = 256;
|
||||
|
||||
private static final byte b0x7c = (byte) 0x7c;
|
||||
private static final byte b0x00 = (byte) 0x00;
|
||||
private static final byte b0x01 = (byte) 0x01;
|
||||
private static final byte b0xfc = (byte) 0xfc;
|
||||
private static final byte b0x80 = (byte) 0x80;
|
||||
private static final byte b0x7b = (byte) 0x7b;
|
||||
private static final byte b0xff = (byte) 0xff;
|
||||
private static final byte b0xfb = (byte) 0xfb;
|
||||
private static final float FLOAT_HALF_PREC = 5.96046E-8f;
|
||||
private static final float FLOAT_HALF_MAX = 65504f;
|
||||
|
||||
static void toHalfFloat(PoolItem item, byte[] data) {
|
||||
private static ByteBuffer byteBuffer = ByteBuffer.allocate(SIZE * 4);
|
||||
private static IntBuffer intBuffer = byteBuffer.asIntBuffer();
|
||||
private static FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
|
||||
private static int[] intArray = new int[SIZE];
|
||||
|
||||
static void toHalfFloat(PoolItem item, short[] data) {
|
||||
floatBuffer.position(0);
|
||||
floatBuffer.put(item.vertices, 0, item.used);
|
||||
intBuffer.position(0);
|
||||
intBuffer.get(intArray, 0, item.used);
|
||||
|
||||
int out = 0;
|
||||
for (int j = 0; j < item.used; j++) {
|
||||
float flt = item.vertices[j];
|
||||
int f = intArray[j];
|
||||
|
||||
if (flt == 0f) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0x00;
|
||||
} else if (flt == -0f) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0x80;
|
||||
if (f == 0x0000000) {
|
||||
// == 0
|
||||
data[out++] = (short) 0x0000;
|
||||
} else if (f == 0x80000000) {
|
||||
// == -0
|
||||
data[out++] = (short) 0x8000;
|
||||
} else if (f == 0x3f800000) {
|
||||
// == 1
|
||||
data[out++] = (short) 0x3c00;
|
||||
} else if (f == 0xbf800000) {
|
||||
// == -1
|
||||
data[out++] = (short) 0xbc00;
|
||||
} else if (flt > FLOAT_HALF_MAX) {
|
||||
if (flt == Float.POSITIVE_INFINITY) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0x7c;
|
||||
data[out++] = (short) 0x7c00;
|
||||
} else {
|
||||
data[out++] = b0xff;
|
||||
data[out++] = b0x7b;
|
||||
data[out++] = (short) 0x7bff;
|
||||
}
|
||||
} else if (flt < -FLOAT_HALF_MAX) {
|
||||
if (flt == Float.NEGATIVE_INFINITY) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0xfc;
|
||||
data[out++] = (short) 0xfc00;
|
||||
} else {
|
||||
data[out++] = b0xff;
|
||||
data[out++] = b0xfb;
|
||||
data[out++] = (short) 0xfbff;
|
||||
}
|
||||
} else if (flt > 0f && flt < FLOAT_HALF_PREC) {
|
||||
data[out++] = b0x01;
|
||||
data[out++] = b0x00;
|
||||
data[out++] = (short) 0x0001;
|
||||
} else if (flt < 0f && flt > -FLOAT_HALF_PREC) {
|
||||
data[out++] = b0x01;
|
||||
data[out++] = b0x80;
|
||||
data[out++] = (short) 0x8001;
|
||||
} else {
|
||||
int f = Float.floatToIntBits(flt);
|
||||
|
||||
// maybe just ignore and set 0? -- we'll see. when this happens
|
||||
if (f == 0x7fc00000)
|
||||
throw new UnsupportedOperationException("NaN to half conversion not supported!");
|
||||
throw new UnsupportedOperationException(
|
||||
"NaN to half conversion not supported!");
|
||||
|
||||
data[out++] = (byte) ((f >> 13) & 0xff);
|
||||
|
||||
data[out++] = (byte) (((f >> 24) & 0x80) | ((((f & 0x7f800000) - 0x38000000) >> 21) & 0x7c) | ((f >> 21) & 0x03));
|
||||
data[out++] = (short) (((f >> 16) & 0x8000)
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
||||
| ((f >> 13) & 0x03ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,60 +17,78 @@ package org.mapsforge.android.glrenderer;
|
||||
|
||||
class Shaders {
|
||||
final static String gLineVertexShader = ""
|
||||
+ "precision highp float; \n"
|
||||
+ "precision mediump float; \n"
|
||||
+ "uniform mat4 u_center;"
|
||||
+ "uniform float u_width;"
|
||||
// + "uniform float u_width;"
|
||||
+ "attribute vec4 a_position;"
|
||||
+ "attribute vec2 a_st;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_center * a_position;"
|
||||
+ " v_st = a_st;" + "}";
|
||||
+ " v_st = a_st;"
|
||||
+ "}";
|
||||
|
||||
final static String gLineFragmentShader = ""
|
||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||
+ "precision mediump float;"
|
||||
+ "uniform float u_width;"
|
||||
+ "uniform int u_mode;"
|
||||
+ "uniform vec2 u_mode;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "const float zero = 0.0;"
|
||||
+ "const int standard = 0;"
|
||||
+ "const int fixed_width = 2;"
|
||||
+ "const vec4 blank = vec4(1.0, 0.0, 0.0, 1.0);"
|
||||
+ "const vec4 blank2 = vec4(0.0, 1.0, 0.0, 1.0);"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " if (u_mode != fixed_width) {"
|
||||
// + " gl_FragColor = u_color;"
|
||||
// + " float fuzz;"
|
||||
// + " float len;"
|
||||
+ " if (v_st.t == zero){ "
|
||||
// + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s));"
|
||||
+ " float fuzz = -fwidth(v_st.s) * 1.5;"
|
||||
+ " float len = abs(v_st.s) - u_width;"
|
||||
// + " if (len < fuzz)"
|
||||
+ " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
+ " } else {"
|
||||
+ " float fuzz = -max(fwidth(v_st.s), fwidth(v_st.t)) * 1.5;"
|
||||
+ " float len = length(v_st) - u_width;"
|
||||
// + " if (len < fuzz)"
|
||||
+ " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
+ " } "
|
||||
// + " if (len > zero)"
|
||||
// + " gl_FragColor = blank;"
|
||||
// + " discard;"
|
||||
// + " gl_FragColor = u_color;"
|
||||
// + " else if (len < fuzz)"
|
||||
// + " gl_FragColor = blank2;"
|
||||
// + " else "
|
||||
+ " } else { "
|
||||
+ " float fuzz = fwidth(v_st.s);"
|
||||
// + " gl_FragColor = u_color * smoothstep(fuzz, zero, abs(v_st.s) - u_width + fuzz);"
|
||||
// + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s)) * 1.5;"
|
||||
+ " gl_FragColor = u_color * smoothstep(fuzz*0.5, -fuzz, abs(v_st.s) - u_width);"
|
||||
+ " }"
|
||||
+ "float width = u_mode[1];"
|
||||
// + " if (v_st.t == zero){ "
|
||||
// + " float fuzz = fwidth(v_st.s) * 1.5;"
|
||||
// + " gl_FragColor = u_color * smoothstep(-fuzz * u_mode[0], fuzz, width - abs(v_st.s));"
|
||||
// + " } else {"
|
||||
+ " float fuzz = max(fwidth(v_st.s), fwidth(v_st.t)) * 1.5;"
|
||||
+ " gl_FragColor = u_color * smoothstep(-fuzz * u_mode[0], fuzz, width - length(v_st));"
|
||||
// + " } "
|
||||
+ "}";
|
||||
|
||||
// final static String gLineFragmentShader = ""
|
||||
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||
// + "precision mediump float;"
|
||||
// + "uniform float u_width;"
|
||||
// + "uniform vec2 u_mode;"
|
||||
// + "uniform vec4 u_color;"
|
||||
// + "const float zero = 0.0;"
|
||||
// // + "const vec4 blank = vec4(1.0, 0.0, 0.0, 1.0);"
|
||||
// + "varying vec2 v_st;"
|
||||
// + "void main() {"
|
||||
// + "float width = u_mode[1];"
|
||||
// // + "float alpha = 1.0;"
|
||||
// + " if (u_mode[0] == zero) {"
|
||||
// // + " gl_FragColor = u_color;"
|
||||
// // + " float fuzz;"
|
||||
// // + " float len;"
|
||||
// + " if (v_st.t == zero){ "
|
||||
// // + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s));"
|
||||
// + " float fuzz = -fwidth(v_st.s) * 1.5;"
|
||||
// + " float len = abs(v_st.s) - width;"
|
||||
// // + " if (len < fuzz)"
|
||||
// + " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
// + " } else {"
|
||||
// + " float fuzz = -max(fwidth(v_st.s), fwidth(v_st.t)) * 1.5;"
|
||||
// + " float len = length(v_st) - width;"
|
||||
// // + " if (len < fuzz)"
|
||||
// + " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
// + " } "
|
||||
// // + " if (len > zero)"
|
||||
// // + " gl_FragColor = blank;"
|
||||
// // + " discard;"
|
||||
// // + " gl_FragColor = u_color;"
|
||||
// // + " else if (len < fuzz)"
|
||||
// // + " gl_FragColor = blank2;"
|
||||
// // + " else "
|
||||
// + " } else { "
|
||||
// + " float fuzz = fwidth(v_st.s);"
|
||||
// // + " gl_FragColor = u_color * smoothstep(fuzz, zero, abs(v_st.s) - u_width + fuzz);"
|
||||
// // + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s)) * 1.5;"
|
||||
// + " gl_FragColor = u_color * smoothstep(fuzz*0.5, -fuzz, abs(v_st.s) - width);"
|
||||
// + " }"
|
||||
// + "}";
|
||||
|
||||
// final static String gLineFragmentShader = "" +
|
||||
// "#extension GL_OES_standard_derivatives : enable\n" +
|
||||
// "precision mediump float;" +
|
||||
|
||||
@ -208,7 +208,7 @@
|
||||
<rule e="way" k="waterway" v="*">
|
||||
|
||||
<rule e="way" k="waterway" v="ditch|drain" zoom-min="14">
|
||||
<line stroke="#b4cbdc" stroke-width="0.5" stroke-linecap="butt"
|
||||
<line stroke="#b4cbdc" stroke-width="0.7" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
</rule>
|
||||
|
||||
@ -332,7 +332,7 @@
|
||||
|
||||
<rule e="way" k="outline" v="*">
|
||||
<rule e="way" k="*" v="1">
|
||||
<outline stroke="#909090" />
|
||||
<outline stroke="#bb909090" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="2">
|
||||
<outline stroke="#c0c0c0" />
|
||||
@ -401,14 +401,10 @@
|
||||
<line stroke="#d3cb98" stroke-width="0.4" outline="2" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="service|byway">
|
||||
<rule e="way" k="*" v="service|byway|pedestrian">
|
||||
<line stroke="#ffffff" stroke-width="0.8" outline="1" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="pedestrian">
|
||||
<line stroke="#f1f0f4" stroke-width="0.8" outline="1" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="construction">
|
||||
<line stroke="#d0d0d0" stroke-width="1.3" outline="1" />
|
||||
</rule>
|
||||
@ -418,9 +414,7 @@
|
||||
|
||||
<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" stroke-linecap="butt"
|
||||
outline="2" />
|
||||
|
||||
<line stroke="#ffffff" stroke-width="1.3" outline="2" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="bridge" v="~|no|false">
|
||||
<line stroke="#ffffff" stroke-width="1.3" outline="1" />
|
||||
@ -434,19 +428,17 @@
|
||||
<rule e="way" k="*" v="*" zoom-min="11">
|
||||
|
||||
<rule e="way" k="*" v="tertiary|secondary_link">
|
||||
<line stroke="#ffff9a" stroke-width="1.5" outline="3" />
|
||||
<line stroke="#ffffff" stroke-width="1.5" outline="1" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="trunk_link|motorway_link">
|
||||
<line stroke="#fed6a3" stroke-width="1.6" stroke-linecap="butt"
|
||||
outline="4" />
|
||||
<line stroke="#fed6a3" stroke-width="1.5" outline="4" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="secondary|primary_link">
|
||||
|
||||
<rule e="way" k="bridge" v="yes|true">
|
||||
<line stroke="#fefe8a" stroke-width="1.6" outline="1"
|
||||
stroke-linecap="butt" />
|
||||
<line stroke="#fefe8a" stroke-width="1.6" outline="1" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="bridge" v="~|no|false">
|
||||
@ -455,18 +447,15 @@
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="primary">
|
||||
<line stroke="#fefe8a" stroke-width="1.7" stroke-linecap="butt"
|
||||
outline="3" />
|
||||
<line stroke="#fefe8a" stroke-width="1.7" outline="3" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="trunk">
|
||||
<line stroke="#fed6a3" stroke-width="1.8" stroke-linecap="butt"
|
||||
outline="4" />
|
||||
<line stroke="#fed6a3" stroke-width="1.8" outline="4" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="motorway">
|
||||
<line stroke="#eec693" stroke-width="1.9" stroke-linecap="butt"
|
||||
outline="4" />
|
||||
<line stroke="#eec693" stroke-width="1.9" outline="4" stroke-linecap="butt" />
|
||||
</rule>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
package org.mapsforge.android.utils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||
* All rights reserved. FastMath.java
|
||||
* Copyright (c) 2009-2010 jMonkeyEngine All rights reserved. FastMath.java
|
||||
*/
|
||||
public class FastMath {
|
||||
|
||||
@ -58,7 +57,8 @@ public class FastMath {
|
||||
int f = Float.floatToIntBits(flt);
|
||||
|
||||
if (f == 0x7fc00000)
|
||||
throw new UnsupportedOperationException("NaN to half conversion not supported!");
|
||||
throw new UnsupportedOperationException(
|
||||
"NaN to half conversion not supported!");
|
||||
|
||||
data[pos + 1] = (byte) (((f >> 24) & 0x80)
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 21) & 0x7c)
|
||||
@ -67,4 +67,50 @@ public class FastMath {
|
||||
data[pos + 0] = (byte) ((f >> 13) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param flt
|
||||
* ...
|
||||
* @param data
|
||||
* ...
|
||||
* @param pos
|
||||
* ..
|
||||
*/
|
||||
public static void convertFloatToHalf(float flt, short[] data, int pos) {
|
||||
if (flt == 0f) {
|
||||
data[pos] = (short) 0x0000;
|
||||
} else if (flt == -0f) {
|
||||
data[pos] = (short) 0x8000;
|
||||
} else if (flt == 1f) {
|
||||
data[pos] = (short) 0x3c00;
|
||||
} else if (flt == -1f) {
|
||||
data[pos] = (short) 0xbc00;
|
||||
} else if (flt > FLOAT_HALF_MAX) {
|
||||
if (flt == Float.POSITIVE_INFINITY) {
|
||||
data[pos] = (short) 0x7c00;
|
||||
} else {
|
||||
data[pos] = (short) 0x7bff;
|
||||
}
|
||||
} else if (flt < -FLOAT_HALF_MAX) {
|
||||
if (flt == Float.NEGATIVE_INFINITY) {
|
||||
data[pos] = (short) 0xfc00;
|
||||
} else {
|
||||
data[pos] = (short) 0xfbff;
|
||||
}
|
||||
} else if (flt > 0f && flt < FLOAT_HALF_PREC) {
|
||||
data[pos] = (short) 0x0001;
|
||||
} else if (flt < 0f && flt > -FLOAT_HALF_PREC) {
|
||||
data[pos] = (short) 0x8001;
|
||||
} else {
|
||||
int f = Float.floatToIntBits(flt);
|
||||
|
||||
if (f == 0x7fc00000)
|
||||
throw new UnsupportedOperationException(
|
||||
"NaN to half conversion not supported!");
|
||||
|
||||
data[pos] = (short) (((f >> 16) & 0x8000)
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
||||
| ((f >> 13) & 0x03ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
*/
|
||||
package org.mapsforge.core;
|
||||
|
||||
|
||||
/**
|
||||
* A tile represents a rectangular part of the world map. All tiles can be identified by their X and Y number together
|
||||
* with their zoom level. The actual area that a tile covers on a map depends on the underlying map projection.
|
||||
@ -33,7 +32,8 @@ public class Tile {
|
||||
/**
|
||||
* Size of a single uncompressed map tile bitmap in bytes.
|
||||
*/
|
||||
public static final int TILE_SIZE_IN_BYTES = TILE_SIZE * TILE_SIZE * TILE_BYTES_PER_PIXEL;
|
||||
public static final int TILE_SIZE_IN_BYTES = TILE_SIZE * TILE_SIZE
|
||||
* TILE_BYTES_PER_PIXEL;
|
||||
|
||||
/**
|
||||
* The X number of this tile.
|
||||
|
||||
@ -254,11 +254,14 @@ public class MapDatabase implements IMapDatabase {
|
||||
try {
|
||||
prepareExecution();
|
||||
QueryParameters queryParameters = new QueryParameters();
|
||||
queryParameters.queryZoomLevel = mMapFileHeader.getQueryZoomLevel(tile.zoomLevel);
|
||||
queryParameters.queryZoomLevel = mMapFileHeader
|
||||
.getQueryZoomLevel(tile.zoomLevel);
|
||||
// get and check the sub-file for the query zoom level
|
||||
SubFileParameter subFileParameter = mMapFileHeader.getSubFileParameter(queryParameters.queryZoomLevel);
|
||||
SubFileParameter subFileParameter = mMapFileHeader
|
||||
.getSubFileParameter(queryParameters.queryZoomLevel);
|
||||
if (subFileParameter == null) {
|
||||
LOG.warning("no sub-file for zoom level: " + queryParameters.queryZoomLevel);
|
||||
LOG.warning("no sub-file for zoom level: "
|
||||
+ queryParameters.queryZoomLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -320,7 +323,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
mReadBuffer = new ReadBuffer(mInputFile);
|
||||
|
||||
mMapFileHeader = new MapFileHeader();
|
||||
FileOpenResult fileOpenResult = mMapFileHeader.readHeader(mReadBuffer, mFileSize);
|
||||
FileOpenResult fileOpenResult = mMapFileHeader.readHeader(mReadBuffer,
|
||||
mFileSize);
|
||||
if (!fileOpenResult.isSuccess()) {
|
||||
closeFile();
|
||||
return fileOpenResult;
|
||||
@ -361,7 +365,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
* @param mapDatabaseCallback
|
||||
* the callback which handles the extracted map elements.
|
||||
*/
|
||||
private void processBlock(QueryParameters queryParameters, SubFileParameter subFileParameter,
|
||||
private void processBlock(QueryParameters queryParameters,
|
||||
SubFileParameter subFileParameter,
|
||||
IMapDatabaseCallback mapDatabaseCallback) {
|
||||
if (!processBlockSignature()) {
|
||||
return;
|
||||
@ -416,7 +421,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
}
|
||||
|
||||
private void processBlocks(IMapDatabaseCallback mapDatabaseCallback, QueryParameters queryParameters,
|
||||
private void processBlocks(IMapDatabaseCallback mapDatabaseCallback,
|
||||
QueryParameters queryParameters,
|
||||
SubFileParameter subFileParameter) throws IOException {
|
||||
boolean queryIsWater = true;
|
||||
// boolean queryReadWaterInfo = false;
|
||||
@ -429,7 +435,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
long blockNumber = row * subFileParameter.blocksWidth + column;
|
||||
|
||||
// get the current index entry
|
||||
long currentBlockIndexEntry = mDatabaseIndexCache.getIndexEntry(subFileParameter, blockNumber);
|
||||
long currentBlockIndexEntry = mDatabaseIndexCache.getIndexEntry(
|
||||
subFileParameter, blockNumber);
|
||||
|
||||
// check if the current query would still return a water tile
|
||||
if (queryIsWater) {
|
||||
@ -440,7 +447,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
|
||||
// get and check the current block pointer
|
||||
long currentBlockPointer = currentBlockIndexEntry & BITMASK_INDEX_OFFSET;
|
||||
if (currentBlockPointer < 1 || currentBlockPointer > subFileParameter.subFileSize) {
|
||||
if (currentBlockPointer < 1
|
||||
|| currentBlockPointer > subFileParameter.subFileSize) {
|
||||
LOG.warning("invalid current block pointer: " + currentBlockPointer);
|
||||
LOG.warning("subFileSize: " + subFileParameter.subFileSize);
|
||||
return;
|
||||
@ -453,9 +461,11 @@ public class MapDatabase implements IMapDatabase {
|
||||
nextBlockPointer = subFileParameter.subFileSize;
|
||||
} else {
|
||||
// get and check the next block pointer
|
||||
nextBlockPointer = mDatabaseIndexCache.getIndexEntry(subFileParameter, blockNumber + 1)
|
||||
nextBlockPointer = mDatabaseIndexCache.getIndexEntry(
|
||||
subFileParameter, blockNumber + 1)
|
||||
& BITMASK_INDEX_OFFSET;
|
||||
if (nextBlockPointer < 1 || nextBlockPointer > subFileParameter.subFileSize) {
|
||||
if (nextBlockPointer < 1
|
||||
|| nextBlockPointer > subFileParameter.subFileSize) {
|
||||
LOG.warning("invalid next block pointer: " + nextBlockPointer);
|
||||
LOG.warning("sub-file size: " + subFileParameter.subFileSize);
|
||||
return;
|
||||
@ -465,7 +475,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
// calculate the size of the current block
|
||||
int currentBlockSize = (int) (nextBlockPointer - currentBlockPointer);
|
||||
if (currentBlockSize < 0) {
|
||||
LOG.warning("current block size must not be negative: " + currentBlockSize);
|
||||
LOG.warning("current block size must not be negative: "
|
||||
+ currentBlockSize);
|
||||
return;
|
||||
} else if (currentBlockSize == 0) {
|
||||
// the current block is empty, continue with the next block
|
||||
@ -475,7 +486,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
LOG.warning("current block size too large: " + currentBlockSize);
|
||||
continue;
|
||||
} else if (currentBlockPointer + currentBlockSize > mFileSize) {
|
||||
LOG.warning("current block largher than file size: " + currentBlockSize);
|
||||
LOG.warning("current block largher than file size: "
|
||||
+ currentBlockSize);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -490,10 +502,12 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
|
||||
// calculate the top-left coordinates of the underlying tile
|
||||
double tileLatitudeDeg = MercatorProjection.tileYToLatitude(subFileParameter.boundaryTileTop + row,
|
||||
double tileLatitudeDeg = MercatorProjection.tileYToLatitude(
|
||||
subFileParameter.boundaryTileTop + row,
|
||||
subFileParameter.baseZoomLevel);
|
||||
double tileLongitudeDeg = MercatorProjection.tileXToLongitude(subFileParameter.boundaryTileLeft
|
||||
+ column, subFileParameter.baseZoomLevel);
|
||||
double tileLongitudeDeg = MercatorProjection.tileXToLongitude(
|
||||
subFileParameter.boundaryTileLeft
|
||||
+ column, subFileParameter.baseZoomLevel);
|
||||
mTileLatitude = (int) (tileLatitudeDeg * 1000000);
|
||||
mTileLongitude = (int) (tileLongitudeDeg * 1000000);
|
||||
|
||||
@ -544,7 +558,6 @@ public class MapDatabase implements IMapDatabase {
|
||||
* @return true if the POIs could be processed successfully, false otherwise.
|
||||
*/
|
||||
private boolean processPOIs(IMapDatabaseCallback mapDatabaseCallback, int numberOfPois) {
|
||||
// List<Tag> tags = new ArrayList<Tag>();
|
||||
Tag[] poiTags = mMapFileHeader.getMapFileInfo().poiTags;
|
||||
Tag[] tags = null;
|
||||
|
||||
@ -586,22 +599,19 @@ public class MapDatabase implements IMapDatabase {
|
||||
byte featureByte = mReadBuffer.readByte();
|
||||
|
||||
// bit 1-3 enable optional features
|
||||
boolean featureName = (featureByte & POI_FEATURE_NAME) != 0;
|
||||
boolean featureHouseNumber = (featureByte & POI_FEATURE_HOUSE_NUMBER) != 0;
|
||||
boolean featureElevation = (featureByte & POI_FEATURE_ELEVATION) != 0;
|
||||
|
||||
// check if the POI has a name
|
||||
if (featureName) {
|
||||
if ((featureByte & POI_FEATURE_NAME) != 0) {
|
||||
mReadBuffer.getPositionAndSkip();
|
||||
}
|
||||
|
||||
// check if the POI has a house number
|
||||
if (featureHouseNumber) {
|
||||
if ((featureByte & POI_FEATURE_HOUSE_NUMBER) != 0) {
|
||||
mReadBuffer.getPositionAndSkip();
|
||||
}
|
||||
|
||||
// check if the POI has an elevation
|
||||
if (featureElevation) {
|
||||
if ((featureByte & POI_FEATURE_ELEVATION) != 0) {
|
||||
mReadBuffer.readSignedInt();
|
||||
// mReadBuffer.getPositionAndSkip();// tags.add(new Tag(Tag.TAG_KEY_ELE,
|
||||
// Integer.toString(mReadBuffer.readSignedInt())));
|
||||
@ -686,7 +696,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
dLon = nLon - wayNodeLongitude;
|
||||
wayNodeLongitude = nLon;
|
||||
|
||||
if (dLon > minLon || dLon < -minLon || dLat > minLat || dLat < -minLat || (pos == length - 2)) {
|
||||
if (dLon > minLon || dLon < -minLon || dLat > minLat || dLat < -minLat
|
||||
|| (pos == length - 2)) {
|
||||
outBuffer[floatPos++] = nLon;
|
||||
outBuffer[floatPos++] = nLat;
|
||||
cnt += 2;
|
||||
@ -727,7 +738,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
dLon = nLon - wayNodeLongitude;
|
||||
wayNodeLongitude = nLon;
|
||||
|
||||
if (dLon > minLon || dLon < -minLon || dLat > minLat || dLat < -minLat || (pos == length - 2)) {
|
||||
if (dLon > minLon || dLon < -minLon || dLat > minLat || dLat < -minLat
|
||||
|| (pos == length - 2)) {
|
||||
outBuffer[floatPos++] = nLon;
|
||||
outBuffer[floatPos++] = nLat;
|
||||
cnt += 2;
|
||||
@ -760,7 +772,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
* how many ways should be processed.
|
||||
* @return true if the ways could be processed successfully, false otherwise.
|
||||
*/
|
||||
private boolean processWays(QueryParameters queryParameters, IMapDatabaseCallback mapDatabaseCallback,
|
||||
private boolean processWays(QueryParameters queryParameters,
|
||||
IMapDatabaseCallback mapDatabaseCallback,
|
||||
int numberOfWays) {
|
||||
|
||||
Tag[] tags = null;
|
||||
@ -787,7 +800,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
}
|
||||
|
||||
if (queryParameters.useTileBitmask) {
|
||||
elementCounter = mReadBuffer.skipWays(queryParameters.queryTileBitmask, elementCounter);
|
||||
elementCounter = mReadBuffer.skipWays(queryParameters.queryTileBitmask,
|
||||
elementCounter);
|
||||
|
||||
if (elementCounter == 0)
|
||||
return true;
|
||||
@ -890,7 +904,8 @@ public class MapDatabase implements IMapDatabase {
|
||||
return false;
|
||||
|
||||
// wayDataContainer.textPos = textPos;
|
||||
mapDatabaseCallback.renderWay(layer, tags, mWayNodes, wayLengths, changed);
|
||||
mapDatabaseCallback
|
||||
.renderWay(layer, tags, mWayNodes, wayLengths, changed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -929,14 +944,18 @@ public class MapDatabase implements IMapDatabase {
|
||||
cumulatedNumberOfPois += mReadBuffer.readUnsignedInt();
|
||||
cumulatedNumberOfWays += mReadBuffer.readUnsignedInt();
|
||||
|
||||
if (cumulatedNumberOfPois < 0 || cumulatedNumberOfPois > MAXIMUM_ZOOM_TABLE_OBJECTS) {
|
||||
LOG.warning("invalid cumulated number of POIs in row " + row + ' ' + cumulatedNumberOfPois);
|
||||
if (cumulatedNumberOfPois < 0
|
||||
|| cumulatedNumberOfPois > MAXIMUM_ZOOM_TABLE_OBJECTS) {
|
||||
LOG.warning("invalid cumulated number of POIs in row " + row + ' '
|
||||
+ cumulatedNumberOfPois);
|
||||
if (mDebugFile) {
|
||||
LOG.warning(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||
}
|
||||
return null;
|
||||
} else if (cumulatedNumberOfWays < 0 || cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
|
||||
LOG.warning("invalid cumulated number of ways in row " + row + ' ' + cumulatedNumberOfWays);
|
||||
} else if (cumulatedNumberOfWays < 0
|
||||
|| cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS) {
|
||||
LOG.warning("invalid cumulated number of ways in row " + row + ' '
|
||||
+ cumulatedNumberOfWays);
|
||||
if (mMapFileHeader.getMapFileInfo().debugFile) {
|
||||
LOG.warning(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user