/* * Copyright 2012 Hannes Janetzek * * This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * * 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.core; import org.oscim.utils.FastMath; public class MapPosition { /** Projected position x 0..1 */ public double x; /** Projected position y 0..1 */ public double y; /** * Absolute scale * - use setScale() to modify */ public double scale; /** Rotation angle */ public float bearing; /** Perspective tilt */ public float tilt; /** * Zoom-level for current scale. * - To be removed: FastMath.log2(scale) * - use setZoomLevel() to modify */ public int zoomLevel; public MapPosition() { this.scale = 1; this.x = 0.5; this.y = 0.5; this.zoomLevel = 1; this.bearing = 0; } public MapPosition(double latitude, double longitude, double scale) { setPosition(latitude, longitude); setScale(scale); } public double getX() { return x; } public MapPosition setX(double x) { this.x = x; return this; } public double getY() { return y; } public MapPosition setY(double y) { this.y = y; return this; } public float getBearing() { return bearing; } public MapPosition setBearing(float bearing) { this.bearing = bearing; return this; } public float getTilt() { return tilt; } public MapPosition setTilt(float tilt) { this.tilt = tilt; return this; } public double getScale() { return scale; } public int getZoomLevel() { return zoomLevel; } public MapPosition setZoomLevel(int zoomLevel) { this.zoomLevel = zoomLevel; this.scale = 1 << zoomLevel; return this; } public MapPosition setScale(double scale) { this.zoomLevel = FastMath.log2((int) scale); this.scale = scale; return this; } public void setPosition(GeoPoint geoPoint) { setPosition(geoPoint.getLatitude(), geoPoint.getLongitude()); } public void setPosition(double latitude, double longitude) { latitude = MercatorProjection.limitLatitude(latitude); longitude = MercatorProjection.limitLongitude(longitude); this.x = MercatorProjection.longitudeToX(longitude); this.y = MercatorProjection.latitudeToY(latitude); } public void copy(MapPosition other) { this.x = other.x; this.y = other.y; this.bearing = other.bearing; this.scale = other.scale; this.tilt = other.tilt; this.zoomLevel = other.zoomLevel; } public void set(double x, double y, double scale, float bearing, float tilt) { this.x = x; this.y = y; this.scale = scale; while (bearing > 180) bearing -= 360; while (bearing < -180) bearing += 360; this.bearing = bearing; this.tilt = tilt; this.zoomLevel = FastMath.log2((int) scale); } /** * @return scale relative to zoom-level. */ public double getZoomScale() { return scale / (1 << zoomLevel); } public GeoPoint getGeoPoint() { return new GeoPoint(MercatorProjection.toLatitude(y), MercatorProjection.toLongitude(x)); } public double getLatitude() { return MercatorProjection.toLatitude(y); } public double getLongitude() { return MercatorProjection.toLongitude(x); } public void setByBoundingBox(BoundingBox bbox, int viewWidth, int viewHeight) { double minx = MercatorProjection.longitudeToX(bbox.getMinLongitude()); double miny = MercatorProjection.latitudeToY(bbox.getMaxLatitude()); double dx = Math.abs(MercatorProjection.longitudeToX(bbox.getMaxLongitude()) - minx); double dy = Math.abs(MercatorProjection.latitudeToY(bbox.getMinLatitude()) - miny); double zx = viewWidth / (dx * Tile.SIZE); double zy = viewHeight / (dy * Tile.SIZE); scale = Math.min(zx, zy); x = minx + dx / 2; y = miny + dy / 2; bearing = 0; tilt = 0; } @Override public String toString() { return new StringBuilder() .append("[X:").append(x) .append(", Y:").append(y) .append(", Z:").append(zoomLevel) .append("] lat:") .append(MercatorProjection.toLatitude(y)) .append(", lon:") .append(MercatorProjection.toLongitude(x)) .toString(); } }