diff --git a/src/org/oscim/database/oscimap/MapDatabase.java b/src/org/oscim/database/oscimap/MapDatabase.java index 4c1fa70f..5d1e2dd8 100644 --- a/src/org/oscim/database/oscimap/MapDatabase.java +++ b/src/org/oscim/database/oscimap/MapDatabase.java @@ -65,7 +65,8 @@ public class MapDatabase implements IMapDatabase { private static final String CACHE_FILE = "%d-%d-%d.tile"; private static final String SERVER_ADDR = "city.informatik.uni-bremen.de"; - private static final String URL = "/osci/map-live/"; + // private static final String URL = "/osci/map-live/"; + private static final String URL = "/osci/oscim/"; private final static float REF_TILE_SIZE = 4096.0f; @@ -83,21 +84,6 @@ public class MapDatabase implements IMapDatabase { private final boolean debug = false; - // private static final int MAX_TAGS_CACHE = 100; - // private static Map tagHash = Collections - // .synchronizedMap(new LinkedHashMap( - // MAX_TAGS_CACHE, 0.75f, true) { - // - // private static final long serialVersionUID = 1L; - // - // @Override - // protected boolean removeEldestEntry(Entry e) { - // if (size() < MAX_TAGS_CACHE) - // return false; - // return true; - // } - // }); - @Override public QueryResult executeQuery(JobTile tile, IMapDatabaseCallback mapDatabaseCallback) { QueryResult result = QueryResult.SUCCESS; @@ -234,7 +220,7 @@ public class MapDatabase implements IMapDatabase { return file; } - // /////////////// hand sewed tile protocol buffers decoder /////////////////// + // /////////////// hand sewed tile protocol buffers decoder /////////////// // TODO write an own serialization format for structs and packed strings.. private static final int BUFFER_SIZE = 65536; @@ -763,7 +749,7 @@ public class MapDatabase implements IMapDatabase { | (buffer[offset + 3] & 0xff); } - // ///////////////////////// Lightweight HttpClient /////////////////////////////////////// + // ///////////////////////// Lightweight HttpClient /////////////////////// // should have written simple tcp server/client for this... private int mMaxReq = 0; @@ -788,9 +774,7 @@ public class MapDatabase implements IMapDatabase { InputStream is = mResponseStream; byte[] buf = mReadBuffer; - boolean first = true; - int read = 0; int pos = 0; int end = 0; @@ -806,8 +790,9 @@ public class MapDatabase implements IMapDatabase { if (first) { // check only for OK first = false; + int i = 0; - for (int i = 0; i < 15 && pos + i < end; i++) + for (; i < 15 && pos + i < end; i++) if (buf[pos + i] != RESPONSE_HTTP_OK[i]) return -1; @@ -854,7 +839,6 @@ public class MapDatabase implements IMapDatabase { if (mSocket != null && ((mMaxReq-- <= 0) || (SystemClock.elapsedRealtime() - mLastRequest > RESPONSE_EXPECTED_TIMEOUT))) { - try { mSocket.close(); } catch (IOException e) { @@ -893,7 +877,8 @@ public class MapDatabase implements IMapDatabase { len += pos; // this does the same but with a few more allocations: - // byte[] request = String.format(REQUEST, Integer.valueOf(tile.zoomLevel), + // byte[] request = String.format(REQUEST, + // Integer.valueOf(tile.zoomLevel), // Integer.valueOf(tile.tileX), Integer.valueOf(tile.tileY)).getBytes(); try { @@ -950,7 +935,8 @@ public class MapDatabase implements IMapDatabase { return pos + i; } - // //////////////////////////// Tile cache //////////////////////////////////// + // //////////////////////////// Tile cache + // //////////////////////////////////// private boolean cacheRead(Tile tile, File f) { if (f.exists() && f.length() > 0) { diff --git a/src/org/oscim/view/MapView.java b/src/org/oscim/view/MapView.java index 3b962745..06cf09ca 100644 --- a/src/org/oscim/view/MapView.java +++ b/src/org/oscim/view/MapView.java @@ -188,7 +188,7 @@ public class MapView extends FrameLayout { mMapZoomControls = new MapZoomControls(mapActivity, this); mMapZoomControls.setShowMapZoomControls(true); - enableRotation = true; + // enableRotation = true; for (MapWorker worker : mMapWorkers) worker.start(); diff --git a/src/org/oscim/view/MapViewPosition.java b/src/org/oscim/view/MapViewPosition.java index 4a3086a2..387b5108 100644 --- a/src/org/oscim/view/MapViewPosition.java +++ b/src/org/oscim/view/MapViewPosition.java @@ -38,7 +38,7 @@ public class MapViewPosition { private byte mZoomLevel; private float mScale; private float mRotation; - private float mTilt; + public float mTilt; // 2^mZoomLevel * mScale; private float mMapScale; @@ -278,4 +278,17 @@ public class MapViewPosition { mScale = newScale / (1 << z); mMapScale = newScale; } + + public boolean tilt(float moveX) { + float tilt = mTilt + moveX; + if (tilt > 25) + tilt = 25; + else if (tilt < 0) + tilt = 0; + if (mTilt == tilt) + return false; + + mTilt = tilt; + return true; + } } diff --git a/src/org/oscim/view/TouchHandler.java b/src/org/oscim/view/TouchHandler.java index a44a8e3a..275e9867 100644 --- a/src/org/oscim/view/TouchHandler.java +++ b/src/org/oscim/view/TouchHandler.java @@ -95,16 +95,21 @@ public class TouchHandler { private boolean mScaling = false; private boolean onActionMove(MotionEvent event) { - int pointerIndex = event.findPointerIndex(mActivePointerId); + int id = event.findPointerIndex(mActivePointerId); // calculate the distance between previous and current position - float moveX = event.getX(pointerIndex) - mPosX; - float moveY = event.getY(pointerIndex) - mPosY; + float moveX = event.getX(id) - mPosX; + float moveY = event.getY(id) - mPosY; + // save the position of the event + + // Log.d("...", "mx " + moveX + " my " + moveY); boolean scaling = mScaleGestureDetector.isInProgress(); + if (!mScaling) { mScaling = scaling; } + if (!scaling && !mMoveStart) { if (Math.abs(moveX) > 3 * mMapMoveDelta @@ -112,11 +117,17 @@ public class TouchHandler { // the map movement threshold has been reached // longPressDetector.pressStop(); mMoveStart = true; - - // save the position of the event - mPosX = event.getX(pointerIndex); - mPosY = event.getY(pointerIndex); } + + return true; + } + + mPosX = event.getX(id); + mPosY = event.getY(id); + + if (!scaling) { + mMapPosition.moveMap(moveX, moveY); + mMapView.redrawMap(); return true; } @@ -133,7 +144,12 @@ public class TouchHandler { double rad = Math.atan2(dy, dx); double r = rad - mAngle; - // Log.d("...", "move " + x + " " + y + " " + cx + " " + cy); + if (!mBeginRotate && Math.abs(dy) < 80) { + if (mMapPosition.tilt(moveY / 4)) { + mMapView.redrawMap(); + return true; + } + } if (!mBeginRotate && !mBeginScale) { if (r > 0.02 || r < -0.02) @@ -153,18 +169,9 @@ public class TouchHandler { mAngle = rad; mMapView.redrawMap(); } + } } - // save the position of the event - mPosX = event.getX(pointerIndex); - mPosY = event.getY(pointerIndex); - - if (scaling) { - return true; - } - - mMapPosition.moveMap(moveX, moveY); - mMapView.redrawMap(); return true; } diff --git a/src/org/oscim/view/renderer/GLRenderer.java b/src/org/oscim/view/renderer/GLRenderer.java index 2463fef1..5f6dea6d 100644 --- a/src/org/oscim/view/renderer/GLRenderer.java +++ b/src/org/oscim/view/renderer/GLRenderer.java @@ -523,7 +523,9 @@ public class GLRenderer implements GLSurfaceView.Renderer { Matrix.setRotateM(mRotateMatrix, 0, mapPosition.angle, 0, 0, 1); // tilt map - float angle = 15f / (mHeight / 2); + // mMapView.getMapViewPosition().mTilt; + + float angle = mMapView.getMapViewPosition().mTilt / (mHeight / 2); Matrix.setRotateM(mTmpMatrix, 0, -angle, 1, 0, 0); // move camera center back to map center @@ -698,6 +700,7 @@ public class GLRenderer implements GLSurfaceView.Renderer { PolygonLayer pl = tile.polygonLayers; boolean clipped = false; + int simpleShader = mRotate ? 0 : 1; for (; pl != null || ll != null;) { int lnext = Integer.MAX_VALUE; @@ -724,7 +727,8 @@ public class GLRenderer implements GLSurfaceView.Renderer { } GLES20.glEnable(GL_BLEND); - ll = LineRenderer.drawLines(tile, ll, pnext, mvp, div, z, s); + ll = LineRenderer.drawLines(tile, ll, pnext, mvp, div, z, s, + simpleShader); } } } @@ -755,8 +759,10 @@ public class GLRenderer implements GLSurfaceView.Renderer { // TODO could use tile.proxies here private static void drawProxyTile(MapPosition mapPosition, MapTile tile) { + int diff = mapPosition.zoomLevel - tile.zoomLevel; + boolean drawn = false; - if (mapPosition.scale > 1.5f) { + if (mapPosition.scale > 1.5f || diff < 0) { // prefer drawing children if (!drawProxyChild(mapPosition, tile)) { if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { diff --git a/src/org/oscim/view/renderer/LineRenderer.java b/src/org/oscim/view/renderer/LineRenderer.java index 8bcff25d..e44326cd 100644 --- a/src/org/oscim/view/renderer/LineRenderer.java +++ b/src/org/oscim/view/renderer/LineRenderer.java @@ -21,73 +21,91 @@ import org.oscim.utils.GlUtils; import android.opengl.GLES20; import android.util.FloatMath; +import android.util.Log; class LineRenderer { + private final static String TAG = "LineRenderer"; + private static int NUM_VERTEX_SHORTS = 4; private static final int LINE_VERTICES_DATA_POS_OFFSET = 0; private static final int LINE_VERTICES_DATA_TEX_OFFSET = 4; // shader handles - private static int lineProgram; - private static int hLineVertexPosition; - private static int hLineTexturePosition; - private static int hLineColor; - private static int hLineMatrix; - private static int hLineScale; - private static int hLineWidth; - private static int hLineOffset; + private static int[] lineProgram = new int[2]; + private static int[] hLineVertexPosition = new int[2]; + private static int[] hLineTexturePosition = new int[2]; + private static int[] hLineColor = new int[2]; + private static int[] hLineMatrix = new int[2]; + private static int[] hLineScale = new int[2]; + private static int[] hLineWidth = new int[2]; static boolean init() { - lineProgram = GlUtils.createProgram(Shaders.lineVertexShader, + lineProgram[0] = GlUtils.createProgram(Shaders.lineVertexShader, Shaders.lineFragmentShader); - if (lineProgram == 0) { - // Log.e(TAG, "Could not create line program."); + if (lineProgram[0] == 0) { + Log.e(TAG, "Could not create line program."); return false; } - hLineMatrix = GLES20.glGetUniformLocation(lineProgram, "u_mvp"); - hLineScale = GLES20.glGetUniformLocation(lineProgram, "u_wscale"); - hLineWidth = GLES20.glGetUniformLocation(lineProgram, "u_width"); - hLineColor = GLES20.glGetUniformLocation(lineProgram, "u_color"); + hLineMatrix[0] = GLES20.glGetUniformLocation(lineProgram[0], "u_mvp"); + hLineScale[0] = GLES20.glGetUniformLocation(lineProgram[0], "u_wscale"); + hLineWidth[0] = GLES20.glGetUniformLocation(lineProgram[0], "u_width"); + hLineColor[0] = GLES20.glGetUniformLocation(lineProgram[0], "u_color"); - hLineVertexPosition = GLES20.glGetAttribLocation(lineProgram, "a_position"); - hLineTexturePosition = GLES20.glGetAttribLocation(lineProgram, "a_st"); + hLineVertexPosition[0] = GLES20.glGetAttribLocation(lineProgram[0], "a_position"); + hLineTexturePosition[0] = GLES20.glGetAttribLocation(lineProgram[0], "a_st"); + + lineProgram[1] = GlUtils.createProgram(Shaders.lineVertexShader, + Shaders.lineSimpleFragmentShader); + if (lineProgram[1] == 0) { + Log.e(TAG, "Could not create simple line program."); + return false; + } + + hLineMatrix[1] = GLES20.glGetUniformLocation(lineProgram[1], "u_mvp"); + hLineScale[1] = GLES20.glGetUniformLocation(lineProgram[1], "u_wscale"); + hLineWidth[1] = GLES20.glGetUniformLocation(lineProgram[1], "u_width"); + hLineColor[1] = GLES20.glGetUniformLocation(lineProgram[1], "u_color"); + + hLineVertexPosition[1] = GLES20.glGetAttribLocation(lineProgram[1], "a_position"); + hLineTexturePosition[1] = GLES20.glGetAttribLocation(lineProgram[1], "a_st"); return true; } - static final boolean mFast = false; + // static int mSimple = 1; static LineLayer drawLines(MapTile tile, LineLayer layer, int next, float[] matrix, - float div, double zoom, float scale) { + float div, double zoom, float scale, int mode) { + // int mode = mSimple; if (layer == null) return null; // TODO should use fast line program when view is not tilted - GLES20.glUseProgram(lineProgram); + GLES20.glUseProgram(lineProgram[mode]); - GLES20.glEnableVertexAttribArray(hLineVertexPosition); - GLES20.glEnableVertexAttribArray(hLineTexturePosition); + GLES20.glEnableVertexAttribArray(hLineVertexPosition[mode]); + GLES20.glEnableVertexAttribArray(hLineTexturePosition[mode]); - GLES20.glVertexAttribPointer(hLineVertexPosition, 2, GLES20.GL_SHORT, + GLES20.glVertexAttribPointer(hLineVertexPosition[mode], 2, GLES20.GL_SHORT, false, 8, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET); - GLES20.glVertexAttribPointer(hLineTexturePosition, 2, GLES20.GL_SHORT, + GLES20.glVertexAttribPointer(hLineTexturePosition[mode], 2, GLES20.GL_SHORT, false, 8, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET); - GLES20.glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0); + GLES20.glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0); // scale factor to map one pixel on tile to one pixel on screen: // only works with orthographic projection float s = scale / div; float pixel = 2.0f / s; - if (mFast) - GLES20.glUniform1f(hLineScale, pixel); - else - GLES20.glUniform1f(hLineScale, 0); + if (mode == 0) + pixel = 0; + + GLES20.glUniform1f(hLineScale[mode], pixel); // line scale factor (for non fixed lines) float lineScale = FloatMath.sqrt(s); @@ -104,13 +122,10 @@ class LineRenderer { if (line.fade >= zoom) alpha = (scale > 1.2f ? scale : 1.2f) - alpha; - GlUtils.setColor(hLineColor, line.color, alpha); + GlUtils.setColor(hLineColor[mode], line.color, alpha); if (blur) { - if (mFast) - GLES20.glUniform1f(hLineScale, pixel); - else - GLES20.glUniform1f(hLineScale, 0); + GLES20.glUniform1f(hLineScale[mode], pixel); blur = false; } @@ -118,39 +133,41 @@ class LineRenderer { for (LineLayer o = l.outlines; o != null; o = o.outlines) { if (line.blur != 0) { - GLES20.glUniform1f(hLineScale, (l.width + o.width) / s + GLES20.glUniform1f(hLineScale[mode], (l.width + o.width) / s - (line.blur / s)); blur = true; } if (zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL) - GLES20.glUniform1f(hLineWidth, (l.width + o.width) / s); + GLES20.glUniform1f(hLineWidth[mode], (l.width + o.width) / s); else - GLES20.glUniform1f(hLineWidth, l.width / s + o.width / lineScale); + GLES20.glUniform1f(hLineWidth[mode], l.width / s + o.width + / lineScale); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, o.offset, o.verticesCnt); } } else { if (line.blur != 0) { - GLES20.glUniform1f(hLineScale, (l.width / lineScale) * line.blur); + GLES20.glUniform1f(hLineScale[mode], (l.width / lineScale) + * line.blur); blur = true; } if (line.fixed || zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL) { // invert scaling of extrusion vectors so that line width // stays the same. - GLES20.glUniform1f(hLineWidth, l.width / s); + GLES20.glUniform1f(hLineWidth[mode], l.width / s); } else { - GLES20.glUniform1f(hLineWidth, l.width / lineScale); + GLES20.glUniform1f(hLineWidth[mode], l.width / lineScale); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt); } } - GLES20.glDisableVertexAttribArray(hLineVertexPosition); - GLES20.glDisableVertexAttribArray(hLineTexturePosition); + GLES20.glDisableVertexAttribArray(hLineVertexPosition[mode]); + GLES20.glDisableVertexAttribArray(hLineTexturePosition[mode]); return l; } diff --git a/src/org/oscim/view/renderer/MapTile.java b/src/org/oscim/view/renderer/MapTile.java index b0568b6d..cdf104eb 100644 --- a/src/org/oscim/view/renderer/MapTile.java +++ b/src/org/oscim/view/renderer/MapTile.java @@ -78,18 +78,6 @@ class MapTile extends JobTile { return isActive || refs > 0; } - // void unref() { - // if (refs == 0) { - // Log.d("MapTile", "XXX already unrefd " + this); - // return; - // } - // refs--; - // } - // - // void ref() { - // refs++; - // } - void lock() { isActive = true; @@ -102,13 +90,14 @@ class MapTile extends JobTile { if (p != null && (p.isReady || p.newData || p.isLoading)) { proxies |= PROXY_PARENT; p.refs++; - } else { - p = rel.parent.parent.tile; - if (p != null && (p.isReady || p.newData || p.isLoading)) { - proxies |= PROXY_GRAMPA; - p.refs++; - } } + + p = rel.parent.parent.tile; + if (p != null && (p.isReady || p.newData || p.isLoading)) { + proxies |= PROXY_GRAMPA; + p.refs++; + } + for (int j = 0; j < 4; j++) { if (rel.child[j] != null) { p = rel.child[j].tile; @@ -129,7 +118,8 @@ class MapTile extends JobTile { if ((proxies & (1 << 4)) != 0) { MapTile p = rel.parent.tile; p.refs--; - } else if ((proxies & (1 << 5)) != 0) { + } + if ((proxies & (1 << 5)) != 0) { MapTile p = rel.parent.parent.tile; p.refs--; } diff --git a/src/org/oscim/view/renderer/Shaders.java b/src/org/oscim/view/renderer/Shaders.java index 3c5a2e89..398dd787 100644 --- a/src/org/oscim/view/renderer/Shaders.java +++ b/src/org/oscim/view/renderer/Shaders.java @@ -51,25 +51,24 @@ class Shaders { // + " v_st = u_width * a_st;" // + "}"; - // final static String lineFragmentShader = "" - // + "precision mediump float;" - // + "uniform float u_wscale;" - // + "uniform float u_width;" - // + "uniform vec4 u_color;" - // + "varying vec2 v_st;" - // + "const float zero = 0.0;" - // + "void main() {" - // + " float len;" - // + " if (v_st.t == zero)" - // + " len = abs(v_st.s);" - // + " else " - // + " len = length(v_st);" - // // fade to alpha. u_wscale is the width in pixel which should be faded, - // // u_width - len the position of this fragment on the perpendicular to - // // this line segment - // + " gl_FragColor = smoothstep(zero, u_wscale, u_width - len) * u_color;" - // // + " gl_FragColor = u_color;" - // + "}"; + final static String lineSimpleFragmentShader = "" + + "precision mediump float;" + + "uniform float u_wscale;" + + "uniform float u_width;" + + "uniform vec4 u_color;" + + "varying vec2 v_st;" + + "const float zero = 0.0;" + + "void main() {" + + " float len;" + + " if (v_st.t == zero)" + + " len = abs(v_st.s);" + + " else " + + " len = length(v_st);" + // fade to alpha. u_wscale is the width in pixel which should be + // faded, u_width - len the position of this fragment on the + // perpendicular to this line segment + + " gl_FragColor = smoothstep(zero, u_wscale, u_width - len) * u_color;" + + "}"; final static String lineFragmentShader = "" + "#extension GL_OES_standard_derivatives : enable\n"