Map view roll (#474)

This commit is contained in:
Izumi Kawashima
2018-01-08 06:08:03 +09:00
committed by Emux
parent 4d7078e861
commit 49476e17bb
10 changed files with 187 additions and 12 deletions

View File

@@ -103,6 +103,7 @@ public class BitmapTileActivity extends MapActivity {
p.setTilt((float) (Math.random() * 60)); p.setTilt((float) (Math.random() * 60));
p.setBearing((float) (Math.random() * 360)); p.setBearing((float) (Math.random() * 360));
p.setRoll((float) (Math.random() * 360));
//mMapView.map().setMapPosition(p); //mMapView.map().setMapPosition(p);
mMapView.map().animator().animateTo(time, p); mMapView.map().animator().animateTo(time, p);

View File

@@ -108,6 +108,7 @@ public class SimpleMapActivity extends BaseMapActivity {
p.setTilt((float) (Math.random() * 60)); p.setTilt((float) (Math.random() * 60));
p.setBearing((float) (Math.random() * 360)); p.setBearing((float) (Math.random() * 360));
p.setRoll((float) (Math.random() * 360));
//mMapView.map().setMapPosition(p); //mMapView.map().setMapPosition(p);
mMapView.map().animator().animateTo(time, p); mMapView.map().animator().animateTo(time, p);

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2018 Izumi Kawashima
* 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
* 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.web.client;
import java.util.Collection;
import java.util.HashSet;
public class CameraRollControl {
private final String divQuerySelector;
public final int MAX_VALUE = 32768;
private Collection<BuildingSolutionControl.ValueChangeListener> listeners = new HashSet<>();
public CameraRollControl(String divQuerySelector) {
this.divQuerySelector = divQuerySelector;
}
public void init() {
initNative(divQuerySelector);
refresh();
}
private native void initNative(String divQuerySelector)/*-{
var crc = $doc.querySelector(divQuerySelector);
var that = this;
function onUpdate(val){
that.@org.oscim.web.client.CameraRollControl::fireValueChangeListeners(I)(val);
}
crc.addEventListener("input",function(){onUpdate(this.value);});
crc.addEventListener("change",function(){onUpdate(this.value);});
}-*/;
private native void refresh()/*-{
}-*/;
public void addValueChangeListener(BuildingSolutionControl.ValueChangeListener l) {
this.listeners.add(l);
}
public void removeValueChangeListener(BuildingSolutionControl.ValueChangeListener l) {
this.listeners.remove(l);
}
private void fireValueChangeListeners(int val) {
for (BuildingSolutionControl.ValueChangeListener l : this.listeners) {
l.onValueChange(val, MAX_VALUE);
}
}
public interface ValueChangeListener {
void onValueChange(int val, int max);
}
}

View File

@@ -1,7 +1,7 @@
/* /*
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2016-2017 Izumi Kawashima * Copyright 2016-2018 Izumi Kawashima
* Copyright 2017 devemux86 * Copyright 2017-2018 devemux86
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -52,6 +52,7 @@ class GwtMap extends GdxMap {
BuildingLayer mBuildingLayer; BuildingLayer mBuildingLayer;
BuildingSolutionControl mBuildingSolutionControl; BuildingSolutionControl mBuildingSolutionControl;
CameraRollControl mCameraRollControl;
SearchBox mSearchBox; SearchBox mSearchBox;
@Override @Override
@@ -175,6 +176,17 @@ class GwtMap extends GdxMap {
mMap.updateMap(true); mMap.updateMap(true);
} }
}); });
mCameraRollControl = new CameraRollControl("#camera-roll-input");
mCameraRollControl.addValueChangeListener(new BuildingSolutionControl.ValueChangeListener() {
@Override
public void onValueChange(int val, int max) {
mMap.viewport().setRoll((float) val / (float) max * 180.0f);
mMap.updateMap(true);
}
});
mBuildingSolutionControl.init(); mBuildingSolutionControl.init();
mCameraRollControl.init();
} }
} }

View File

@@ -111,6 +111,12 @@ html,body {
top: 40px; top: 40px;
left: 0px; left: 0px;
} }
#camera-roll{
z-index: 20001;
position: absolute;
top: 220px;
left: 0px;
}
input[type=range][orient=vertical]{ input[type=range][orient=vertical]{
writing-mode: bt-lr; /* IE */ writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* WebKit */ -webkit-appearance: slider-vertical; /* WebKit */

View File

@@ -76,5 +76,8 @@
<div id="building-solution"> <div id="building-solution">
<input type="range" orient="vertical" id="building-solution-input" min="0" max="65536" value="65536"/> <input type="range" orient="vertical" id="building-solution-input" min="0" max="65536" value="65536"/>
</div> </div>
<div id="camera-roll">
<input type="range" orient="vertical" id="camera-roll-input" min="-32768" max="32768" value="0"/>
</div>
</body> </body>
</html> </html>

View File

@@ -1,6 +1,7 @@
/* /*
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2018 devemux86 * Copyright 2018 devemux86
* Copyright 2018 Izumi Kawashima
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -27,7 +28,7 @@ import org.oscim.map.Map;
import java.util.HashMap; import java.util.HashMap;
public class MapUrl extends Timer { public class MapUrl extends Timer {
private int curLon, curLat, curZoom, curTilt, curRot; private int curLon, curLat, curZoom, curTilt, curRot, curRoll;
private MapPosition pos = new MapPosition(); private MapPosition pos = new MapPosition();
private final Map mMap; private final Map mMap;
private String mParams = ""; private String mParams = "";
@@ -57,6 +58,7 @@ public class MapUrl extends Timer {
double lat = pos.getLatitude(), lon = pos.getLongitude(); double lat = pos.getLatitude(), lon = pos.getLongitude();
float rotation = pos.bearing; float rotation = pos.bearing;
float tilt = pos.tilt; float tilt = pos.tilt;
float roll = pos.roll;
//String themeName = ""; //String themeName = "";
//String mapName = ""; //String mapName = "";
@@ -76,6 +78,8 @@ public class MapUrl extends Timer {
rotation = Float.parseFloat(p.substring(4)); rotation = Float.parseFloat(p.substring(4));
else if (p.startsWith("tilt=")) else if (p.startsWith("tilt="))
tilt = Float.parseFloat(p.substring(5)); tilt = Float.parseFloat(p.substring(5));
else if (p.startsWith("roll="))
roll = Float.parseFloat(p.substring(5));
// else if (p.startsWith("theme=")) // else if (p.startsWith("theme="))
// themeName = p.substring(6); // themeName = p.substring(6);
// else if (p.startsWith("map=")) // else if (p.startsWith("map="))
@@ -100,7 +104,7 @@ public class MapUrl extends Timer {
MercatorProjection.latitudeToY(lat), MercatorProjection.latitudeToY(lat),
1 << zoom, 1 << zoom,
rotation, rotation,
tilt); tilt, roll);
} }
@@ -111,14 +115,16 @@ public class MapUrl extends Timer {
int lon = (int) (pos.getLongitude() * 1000); int lon = (int) (pos.getLongitude() * 1000);
int tilt = (int) (pos.tilt); int tilt = (int) (pos.tilt);
int rot = (int) (pos.bearing); int rot = (int) (pos.bearing);
int roll = (int) (pos.roll);
if (curZoom != pos.zoomLevel || curLat != lat || curLon != lon if (curZoom != pos.zoomLevel || curLat != lat || curLon != lon
|| curTilt != tilt || curRot != rot) { || curTilt != tilt || curRot != rot || curRoll != roll) {
curLat = lat; curLat = lat;
curLon = lon; curLon = lon;
curZoom = pos.zoomLevel; curZoom = pos.zoomLevel;
curTilt = tilt; curTilt = tilt;
curRot = rot; curRot = rot;
curRoll = roll;
String newURL = Window.Location String newURL = Window.Location
.createUrlBuilder() .createUrlBuilder()
@@ -126,6 +132,7 @@ public class MapUrl extends Timer {
+ "scale=" + pos.zoomLevel + "scale=" + pos.zoomLevel
+ "&rot=" + curRot + "&rot=" + curRot
+ "&tilt=" + curTilt + "&tilt=" + curTilt
+ "&roll=" + curRoll
+ "&lat=" + (curLat / 1000f) + "&lat=" + (curLat / 1000f)
+ "&lon=" + (curLon / 1000f)) + "&lon=" + (curLon / 1000f))
.buildString(); .buildString();

View File

@@ -1,6 +1,7 @@
/* /*
* Copyright 2012 Hannes Janetzek * Copyright 2012 Hannes Janetzek
* Copyright 2016-2018 devemux86 * Copyright 2016-2018 devemux86
* Copyright 2018 Izumi Kawashima
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -47,6 +48,11 @@ public class MapPosition {
*/ */
public float tilt; public float tilt;
/**
* Perspective roll
*/
public float roll;
/** /**
* Zoom-level for current scale. * Zoom-level for current scale.
* - To be removed: FastMath.log2(scale) * - To be removed: FastMath.log2(scale)
@@ -61,6 +67,7 @@ public class MapPosition {
this.zoomLevel = 0; this.zoomLevel = 0;
this.bearing = 0; this.bearing = 0;
this.tilt = 0; this.tilt = 0;
this.roll = 0;
} }
public MapPosition(double latitude, double longitude, double scale) { public MapPosition(double latitude, double longitude, double scale) {
@@ -95,6 +102,15 @@ public class MapPosition {
return this; return this;
} }
public float getRoll() {
return roll;
}
public MapPosition setRoll(float roll) {
this.roll = clampRoll(roll);
return this;
}
public float getTilt() { public float getTilt() {
return tilt; return tilt;
} }
@@ -157,6 +173,7 @@ public class MapPosition {
this.scale = other.scale; this.scale = other.scale;
this.tilt = other.tilt; this.tilt = other.tilt;
this.zoomLevel = other.zoomLevel; this.zoomLevel = other.zoomLevel;
this.roll = other.roll;
} }
public void set(double x, double y, double scale, float bearing, float tilt) { public void set(double x, double y, double scale, float bearing, float tilt) {
@@ -169,6 +186,11 @@ public class MapPosition {
this.zoomLevel = FastMath.log2((int) scale); this.zoomLevel = FastMath.log2((int) scale);
} }
public void set(double x, double y, double scale, float bearing, float tilt, float roll) {
set(x, y, scale, bearing, tilt);
this.roll = clampRoll(roll);
}
private static float clampBearing(float bearing) { private static float clampBearing(float bearing) {
while (bearing > 180) while (bearing > 180)
bearing -= 360; bearing -= 360;
@@ -177,6 +199,10 @@ public class MapPosition {
return bearing; return bearing;
} }
private static float clampRoll(float roll) {
return clampBearing(roll); // Uses the same logic
}
/** /**
* @return scale relative to zoom-level. * @return scale relative to zoom-level.
*/ */
@@ -212,6 +238,7 @@ public class MapPosition {
y = miny + dy / 2; y = miny + dy / 2;
bearing = 0; bearing = 0;
tilt = 0; tilt = 0;
roll = 0;
} }
@Override @Override

View File

@@ -1,6 +1,7 @@
/* /*
* Copyright 2016 devemux86 * Copyright 2016-2018 devemux86
* Copyright 2017 Luca Osten * Copyright 2017 Luca Osten
* Copyright 2018 Izumi Kawashima
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -200,6 +201,23 @@ public class ViewController extends Viewport {
updateMatrices(); updateMatrices();
} }
public void rollMap(float move) {
setRoll(mPos.roll + move);
}
public void setRoll(double degree) {
ThreadUtils.assertMainThread();
while (degree > 360)
degree -= 360;
while (degree < 0)
degree += 360;
mPos.roll = (float) degree;
updateMatrices();
}
public boolean tiltMap(float move) { public boolean tiltMap(float move) {
return setTilt(mPos.tilt + move); return setTilt(mPos.tilt + move);
} }
@@ -233,13 +251,16 @@ public class ViewController extends Viewport {
private void updateMatrices() { private void updateMatrices() {
/* - view matrix: /* - view matrix:
* 0. apply rotate * 0. apply yaw
* 1. apply tilt */ * 1. apply pitch
* 2. apply roll */
mRotationMatrix.setRotation(mPos.bearing, 0, 0, 1); mRotationMatrix.setRotation(mPos.bearing, 0, 0, 1);
mTmpMatrix.setRotation(mPos.tilt, 1, 0, 0);
/* apply first rotation, then tilt */ mTmpMatrix.setRotation(mPos.tilt, 1, 0, 0);
mRotationMatrix.multiplyLhs(mTmpMatrix);
mTmpMatrix.setRotation(mPos.roll, 0, 1, 0);
mRotationMatrix.multiplyLhs(mTmpMatrix); mRotationMatrix.multiplyLhs(mTmpMatrix);
mViewMatrix.copy(mRotationMatrix); mViewMatrix.copy(mRotationMatrix);

View File

@@ -1,8 +1,9 @@
/* /*
* Copyright 2012 Hannes Janetzek * Copyright 2012 Hannes Janetzek
* Copyright 2016 devemux86 * Copyright 2016-2018 devemux86
* Copyright 2016 Erik Duisters * Copyright 2016 Erik Duisters
* Copyright 2017 Luca Osten * Copyright 2017 Luca Osten
* Copyright 2018 Izumi Kawashima
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -52,6 +53,9 @@ public class Viewport {
protected float mMinBearing = -180; protected float mMinBearing = -180;
protected float mMaxBearing = 180; protected float mMaxBearing = 180;
protected float mMinRoll = -180;
protected float mMaxRoll = 180;
protected double mMinX = 0; protected double mMinX = 0;
protected double mMaxX = 1; protected double mMaxX = 1;
protected double mMinY = 0; protected double mMinY = 0;
@@ -90,6 +94,7 @@ public class Viewport {
mPos.y = 0.5; mPos.y = 0.5;
mPos.bearing = 0; mPos.bearing = 0;
mPos.tilt = 0; mPos.tilt = 0;
mPos.roll = 0;
} }
public double limitScale(double scale) { public double limitScale(double scale) {
@@ -136,6 +141,14 @@ public class Viewport {
changed = true; changed = true;
} }
if (pos.roll > mMaxRoll) {
pos.roll = mMaxRoll;
changed = true;
} else if (pos.roll < mMinRoll) {
pos.roll = mMinRoll;
changed = true;
}
if (pos.x > mMaxX) { if (pos.x > mMaxX) {
pos.x = mMaxX; pos.x = mMaxX;
changed = true; changed = true;
@@ -168,10 +181,12 @@ public class Viewport {
|| pos.x != mPos.x || pos.x != mPos.x
|| pos.y != mPos.y || pos.y != mPos.y
|| pos.bearing != mPos.bearing || pos.bearing != mPos.bearing
|| pos.tilt != mPos.tilt); || pos.tilt != mPos.tilt
|| pos.roll != mPos.roll);
pos.bearing = mPos.bearing; pos.bearing = mPos.bearing;
pos.tilt = mPos.tilt; pos.tilt = mPos.tilt;
pos.roll = mPos.roll;
pos.x = mPos.x; pos.x = mPos.x;
pos.y = mPos.y; pos.y = mPos.y;
@@ -471,6 +486,22 @@ public class Viewport {
this.mMinBearing = minBearing; this.mMinBearing = minBearing;
} }
public float getMaxRoll() {
return mMaxRoll;
}
public void setMaxRoll(float maxRoll) {
this.mMaxRoll = maxRoll;
}
public float getMinRoll() {
return mMinRoll;
}
public void setMinRoll(float minRoll) {
this.mMinRoll = minRoll;
}
public double getMaxX() { public double getMaxX() {
return mMaxX; return mMaxX;
} }