switch package org.mapsforge -> org.oscim
This commit is contained in:
182
src/org/oscim/core/BoundingBox.java
Normal file
182
src/org/oscim/core/BoundingBox.java
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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 java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A BoundingBox represents an immutable set of two latitude and two longitude coordinates.
|
||||
*/
|
||||
public class BoundingBox implements Serializable {
|
||||
/**
|
||||
* Conversion factor from degrees to microdegrees.
|
||||
*/
|
||||
private static final double CONVERSION_FACTOR = 1000000d;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static boolean isBetween(int number, int min, int max) {
|
||||
return min <= number && number <= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum latitude value of this BoundingBox in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public final int maxLatitudeE6;
|
||||
|
||||
/**
|
||||
* The maximum longitude value of this BoundingBox in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public final int maxLongitudeE6;
|
||||
|
||||
/**
|
||||
* The minimum latitude value of this BoundingBox in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public final int minLatitudeE6;
|
||||
|
||||
/**
|
||||
* The minimum longitude value of this BoundingBox in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public final int minLongitudeE6;
|
||||
|
||||
/**
|
||||
* The hash code of this object.
|
||||
*/
|
||||
private transient int hashCodeValue;
|
||||
|
||||
/**
|
||||
* @param minLatitudeE6
|
||||
* the minimum latitude in microdegrees (degrees * 10^6).
|
||||
* @param minLongitudeE6
|
||||
* the minimum longitude in microdegrees (degrees * 10^6).
|
||||
* @param maxLatitudeE6
|
||||
* the maximum latitude in microdegrees (degrees * 10^6).
|
||||
* @param maxLongitudeE6
|
||||
* the maximum longitude in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public BoundingBox(int minLatitudeE6, int minLongitudeE6, int maxLatitudeE6, int maxLongitudeE6) {
|
||||
this.minLatitudeE6 = minLatitudeE6;
|
||||
this.minLongitudeE6 = minLongitudeE6;
|
||||
this.maxLatitudeE6 = maxLatitudeE6;
|
||||
this.maxLongitudeE6 = maxLongitudeE6;
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param geoPoint
|
||||
* the point whose coordinates should be checked.
|
||||
* @return true if this BoundingBox contains the given GeoPoint, false otherwise.
|
||||
*/
|
||||
public boolean contains(GeoPoint geoPoint) {
|
||||
return isBetween(geoPoint.latitudeE6, this.minLatitudeE6, this.maxLatitudeE6)
|
||||
&& isBetween(geoPoint.longitudeE6, this.minLongitudeE6, this.maxLongitudeE6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
} else if (!(obj instanceof BoundingBox)) {
|
||||
return false;
|
||||
}
|
||||
BoundingBox other = (BoundingBox) obj;
|
||||
if (this.maxLatitudeE6 != other.maxLatitudeE6) {
|
||||
return false;
|
||||
} else if (this.maxLongitudeE6 != other.maxLongitudeE6) {
|
||||
return false;
|
||||
} else if (this.minLatitudeE6 != other.minLatitudeE6) {
|
||||
return false;
|
||||
} else if (this.minLongitudeE6 != other.minLongitudeE6) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the GeoPoint at the horizontal and vertical center of this BoundingBox.
|
||||
*/
|
||||
public GeoPoint getCenterPoint() {
|
||||
int latitudeOffset = (this.maxLatitudeE6 - this.minLatitudeE6) / 2;
|
||||
int longitudeOffset = (this.maxLongitudeE6 - this.minLongitudeE6) / 2;
|
||||
return new GeoPoint(this.minLatitudeE6 + latitudeOffset, this.minLongitudeE6 + longitudeOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum latitude value of this BoundingBox in degrees.
|
||||
*/
|
||||
public double getMaxLatitude() {
|
||||
return this.maxLatitudeE6 / CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum longitude value of this BoundingBox in degrees.
|
||||
*/
|
||||
public double getMaxLongitude() {
|
||||
return this.maxLongitudeE6 / CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum latitude value of this BoundingBox in degrees.
|
||||
*/
|
||||
public double getMinLatitude() {
|
||||
return this.minLatitudeE6 / CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum longitude value of this BoundingBox in degrees.
|
||||
*/
|
||||
public double getMinLongitude() {
|
||||
return this.minLongitudeE6 / CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hashCodeValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("BoundingBox [minLatitudeE6=");
|
||||
stringBuilder.append(this.minLatitudeE6);
|
||||
stringBuilder.append(", minLongitudeE6=");
|
||||
stringBuilder.append(this.minLongitudeE6);
|
||||
stringBuilder.append(", maxLatitudeE6=");
|
||||
stringBuilder.append(this.maxLatitudeE6);
|
||||
stringBuilder.append(", maxLongitudeE6=");
|
||||
stringBuilder.append(this.maxLongitudeE6);
|
||||
stringBuilder.append("]");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hash code of this object.
|
||||
*/
|
||||
private int calculateHashCode() {
|
||||
int result = 7;
|
||||
result = 31 * result + this.maxLatitudeE6;
|
||||
result = 31 * result + this.maxLongitudeE6;
|
||||
result = 31 * result + this.minLatitudeE6;
|
||||
result = 31 * result + this.minLongitudeE6;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
||||
objectInputStream.defaultReadObject();
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
}
|
||||
}
|
||||
139
src/org/oscim/core/GeoPoint.java
Normal file
139
src/org/oscim/core/GeoPoint.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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;
|
||||
|
||||
|
||||
/**
|
||||
* A GeoPoint represents an immutable pair of latitude and longitude coordinates.
|
||||
*/
|
||||
public class GeoPoint implements Comparable<GeoPoint> {
|
||||
/**
|
||||
* Conversion factor from degrees to microdegrees.
|
||||
*/
|
||||
private static final double CONVERSION_FACTOR = 1000000d;
|
||||
|
||||
/**
|
||||
* The latitude value of this GeoPoint in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public final int latitudeE6;
|
||||
|
||||
/**
|
||||
* The longitude value of this GeoPoint in microdegrees (degrees * 10^6).
|
||||
*/
|
||||
public final int longitudeE6;
|
||||
|
||||
/**
|
||||
* The hash code of this object.
|
||||
*/
|
||||
private int hashCodeValue = 0;
|
||||
|
||||
/**
|
||||
* @param latitude
|
||||
* the latitude in degrees, will be limited to the possible latitude range.
|
||||
* @param longitude
|
||||
* the longitude in degrees, will be limited to the possible longitude range.
|
||||
*/
|
||||
public GeoPoint(double latitude, double longitude) {
|
||||
double limitLatitude = MercatorProjection.limitLatitude(latitude);
|
||||
this.latitudeE6 = (int) (limitLatitude * CONVERSION_FACTOR);
|
||||
|
||||
double limitLongitude = MercatorProjection.limitLongitude(longitude);
|
||||
this.longitudeE6 = (int) (limitLongitude * CONVERSION_FACTOR);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param latitudeE6
|
||||
* the latitude in microdegrees (degrees * 10^6), will be limited to the possible latitude range.
|
||||
* @param longitudeE6
|
||||
* the longitude in microdegrees (degrees * 10^6), will be limited to the possible longitude range.
|
||||
*/
|
||||
public GeoPoint(int latitudeE6, int longitudeE6) {
|
||||
this(latitudeE6 / CONVERSION_FACTOR, longitudeE6 / CONVERSION_FACTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GeoPoint geoPoint) {
|
||||
if (this.longitudeE6 > geoPoint.longitudeE6) {
|
||||
return 1;
|
||||
} else if (this.longitudeE6 < geoPoint.longitudeE6) {
|
||||
return -1;
|
||||
} else if (this.latitudeE6 > geoPoint.latitudeE6) {
|
||||
return 1;
|
||||
} else if (this.latitudeE6 < geoPoint.latitudeE6) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
} else if (!(obj instanceof GeoPoint)) {
|
||||
return false;
|
||||
}
|
||||
GeoPoint other = (GeoPoint) obj;
|
||||
if (this.latitudeE6 != other.latitudeE6) {
|
||||
return false;
|
||||
} else if (this.longitudeE6 != other.longitudeE6) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the latitude value of this GeoPoint in degrees.
|
||||
*/
|
||||
public double getLatitude() {
|
||||
return this.latitudeE6 / CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the longitude value of this GeoPoint in degrees.
|
||||
*/
|
||||
public double getLongitude() {
|
||||
return this.longitudeE6 / CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (this.hashCodeValue == 0)
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
|
||||
return this.hashCodeValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("GeoPoint [latitudeE6=");
|
||||
stringBuilder.append(this.latitudeE6);
|
||||
stringBuilder.append(", longitudeE6=");
|
||||
stringBuilder.append(this.longitudeE6);
|
||||
stringBuilder.append("]");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hash code of this object.
|
||||
*/
|
||||
private int calculateHashCode() {
|
||||
int result = 7;
|
||||
result = 31 * result + this.latitudeE6;
|
||||
result = 31 * result + this.longitudeE6;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
57
src/org/oscim/core/LRUCache.java
Normal file
57
src/org/oscim/core/LRUCache.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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 java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An LRUCache with a fixed size and an access-order policy. Old mappings are automatically removed from the cache when
|
||||
* new mappings are added. This implementation uses an {@link LinkedHashMap} internally.
|
||||
*
|
||||
* @param <K>
|
||||
* the type of the map key, see {@link Map}.
|
||||
* @param <V>
|
||||
* the type of the map value, see {@link Map}.
|
||||
*/
|
||||
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
|
||||
private static final float LOAD_FACTOR = 0.6f;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static int calculateInitialCapacity(int capacity) {
|
||||
if (capacity < 0) {
|
||||
throw new IllegalArgumentException("capacity must not be negative: " + capacity);
|
||||
}
|
||||
return (int) (capacity / LOAD_FACTOR) + 2;
|
||||
}
|
||||
|
||||
private final int capacity;
|
||||
|
||||
/**
|
||||
* @param capacity
|
||||
* the maximum capacity of this cache.
|
||||
* @throws IllegalArgumentException
|
||||
* if the capacity is negative.
|
||||
*/
|
||||
public LRUCache(int capacity) {
|
||||
super(calculateInitialCapacity(capacity), LOAD_FACTOR, true);
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
||||
return size() > this.capacity;
|
||||
}
|
||||
}
|
||||
97
src/org/oscim/core/MapPosition.java
Normal file
97
src/org/oscim/core/MapPosition.java
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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;
|
||||
|
||||
/**
|
||||
* A MapPosition represents an immutable pair of {@link GeoPoint} and zoom level.
|
||||
*/
|
||||
public class MapPosition {
|
||||
|
||||
/**
|
||||
* The map position.
|
||||
*/
|
||||
// public final GeoPoint geoPoint;
|
||||
public final double lon;
|
||||
public final double lat;
|
||||
|
||||
/**
|
||||
* The zoom level.
|
||||
*/
|
||||
public final byte zoomLevel;
|
||||
|
||||
/**
|
||||
* 1.0 - 2.0 scale of current zoomlevel
|
||||
*/
|
||||
public final float scale;
|
||||
|
||||
public final float angle;
|
||||
|
||||
public final double x;
|
||||
public final double y;
|
||||
|
||||
public MapPosition() {
|
||||
this.zoomLevel = (byte) 1;
|
||||
this.scale = 1;
|
||||
this.lat = 0;
|
||||
this.lon = 0;
|
||||
this.angle = 0;
|
||||
this.x = MercatorProjection.longitudeToPixelX(this.lon, zoomLevel);
|
||||
this.y = MercatorProjection.latitudeToPixelY(this.lat, zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param geoPoint
|
||||
* the map position.
|
||||
* @param zoomLevel
|
||||
* the zoom level.
|
||||
* @param scale
|
||||
* ...
|
||||
*/
|
||||
public MapPosition(GeoPoint geoPoint, byte zoomLevel, float scale) {
|
||||
// this.geoPoint = geoPoint;
|
||||
this.zoomLevel = zoomLevel;
|
||||
this.scale = scale;
|
||||
this.lat = geoPoint.getLatitude();
|
||||
this.lon = geoPoint.getLongitude();
|
||||
this.angle = 0;
|
||||
this.x = MercatorProjection.longitudeToPixelX(this.lon, zoomLevel);
|
||||
this.y = MercatorProjection.latitudeToPixelY(this.lat, zoomLevel);
|
||||
}
|
||||
|
||||
public MapPosition(double latitude, double longitude, byte zoomLevel, float scale,
|
||||
float angle) {
|
||||
this.zoomLevel = zoomLevel;
|
||||
this.scale = scale;
|
||||
this.lat = latitude;
|
||||
this.lon = longitude;
|
||||
this.angle = angle;
|
||||
this.x = MercatorProjection.longitudeToPixelX(longitude, zoomLevel);
|
||||
this.y = MercatorProjection.latitudeToPixelY(latitude, zoomLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("MapPosition [geoPoint=");
|
||||
builder.append("lat");
|
||||
builder.append(this.lat);
|
||||
builder.append("lon");
|
||||
builder.append(this.lon);
|
||||
builder.append(", zoomLevel=");
|
||||
builder.append(this.zoomLevel);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
237
src/org/oscim/core/MercatorProjection.java
Normal file
237
src/org/oscim/core/MercatorProjection.java
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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;
|
||||
|
||||
/**
|
||||
* An implementation of the spherical Mercator projection.
|
||||
*/
|
||||
public final class MercatorProjection {
|
||||
/**
|
||||
* The circumference of the earth at the equator in meters.
|
||||
*/
|
||||
public static final double EARTH_CIRCUMFERENCE = 40075016.686;
|
||||
|
||||
/**
|
||||
* Maximum possible latitude coordinate of the map.
|
||||
*/
|
||||
public static final double LATITUDE_MAX = 85.05112877980659;
|
||||
|
||||
/**
|
||||
* Minimum possible latitude coordinate of the map.
|
||||
*/
|
||||
public static final double LATITUDE_MIN = -LATITUDE_MAX;
|
||||
|
||||
/**
|
||||
* Maximum possible longitude coordinate of the map.
|
||||
*/
|
||||
public static final double LONGITUDE_MAX = 180;
|
||||
|
||||
/**
|
||||
* Minimum possible longitude coordinate of the map.
|
||||
*/
|
||||
public static final double LONGITUDE_MIN = -LONGITUDE_MAX;
|
||||
|
||||
/**
|
||||
* Calculates the distance on the ground that is represented by a single pixel on the map.
|
||||
*
|
||||
* @param latitude
|
||||
* the latitude coordinate at which the resolution should be calculated.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the resolution should be calculated.
|
||||
* @return the ground resolution at the given latitude and zoom level.
|
||||
*/
|
||||
public static double calculateGroundResolution(double latitude, byte zoomLevel) {
|
||||
return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE
|
||||
/ ((long) Tile.TILE_SIZE << zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a latitude coordinate (in degrees) to a pixel Y coordinate at a certain zoom level.
|
||||
*
|
||||
* @param latitude
|
||||
* the latitude coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the pixel Y coordinate of the latitude value.
|
||||
*/
|
||||
public static double latitudeToPixelY(double latitude, byte zoomLevel) {
|
||||
double sinLatitude = Math.sin(latitude * (Math.PI / 180));
|
||||
return (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI))
|
||||
* ((long) Tile.TILE_SIZE << zoomLevel);
|
||||
}
|
||||
|
||||
public static double latitudeToPixelY(MapPosition mapPosition) {
|
||||
double sinLatitude = Math.sin(mapPosition.lat * (Math.PI / 180));
|
||||
return (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI))
|
||||
* ((long) Tile.TILE_SIZE << mapPosition.zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a latitude coordinate (in degrees) to a tile Y number at a certain zoom level.
|
||||
*
|
||||
* @param latitude
|
||||
* the latitude coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the tile Y number of the latitude value.
|
||||
*/
|
||||
public static long latitudeToTileY(double latitude, byte zoomLevel) {
|
||||
return pixelYToTileY(latitudeToPixelY(latitude, zoomLevel), zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param latitude
|
||||
* the latitude value which should be checked.
|
||||
* @return the given latitude value, limited to the possible latitude range.
|
||||
*/
|
||||
public static double limitLatitude(double latitude) {
|
||||
return Math.max(Math.min(latitude, LATITUDE_MAX), LATITUDE_MIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param longitude
|
||||
* the longitude value which should be checked.
|
||||
* @return the given longitude value, limited to the possible longitude range.
|
||||
*/
|
||||
public static double limitLongitude(double longitude) {
|
||||
return Math.max(Math.min(longitude, LONGITUDE_MAX), LONGITUDE_MIN);
|
||||
}
|
||||
|
||||
public static double wrapLongitude(double longitude) {
|
||||
if (longitude < -180)
|
||||
return Math.max(Math.min(360 + longitude, LONGITUDE_MAX), LONGITUDE_MIN);
|
||||
else if (longitude > 180)
|
||||
return Math.max(Math.min(longitude - 360, LONGITUDE_MAX), LONGITUDE_MIN);
|
||||
|
||||
return longitude;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a longitude coordinate (in degrees) to a pixel X coordinate at a certain zoom level.
|
||||
*
|
||||
* @param longitude
|
||||
* the longitude coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the pixel X coordinate of the longitude value.
|
||||
*/
|
||||
public static double longitudeToPixelX(double longitude, byte zoomLevel) {
|
||||
return (longitude + 180) / 360 * ((long) Tile.TILE_SIZE << zoomLevel);
|
||||
}
|
||||
|
||||
public static double longitudeToPixelX(MapPosition mapPosition) {
|
||||
return (mapPosition.lon + 180) / 360
|
||||
* ((long) Tile.TILE_SIZE << mapPosition.zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a longitude coordinate (in degrees) to the tile X number at a certain zoom level.
|
||||
*
|
||||
* @param longitude
|
||||
* the longitude coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the tile X number of the longitude value.
|
||||
*/
|
||||
public static long longitudeToTileX(double longitude, byte zoomLevel) {
|
||||
return pixelXToTileX(longitudeToPixelX(longitude, zoomLevel), zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a pixel X coordinate at a certain zoom level to a longitude coordinate.
|
||||
*
|
||||
* @param pixelX
|
||||
* the pixel X coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the longitude value of the pixel X coordinate.
|
||||
*/
|
||||
public static double pixelXToLongitude(double pixelX, byte zoomLevel) {
|
||||
return 360 * ((pixelX / ((long) Tile.TILE_SIZE << zoomLevel)) - 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a pixel X coordinate to the tile X number.
|
||||
*
|
||||
* @param pixelX
|
||||
* the pixel X coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the tile X number.
|
||||
*/
|
||||
public static int pixelXToTileX(double pixelX, byte zoomLevel) {
|
||||
return (int) Math.min(Math.max(pixelX / Tile.TILE_SIZE, 0),
|
||||
Math.pow(2, zoomLevel) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a pixel Y coordinate at a certain zoom level to a latitude coordinate.
|
||||
*
|
||||
* @param pixelY
|
||||
* the pixel Y coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the latitude value of the pixel Y coordinate.
|
||||
*/
|
||||
public static double pixelYToLatitude(double pixelY, byte zoomLevel) {
|
||||
double y = 0.5 - (pixelY / ((long) Tile.TILE_SIZE << zoomLevel));
|
||||
return 90 - 360 * Math.atan(Math.exp(-y * (2 * Math.PI))) / Math.PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a pixel Y coordinate to the tile Y number.
|
||||
*
|
||||
* @param pixelY
|
||||
* the pixel Y coordinate that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the coordinate should be converted.
|
||||
* @return the tile Y number.
|
||||
*/
|
||||
public static int pixelYToTileY(double pixelY, byte zoomLevel) {
|
||||
return (int) Math.min(Math.max(pixelY / Tile.TILE_SIZE, 0),
|
||||
Math.pow(2, zoomLevel) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a tile X number at a certain zoom level to a longitude coordinate.
|
||||
*
|
||||
* @param tileX
|
||||
* the tile X number that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the number should be converted.
|
||||
* @return the longitude value of the tile X number.
|
||||
*/
|
||||
public static double tileXToLongitude(long tileX, byte zoomLevel) {
|
||||
return pixelXToLongitude(tileX * Tile.TILE_SIZE, zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a tile Y number at a certain zoom level to a latitude coordinate.
|
||||
*
|
||||
* @param tileY
|
||||
* the tile Y number that should be converted.
|
||||
* @param zoomLevel
|
||||
* the zoom level at which the number should be converted.
|
||||
* @return the latitude value of the tile Y number.
|
||||
*/
|
||||
public static double tileYToLatitude(long tileY, byte zoomLevel) {
|
||||
return pixelYToLatitude(tileY * Tile.TILE_SIZE, zoomLevel);
|
||||
}
|
||||
|
||||
private MercatorProjection() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
153
src/org/oscim/core/Tag.java
Normal file
153
src/org/oscim/core/Tag.java
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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;
|
||||
|
||||
/**
|
||||
* A tag represents an immutable key-value pair.
|
||||
*/
|
||||
public class Tag {
|
||||
private static final char KEY_VALUE_SEPARATOR = '=';
|
||||
/**
|
||||
* The key of the house number OpenStreetMap tag.
|
||||
*/
|
||||
public static final String TAG_KEY_HOUSE_NUMBER = "addr:housenumber";
|
||||
|
||||
/**
|
||||
* The key of the name OpenStreetMap tag.
|
||||
*/
|
||||
public static final String TAG_KEY_NAME = "name";
|
||||
|
||||
/**
|
||||
* The key of the reference OpenStreetMap tag.
|
||||
*/
|
||||
public static final String TAG_KEY_REF = "ref";
|
||||
|
||||
/**
|
||||
* The key of the elevation OpenStreetMap tag.
|
||||
*/
|
||||
public static final String TAG_KEY_ELE = "ele";
|
||||
|
||||
/**
|
||||
* The key of this tag.
|
||||
*/
|
||||
public final String key;
|
||||
|
||||
/**
|
||||
* The value of this tag.
|
||||
*/
|
||||
public String value;
|
||||
|
||||
private transient int hashCodeValue = 0;
|
||||
|
||||
/**
|
||||
* @param tag
|
||||
* the textual representation of the tag.
|
||||
*/
|
||||
|
||||
public Tag(String tag) {
|
||||
int splitPosition = tag.indexOf(KEY_VALUE_SEPARATOR);
|
||||
if (splitPosition < 0) {
|
||||
System.out.println("TAG:" + tag);
|
||||
}
|
||||
this.key = tag.substring(0, splitPosition).intern();
|
||||
this.value = tag.substring(splitPosition + 1).intern();
|
||||
}
|
||||
|
||||
public Tag(String tag, boolean hashValue) {
|
||||
int splitPosition = tag.indexOf(KEY_VALUE_SEPARATOR);
|
||||
if (splitPosition < 0) {
|
||||
System.out.println("TAG:" + tag);
|
||||
}
|
||||
this.key = tag.substring(0, splitPosition).intern();
|
||||
if (!hashValue)
|
||||
this.value = tag.substring(splitPosition + 1);
|
||||
else
|
||||
this.value = tag.substring(splitPosition + 1).intern();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* the key of the tag.
|
||||
* @param value
|
||||
* the value of the tag.
|
||||
*/
|
||||
public Tag(String key, String value) {
|
||||
this.key = (key == null ? null : key.intern());
|
||||
this.value = (value == null ? null : value.intern());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* the key of the tag.
|
||||
* @param value
|
||||
* the value of the tag.
|
||||
* @param intern
|
||||
* true when string should be intern()alized.
|
||||
*/
|
||||
public Tag(String key, String value, boolean intern) {
|
||||
if (intern) {
|
||||
this.key = (key == null ? null : key.intern());
|
||||
this.value = (value == null ? null : value.intern());
|
||||
}
|
||||
else {
|
||||
this.key = (key == null ? null : key);
|
||||
this.value = (value == null ? null : value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
} else if (!(obj instanceof Tag)) {
|
||||
return false;
|
||||
}
|
||||
Tag other = (Tag) obj;
|
||||
|
||||
if ((this.key == other.key) && (this.value == other.value))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (this.hashCodeValue == 0)
|
||||
this.hashCodeValue = calculateHashCode();
|
||||
|
||||
return this.hashCodeValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("Tag [key=");
|
||||
stringBuilder.append(this.key);
|
||||
stringBuilder.append(", value=");
|
||||
stringBuilder.append(this.value);
|
||||
stringBuilder.append("]");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hash code of this object.
|
||||
*/
|
||||
private int calculateHashCode() {
|
||||
int result = 7;
|
||||
result = 31 * result + ((this.key == null) ? 0 : this.key.hashCode());
|
||||
result = 31 * result + ((this.value == null) ? 0 : this.value.hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
111
src/org/oscim/core/Tile.java
Normal file
111
src/org/oscim/core/Tile.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.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;
|
||||
|
||||
/**
|
||||
* A tile represents a rectangular part of the world map. All tiles can be identified by their X and Y number together
|
||||
* with their zoom level. The actual area that a tile covers on a map depends on the underlying map projection.
|
||||
*/
|
||||
public class Tile {
|
||||
|
||||
/**
|
||||
* Width and height of a map tile in pixel.
|
||||
*/
|
||||
public static int TILE_SIZE = 256;
|
||||
|
||||
/**
|
||||
* The X number of this tile.
|
||||
*/
|
||||
public final int tileX;
|
||||
|
||||
/**
|
||||
* The Y number of this tile.
|
||||
*/
|
||||
public final int tileY;
|
||||
|
||||
/**
|
||||
* The Zoom level of this tile.
|
||||
*/
|
||||
public final byte zoomLevel;
|
||||
|
||||
/**
|
||||
* the pixel X coordinate of the upper left corner of this tile.
|
||||
*/
|
||||
public final long pixelX;
|
||||
/**
|
||||
* the pixel Y coordinate of the upper left corner of this tile.
|
||||
*/
|
||||
public final long pixelY;
|
||||
|
||||
/**
|
||||
* @param tileX
|
||||
* the X number of the tile.
|
||||
* @param tileY
|
||||
* the Y number of the tile.
|
||||
* @param zoomLevel
|
||||
* the zoom level of the tile.
|
||||
*/
|
||||
public Tile(int tileX, int tileY, byte zoomLevel) {
|
||||
this.tileX = tileX;
|
||||
this.tileY = tileY;
|
||||
this.pixelX = this.tileX * TILE_SIZE;
|
||||
this.pixelY = this.tileY * TILE_SIZE;
|
||||
this.zoomLevel = zoomLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("Tile [tileX=");
|
||||
stringBuilder.append(this.tileX);
|
||||
stringBuilder.append(", tileY=");
|
||||
stringBuilder.append(this.tileY);
|
||||
stringBuilder.append(", zoomLevel=");
|
||||
stringBuilder.append(this.zoomLevel);
|
||||
stringBuilder.append("]");
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof Tile))
|
||||
return false;
|
||||
|
||||
Tile o = (Tile) obj;
|
||||
|
||||
if (o.tileX == this.tileX && o.tileY == this.tileY
|
||||
&& o.zoomLevel == this.zoomLevel)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int mHash = 0;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (mHash == 0) {
|
||||
int result = 7;
|
||||
result = 31 * result + this.tileX;
|
||||
result = 31 * result + this.tileY;
|
||||
result = 31 * result + this.zoomLevel;
|
||||
mHash = result;
|
||||
}
|
||||
return mHash;
|
||||
}
|
||||
}
|
||||
130
src/org/oscim/core/WebMercator.java
Normal file
130
src/org/oscim/core/WebMercator.java
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General 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 License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oscim.core;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class WebMercator {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static final String NAME = "SphericalMercator";
|
||||
|
||||
private static final double f900913 = 20037508.342789244;
|
||||
private static final double f900913_2 = 20037508.342789244 * 2;
|
||||
|
||||
/**
|
||||
* @param lon
|
||||
* ...
|
||||
* @param z
|
||||
* ...
|
||||
* @param offset
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public static float sphericalMercatorToPixelX(float lon, long z, long offset) {
|
||||
return (float) (((lon + f900913) / f900913_2) * z - offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lat
|
||||
* ...
|
||||
* @param z
|
||||
* ...
|
||||
* @param offset
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public static float sphericalMercatorToPixelY(float lat, long z, long offset) {
|
||||
return (float) (((lat + f900913) / f900913_2) * z
|
||||
- (z - offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pixelY
|
||||
* ...
|
||||
* @param z
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public static double PixelYtoSphericalMercator(long pixelY, byte z) {
|
||||
long half = (Tile.TILE_SIZE << z) >> 1;
|
||||
return ((half - pixelY) / (double) half) * f900913;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pixelX
|
||||
* ...
|
||||
* @param z
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public static double PixelXtoSphericalMercator(long pixelX, byte z) {
|
||||
long half = (Tile.TILE_SIZE << z) >> 1;
|
||||
return ((pixelX - half) / (double) half) * f900913;
|
||||
}
|
||||
|
||||
private static double radius = 6378137;
|
||||
private static double D2R = Math.PI / 180;
|
||||
private static double HALF_PI = Math.PI / 2;
|
||||
|
||||
/**
|
||||
* from http://pauldendulk.com/2011/04/projecting-from-wgs84-to.html
|
||||
*
|
||||
* @param lon
|
||||
* ...
|
||||
* @param lat
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public static float[] fromLonLat(double lon, double lat)
|
||||
{
|
||||
double lonRadians = (D2R * lon);
|
||||
double latRadians = (D2R * lat);
|
||||
|
||||
double x = radius * lonRadians;
|
||||
double y = radius * Math.log(Math.tan(Math.PI * 0.25 + latRadians * 0.5));
|
||||
|
||||
float[] result = { (float) x, (float) y };
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* from http://pauldendulk.com/2011/04/projecting-from-wgs84-to.html
|
||||
*
|
||||
* @param x
|
||||
* ...
|
||||
* @param y
|
||||
* ...
|
||||
* @return ...
|
||||
*/
|
||||
public static float[] toLonLat(double x, double y)
|
||||
{
|
||||
double ts;
|
||||
ts = Math.exp(-y / (radius));
|
||||
double latRadians = HALF_PI - 2 * Math.atan(ts);
|
||||
|
||||
double lonRadians = x / (radius);
|
||||
|
||||
double lon = (lonRadians / D2R);
|
||||
double lat = (latRadians / D2R);
|
||||
|
||||
float[] result = { (float) lon, (float) lat };
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user