switch package org.mapsforge -> org.oscim

This commit is contained in:
Hannes Janetzek
2012-09-12 00:33:39 +02:00
parent 489f07dd5d
commit e2da87d8e0
155 changed files with 548 additions and 535 deletions

View 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();
}
}

View 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;
}
}

View 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;
}
}

View 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();
}
}

View 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
View 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;
}
}

View 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;
}
}

View 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;
}
}