Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location texture renderer: rewrite and optimize #750

Merged
merged 2 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## New since 0.12.0

- Render themes: symbols on lines with billboard / rotation [#743](https://github.com/mapsforge/vtm/pull/743)
- Location texture renderer: rewrite and optimize [#750](https://github.com/mapsforge/vtm/pull/750)
- Android: OpenGL ES 2.0 default for performance / stability [#749](https://github.com/mapsforge/vtm/pull/749)
- `MapView.OPENGL_VERSION`
- Android: threaded system initialization
Expand Down
15 changes: 15 additions & 0 deletions vtm-android-example/res/raw/marker.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import android.os.Bundle;
import org.oscim.core.MapPosition;
import org.oscim.layers.LocationLayer;
import org.oscim.renderer.LocationCallback;

public class LocationActivity extends BitmapTileActivity implements LocationListener {
private Location location;
private LocationLayer locationLayer;
private LocationManager locationManager;
private final MapPosition mapPosition = new MapPosition();
Expand All @@ -37,7 +39,17 @@ public void onCreate(Bundle savedInstanceState) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

locationLayer = new LocationLayer(mMap);
locationLayer.locationRenderer.setShader("location_1_reverse");
locationLayer.locationRenderer.setCallback(new LocationCallback() {
@Override
public boolean hasRotation() {
return location != null && location.hasBearing();
}

@Override
public float getRotation() {
return location != null && location.hasBearing() ? location.getBearing() : 0;
}
});
locationLayer.setEnabled(false);
mMap.layers().add(locationLayer);
}
Expand Down Expand Up @@ -66,6 +78,7 @@ public void onStop() {

@Override
public void onLocationChanged(Location location) {
this.location = location;
locationLayer.setEnabled(true);
locationLayer.setPosition(location.getLatitude(), location.getLongitude(), location.getAccuracy());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,16 @@
import android.os.Bundle;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.backend.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.layers.LocationTextureLayer;
import org.oscim.renderer.atlas.TextureAtlas;
import org.oscim.renderer.atlas.TextureRegion;
import org.oscim.renderer.bucket.TextureItem;
import org.oscim.renderer.LocationCallback;
import org.oscim.utils.IOUtils;

import java.io.IOException;
import java.io.InputStream;

public class LocationTextureActivity extends BitmapTileActivity implements LocationListener {
private Location location;
private LocationTextureLayer locationLayer;
private LocationManager locationManager;
private final MapPosition mapPosition = new MapPosition();
Expand All @@ -47,34 +45,41 @@ public void onCreate(Bundle savedInstanceState) {

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

// load a Bitmap/SVG from resources
InputStream is = null;
Bitmap bmp = null;
Bitmap bitmapArrow = null;
try {
is = getResources().openRawResource(R.raw.arrow);
float scale = CanvasAdapter.getScale();
bmp = CanvasAdapter.decodeSvgBitmap(is, (int) (60 * scale), (int) (60 * scale), 100);
bitmapArrow = CanvasAdapter.decodeSvgBitmap(is, (int) (48 * CanvasAdapter.getScale()), (int) (48 * CanvasAdapter.getScale()), 100);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(is);
}

// create TextureRegion from Bitmap
TextureRegion textureRegion = new TextureRegion(new TextureItem(bmp), new TextureAtlas.Rect(0, 0, bmp.getWidth(), bmp.getHeight()));

// create LocationTextureLayer with created/loaded TextureRegion
locationLayer = new LocationTextureLayer(mMap, textureRegion);

// set color of accuracy circle (Color.BLUE is default)
locationLayer.locationRenderer.setAccuracyColor(Color.get(50, 50, 255));

// set color of indicator circle (Color.RED is default)
locationLayer.locationRenderer.setIndicatorColor(Color.MAGENTA);
Bitmap bitmapMarker = null;
try {
is = getResources().openRawResource(R.raw.marker);
bitmapMarker = CanvasAdapter.decodeSvgBitmap(is, (int) (48 * CanvasAdapter.getScale()), (int) (48 * CanvasAdapter.getScale()), 100);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(is);
}

// set billboard rendering for TextureRegion (false is default)
locationLayer.locationRenderer.setBillboard(false);
locationLayer = new LocationTextureLayer(mMap);
locationLayer.locationRenderer.setBitmapArrow(bitmapArrow);
locationLayer.locationRenderer.setBitmapMarker(bitmapMarker);
locationLayer.locationRenderer.setCallback(new LocationCallback() {
@Override
public boolean hasRotation() {
return location != null && location.hasBearing();
}

@Override
public float getRotation() {
return location != null && location.hasBearing() ? location.getBearing() : 0;
}
});
locationLayer.setEnabled(false);
mMap.layers().add(locationLayer);
}
Expand Down Expand Up @@ -103,8 +108,9 @@ public void onStop() {

@Override
public void onLocationChanged(Location location) {
this.location = location;
locationLayer.setEnabled(true);
locationLayer.setPosition(location.getLatitude(), location.getLongitude(), location.getBearing(), location.getAccuracy());
locationLayer.setPosition(location.getLatitude(), location.getLongitude(), location.getAccuracy());

// Follow location
mMap.getMapPosition(mapPosition);
Expand Down
8 changes: 3 additions & 5 deletions vtm-app/src/org/oscim/app/location/Compass.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright 2013 Ahmad Saleem
* Copyright 2013 Hannes Janetzek
* Copyright 2016-2017 devemux86
* Copyright 2016-2019 devemux86
*
* 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
Expand All @@ -24,19 +24,17 @@
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;

import org.oscim.app.App;
import org.oscim.app.R;
import org.oscim.core.MapPosition;
import org.oscim.event.Event;
import org.oscim.layers.Layer;
import org.oscim.map.Map;
import org.oscim.renderer.LocationRenderer;
import org.oscim.renderer.LocationCallback;
import org.oscim.utils.FastMath;

@SuppressWarnings("deprecation")
public class Compass extends Layer implements SensorEventListener, Map.UpdateListener,
LocationRenderer.Callback {
public class Compass extends Layer implements SensorEventListener, Map.UpdateListener, LocationCallback {

// static final Logger log = LoggerFactory.getLogger(Compass.class);

Expand Down
38 changes: 38 additions & 0 deletions vtm/resources/assets/shaders/accuracy_1.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifdef GLES
precision mediump float;
#endif
uniform mat4 u_mvp;
uniform float u_phase;
uniform float u_scale;
attribute vec2 a_pos;
varying vec2 v_tex;

void main() {
gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);
v_tex = a_pos;
}

$$

#ifdef GLES
precision mediump float;
#endif
varying vec2 v_tex;
uniform float u_scale;
uniform int u_mode;
uniform vec4 u_color;

void main() {
float len = 1.0 - length(v_tex);
if (u_mode == -1) {
gl_FragColor = u_color * len;
} else {
// outer ring
float a = smoothstep(0.0, 2.0 / u_scale, len);
// inner ring
float b = 0.8 * smoothstep(3.0 / u_scale, 4.0 / u_scale, len);
// - subtract inner from outer to create the outline
a = a - b;
gl_FragColor = u_color * a;
}
}
4 changes: 2 additions & 2 deletions vtm/src/org/oscim/layers/LocationLayer.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright 2013 Ahmad Saleem
* Copyright 2013 Hannes Janetzek
* Copyright 2016-2017 devemux86
* Copyright 2016-2019 devemux86
*
* 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
Expand Down Expand Up @@ -45,7 +45,7 @@ public void setEnabled(boolean enabled) {
locationRenderer.animate(false);
}

public void setPosition(double latitude, double longitude, double accuracy) {
public void setPosition(double latitude, double longitude, float accuracy) {
double x = MercatorProjection.longitudeToX(longitude);
double y = MercatorProjection.latitudeToY(latitude);
double radius = accuracy / MercatorProjection.groundResolutionWithScale(latitude, 1);
Expand Down
22 changes: 12 additions & 10 deletions vtm/src/org/oscim/layers/LocationTextureLayer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/*
* Copyright 2013 Ahmad Saleem
* Copyright 2013 Hannes Janetzek
* Copyright 2016-2019 devemux86
* Copyright 2017-2018 Longri
* Copyright 2018 devemux86
*
* 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
Expand All @@ -15,19 +17,22 @@
*/
package org.oscim.layers;

import org.oscim.backend.CanvasAdapter;
import org.oscim.core.MercatorProjection;
import org.oscim.map.Map;
import org.oscim.renderer.LocationTextureRenderer;
import org.oscim.renderer.atlas.TextureRegion;

public class LocationTextureLayer extends Layer {
public final LocationTextureRenderer locationRenderer;

public LocationTextureLayer(Map map, TextureRegion textureRegion) {
public LocationTextureLayer(Map map) {
this(map, CanvasAdapter.getScale());
}

public LocationTextureLayer(Map map, float scale) {
super(map);

mRenderer = locationRenderer = new LocationTextureRenderer(map);
locationRenderer.setTextureRegion(textureRegion);
mRenderer = locationRenderer = new LocationTextureRenderer(map, this, scale);
}

@Override
Expand All @@ -41,14 +46,11 @@ public void setEnabled(boolean enabled) {
locationRenderer.animate(false);
}

public void setPosition(double latitude, double longitude, float bearing, float accuracy) {
public void setPosition(double latitude, double longitude, float accuracy) {
double x = MercatorProjection.longitudeToX(longitude);
double y = MercatorProjection.latitudeToY(latitude);
bearing = -bearing;
while (bearing < 0)
bearing += 360;
double radius = accuracy / MercatorProjection.groundResolutionWithScale(latitude, 1);
locationRenderer.setLocation(x, y, bearing, radius);
locationRenderer.setLocation(x, y, radius);
locationRenderer.animate(true);
}
}
24 changes: 24 additions & 0 deletions vtm/src/org/oscim/renderer/LocationCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2016-2019 devemux86
*
* 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.oscim.renderer;

public interface LocationCallback {
/**
* Useful with Android Location.hasBearing().
*/
boolean hasRotation();

float getRotation();
}
30 changes: 5 additions & 25 deletions vtm/src/org/oscim/renderer/LocationRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.GL;
import org.oscim.backend.canvas.Color;
import org.oscim.core.Box;
import org.oscim.core.Point;
import org.oscim.core.Tile;
Expand Down Expand Up @@ -68,8 +67,8 @@ public class LocationRenderer extends LayerRenderer {
private long mAnimStart;
private boolean mCenter;

private Callback mCallback;
private final float[] mColors = new float[4];
private LocationCallback mCallback;
private int mColor = COLOR;
private final Point mLocation = new Point(Double.NaN, Double.NaN);
private double mRadius;
private int mShowAccuracyZoom = SHOW_ACCURACY_ZOOM;
Expand All @@ -82,19 +81,13 @@ public LocationRenderer(Map map, Layer layer, float scale) {
mMap = map;
mLayer = layer;
mScale = scale;

float a = Color.aToFloat(COLOR);
mColors[0] = a * Color.rToFloat(COLOR);
mColors[1] = a * Color.gToFloat(COLOR);
mColors[2] = a * Color.bToFloat(COLOR);
mColors[3] = a;
}

public void setAnimate(boolean animate) {
mAnimate = animate;
}

public void setCallback(Callback callback) {
public void setCallback(LocationCallback callback) {
mCallback = callback;
}

Expand All @@ -103,11 +96,7 @@ public void setCenter(boolean center) {
}

public void setColor(int color) {
float a = Color.aToFloat(color);
mColors[0] = a * Color.rToFloat(color);
mColors[1] = a * Color.gToFloat(color);
mColors[2] = a * Color.bToFloat(color);
mColors[3] = a;
mColor = color;
}

public void setLocation(double x, double y, double radius) {
Expand Down Expand Up @@ -287,7 +276,7 @@ public void render(GLViewport v) {
} else
gl.uniform1i(uMode, -1); // Outside screen

GLUtils.glUniform4fv(uColor, 1, mColors);
GLUtils.setColor(uColor, mColor);

gl.drawArrays(GL.TRIANGLE_STRIP, 0, 4);
}
Expand All @@ -308,13 +297,4 @@ protected boolean init() {

return true;
}

public interface Callback {
/**
* Usually true, can be used with e.g. Android Location.hasBearing().
*/
boolean hasRotation();

float getRotation();
}
}
Loading