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
No known key found for this signature in database
GPG Key ID: 89C6921D7AF2BDD0
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.setBearing((float) (Math.random() * 360));
p.setRoll((float) (Math.random() * 360));
//mMapView.map().setMapPosition(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.setBearing((float) (Math.random() * 360));
p.setRoll((float) (Math.random() * 360));
//mMapView.map().setMapPosition(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 2016-2017 Izumi Kawashima
* Copyright 2017 devemux86
* Copyright 2016-2018 Izumi Kawashima
* Copyright 2017-2018 devemux86
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -52,6 +52,7 @@ class GwtMap extends GdxMap {
BuildingLayer mBuildingLayer;
BuildingSolutionControl mBuildingSolutionControl;
CameraRollControl mCameraRollControl;
SearchBox mSearchBox;
@Override
@ -175,6 +176,17 @@ class GwtMap extends GdxMap {
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();
mCameraRollControl.init();
}
}

View File

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

View File

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

View File

@ -1,6 +1,7 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2018 devemux86
* Copyright 2018 Izumi Kawashima
*
* 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;
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 final Map mMap;
private String mParams = "";
@ -57,6 +58,7 @@ public class MapUrl extends Timer {
double lat = pos.getLatitude(), lon = pos.getLongitude();
float rotation = pos.bearing;
float tilt = pos.tilt;
float roll = pos.roll;
//String themeName = "";
//String mapName = "";
@ -76,6 +78,8 @@ public class MapUrl extends Timer {
rotation = Float.parseFloat(p.substring(4));
else if (p.startsWith("tilt="))
tilt = Float.parseFloat(p.substring(5));
else if (p.startsWith("roll="))
roll = Float.parseFloat(p.substring(5));
// else if (p.startsWith("theme="))
// themeName = p.substring(6);
// else if (p.startsWith("map="))
@ -100,7 +104,7 @@ public class MapUrl extends Timer {
MercatorProjection.latitudeToY(lat),
1 << zoom,
rotation,
tilt);
tilt, roll);
}
@ -111,14 +115,16 @@ public class MapUrl extends Timer {
int lon = (int) (pos.getLongitude() * 1000);
int tilt = (int) (pos.tilt);
int rot = (int) (pos.bearing);
int roll = (int) (pos.roll);
if (curZoom != pos.zoomLevel || curLat != lat || curLon != lon
|| curTilt != tilt || curRot != rot) {
|| curTilt != tilt || curRot != rot || curRoll != roll) {
curLat = lat;
curLon = lon;
curZoom = pos.zoomLevel;
curTilt = tilt;
curRot = rot;
curRoll = roll;
String newURL = Window.Location
.createUrlBuilder()
@ -126,6 +132,7 @@ public class MapUrl extends Timer {
+ "scale=" + pos.zoomLevel
+ "&rot=" + curRot
+ "&tilt=" + curTilt
+ "&roll=" + curRoll
+ "&lat=" + (curLat / 1000f)
+ "&lon=" + (curLon / 1000f))
.buildString();

View File

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

View File

@ -1,6 +1,7 @@
/*
* Copyright 2016 devemux86
* Copyright 2016-2018 devemux86
* Copyright 2017 Luca Osten
* Copyright 2018 Izumi Kawashima
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@ -200,6 +201,23 @@ public class ViewController extends Viewport {
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) {
return setTilt(mPos.tilt + move);
}
@ -233,13 +251,16 @@ public class ViewController extends Viewport {
private void updateMatrices() {
/* - view matrix:
* 0. apply rotate
* 1. apply tilt */
* 0. apply yaw
* 1. apply pitch
* 2. apply roll */
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);
mViewMatrix.copy(mRotationMatrix);

View File

@ -1,8 +1,9 @@
/*
* Copyright 2012 Hannes Janetzek
* Copyright 2016 devemux86
* Copyright 2016-2018 devemux86
* Copyright 2016 Erik Duisters
* Copyright 2017 Luca Osten
* Copyright 2018 Izumi Kawashima
*
* 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 mMaxBearing = 180;
protected float mMinRoll = -180;
protected float mMaxRoll = 180;
protected double mMinX = 0;
protected double mMaxX = 1;
protected double mMinY = 0;
@ -90,6 +94,7 @@ public class Viewport {
mPos.y = 0.5;
mPos.bearing = 0;
mPos.tilt = 0;
mPos.roll = 0;
}
public double limitScale(double scale) {
@ -136,6 +141,14 @@ public class Viewport {
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) {
pos.x = mMaxX;
changed = true;
@ -168,10 +181,12 @@ public class Viewport {
|| pos.x != mPos.x
|| pos.y != mPos.y
|| pos.bearing != mPos.bearing
|| pos.tilt != mPos.tilt);
|| pos.tilt != mPos.tilt
|| pos.roll != mPos.roll);
pos.bearing = mPos.bearing;
pos.tilt = mPos.tilt;
pos.roll = mPos.roll;
pos.x = mPos.x;
pos.y = mPos.y;
@ -471,6 +486,22 @@ public class Viewport {
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() {
return mMaxX;
}