use MapPosition.scale: get rid of zoomLevel relative functions in MercatorProjection
This commit is contained in:
@@ -51,13 +51,13 @@ public final class MercatorProjection {
|
|||||||
* @param latitude
|
* @param latitude
|
||||||
* the latitude coordinate at which the resolution should be
|
* the latitude coordinate at which the resolution should be
|
||||||
* calculated.
|
* calculated.
|
||||||
* @param zoomLevel
|
* @param scale
|
||||||
* the zoom level at which the resolution should be calculated.
|
* the map scale at which the resolution should be calculated.
|
||||||
* @return the ground resolution at the given latitude and zoom level.
|
* @return the ground resolution at the given latitude and zoom level.
|
||||||
*/
|
*/
|
||||||
public static double calculateGroundResolution(double latitude, int zoomLevel) {
|
public static double calculateGroundResolution(double latitude, double scale) {
|
||||||
return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE
|
return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE
|
||||||
/ ((long) Tile.SIZE << zoomLevel);
|
/ (Tile.SIZE * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,11 +84,23 @@ public final class MercatorProjection {
|
|||||||
* @return the position .
|
* @return the position .
|
||||||
*/
|
*/
|
||||||
public static double longitudeToX(double longitude) {
|
public static double longitudeToX(double longitude) {
|
||||||
return (longitude + 180) / 360;
|
return (longitude + 180.0) / 360.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double toLongitude(double x) {
|
public static double toLongitude(double x) {
|
||||||
return 360 * (x - 0.5);
|
return 360.0 * (x - 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PointD project(GeoPoint p, PointD reuse) {
|
||||||
|
if (reuse == null)
|
||||||
|
reuse = new PointD();
|
||||||
|
|
||||||
|
reuse.x = ((p.longitudeE6 / 1E6) + 180.0) / 360.0;
|
||||||
|
|
||||||
|
double sinLatitude = Math.sin((p.latitudeE6 / 1E6) * (Math.PI / 180.0));
|
||||||
|
reuse.y = 0.5 - Math.log((1.0 + sinLatitude) / (1.0 - sinLatitude)) / (4.0 * Math.PI);
|
||||||
|
|
||||||
|
return reuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,65 +131,6 @@ public final class MercatorProjection {
|
|||||||
return longitude;
|
return longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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, int zoomLevel) {
|
|
||||||
return 360 * ((pixelX / ((long) Tile.SIZE << zoomLevel)) - 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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, int zoomLevel) {
|
|
||||||
return (longitude + 180) / 360 * ((long) Tile.SIZE << zoomLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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, int zoomLevel) {
|
|
||||||
double y = 0.5 - (pixelY / ((long) Tile.SIZE << zoomLevel));
|
|
||||||
return 90 - 360 * Math.atan(Math.exp(-y * (2 * Math.PI))) / Math.PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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, int zoomLevel) {
|
|
||||||
double sinLatitude = Math.sin(latitude * (Math.PI / 180));
|
|
||||||
return (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI))
|
|
||||||
* ((long) Tile.SIZE << zoomLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MercatorProjection() {
|
private MercatorProjection() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.database.mapfile;
|
package org.oscim.database.mapfile;
|
||||||
|
|
||||||
import org.oscim.core.MercatorProjection;
|
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
public class Projection {
|
public class Projection {
|
||||||
@@ -31,7 +30,7 @@ public class Projection {
|
|||||||
* @return the longitude value of the tile X number.
|
* @return the longitude value of the tile X number.
|
||||||
*/
|
*/
|
||||||
public static double tileXToLongitude(long tileX, int zoomLevel) {
|
public static double tileXToLongitude(long tileX, int zoomLevel) {
|
||||||
return MercatorProjection.pixelXToLongitude(tileX * Tile.SIZE, zoomLevel);
|
return pixelXToLongitude(tileX * Tile.SIZE, zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +44,7 @@ public class Projection {
|
|||||||
* @return the latitude value of the tile Y number.
|
* @return the latitude value of the tile Y number.
|
||||||
*/
|
*/
|
||||||
public static double tileYToLatitude(long tileY, int zoomLevel) {
|
public static double tileYToLatitude(long tileY, int zoomLevel) {
|
||||||
return MercatorProjection.pixelYToLatitude(tileY * Tile.SIZE, zoomLevel);
|
return pixelYToLatitude(tileY * Tile.SIZE, zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,7 +58,7 @@ public class Projection {
|
|||||||
* @return the tile Y number of the latitude value.
|
* @return the tile Y number of the latitude value.
|
||||||
*/
|
*/
|
||||||
public static long latitudeToTileY(double latitude, int zoomLevel) {
|
public static long latitudeToTileY(double latitude, int zoomLevel) {
|
||||||
return pixelYToTileY(MercatorProjection.latitudeToPixelY(latitude, zoomLevel), zoomLevel);
|
return pixelYToTileY(latitudeToPixelY(latitude, zoomLevel), zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,7 +72,7 @@ public class Projection {
|
|||||||
* @return the tile X number of the longitude value.
|
* @return the tile X number of the longitude value.
|
||||||
*/
|
*/
|
||||||
public static long longitudeToTileX(double longitude, int zoomLevel) {
|
public static long longitudeToTileX(double longitude, int zoomLevel) {
|
||||||
return pixelXToTileX(MercatorProjection.longitudeToPixelX(longitude, zoomLevel), zoomLevel);
|
return pixelXToTileX(longitudeToPixelX(longitude, zoomLevel), zoomLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,6 +101,65 @@ public class Projection {
|
|||||||
return (int) Math.min(Math.max(pixelY / Tile.SIZE, 0),
|
return (int) Math.min(Math.max(pixelY / Tile.SIZE, 0),
|
||||||
Math.pow(2, zoomLevel) - 1);
|
Math.pow(2, zoomLevel) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, int zoomLevel) {
|
||||||
|
return 360 * ((pixelX / ((long) Tile.SIZE << zoomLevel)) - 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, int zoomLevel) {
|
||||||
|
return (longitude + 180) / 360 * ((long) Tile.SIZE << zoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, int zoomLevel) {
|
||||||
|
double y = 0.5 - (pixelY / ((long) Tile.SIZE << zoomLevel));
|
||||||
|
return 90 - 360 * Math.atan(Math.exp(-y * (2 * Math.PI))) / Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, int zoomLevel) {
|
||||||
|
double sinLatitude = Math.sin(latitude * (Math.PI / 180));
|
||||||
|
return (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI))
|
||||||
|
* ((long) Tile.SIZE << zoomLevel);
|
||||||
|
}
|
||||||
private Projection(){
|
private Projection(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,14 @@ package org.oscim.overlay;
|
|||||||
// - and to make this work for multiple overlays
|
// - and to make this work for multiple overlays
|
||||||
// a global scenegraph is probably required.
|
// a global scenegraph is probably required.
|
||||||
|
|
||||||
import org.oscim.core.GeoPoint;
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
|
import org.oscim.core.PointD;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.overlay.OverlayItem.HotspotPlace;
|
import org.oscim.overlay.OverlayItem.HotspotPlace;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
import org.oscim.renderer.layer.SymbolLayer;
|
import org.oscim.renderer.layer.SymbolLayer;
|
||||||
import org.oscim.renderer.overlays.BasicOverlay;
|
import org.oscim.renderer.overlays.BasicOverlay;
|
||||||
import org.oscim.utils.FastMath;
|
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -73,8 +72,9 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
|
|
||||||
private int mSize;
|
private int mSize;
|
||||||
|
|
||||||
// pre-projected points to zoomlovel 18
|
// pre-projected points to zoomlevel 20
|
||||||
private static final byte MAX_ZOOM = 18;
|
private static final byte MAX_ZOOM = 20;
|
||||||
|
private final double MAX_SCALE;
|
||||||
|
|
||||||
class ItemOverlay extends BasicOverlay {
|
class ItemOverlay extends BasicOverlay {
|
||||||
|
|
||||||
@@ -97,12 +97,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
|
|
||||||
mUpdate = false;
|
mUpdate = false;
|
||||||
|
|
||||||
//int mx = (int) curPos.x;
|
int z = curPos.zoomLevel;
|
||||||
//int my = (int) curPos.y;
|
|
||||||
|
|
||||||
//int z = curPos.zoomLevel;
|
|
||||||
|
|
||||||
int z = FastMath.log2((int) curPos.scale);
|
|
||||||
int diff = MAX_ZOOM - z;
|
int diff = MAX_ZOOM - z;
|
||||||
|
|
||||||
int mx = (int) (curPos.x * (Tile.SIZE << z));
|
int mx = (int) (curPos.x * (Tile.SIZE << z));
|
||||||
@@ -177,14 +172,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
// updateMapPosition();
|
// updateMapPosition();
|
||||||
mMapPosition.copy(curPos);
|
mMapPosition.copy(curPos);
|
||||||
|
|
||||||
//mMapPosition.x = curPos.x;
|
// items are placed relative to zoomLevel
|
||||||
//mMapPosition.y = curPos.y;
|
|
||||||
//mMapPosition.zoomLevel = curPos.zoomLevel;
|
|
||||||
//mMapPosition.scale = curPos.scale;
|
|
||||||
//mMapPosition.angle = curPos.angle;
|
|
||||||
|
|
||||||
// items are placed relative to scale == 1
|
|
||||||
// mMapPosition.scale = 1;
|
|
||||||
mMapPosition.scale = 1 << z;
|
mMapPosition.scale = 1 << z;
|
||||||
|
|
||||||
layers.clear();
|
layers.clear();
|
||||||
@@ -251,8 +239,12 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
|
|
||||||
this.mDefaultMarker = pDefaultMarker;
|
this.mDefaultMarker = pDefaultMarker;
|
||||||
mLayer = new ItemOverlay(mapView);
|
mLayer = new ItemOverlay(mapView);
|
||||||
|
|
||||||
|
MAX_SCALE = (1 << MAX_ZOOM) * Tile.SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final PointD mMapPoint = new PointD();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to perform all processing on a new ItemizedOverlay.
|
* Utility method to perform all processing on a new ItemizedOverlay.
|
||||||
* Subclasses provide Items through the createItem(int) method. The subclass
|
* Subclasses provide Items through the createItem(int) method. The subclass
|
||||||
@@ -286,9 +278,11 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
it.item = createItem(a);
|
it.item = createItem(a);
|
||||||
|
|
||||||
// pre-project points
|
// pre-project points
|
||||||
GeoPoint p = it.item.mGeoPoint;
|
MercatorProjection.project(it.item.mGeoPoint, mMapPoint);
|
||||||
it.px = (int) MercatorProjection.longitudeToPixelX(p.getLongitude(), MAX_ZOOM);
|
it.px = (int) (mMapPoint.x * MAX_SCALE);
|
||||||
it.py = (int) MercatorProjection.latitudeToPixelY(p.getLatitude(), MAX_ZOOM);
|
it.py = (int) (mMapPoint.y * MAX_SCALE);
|
||||||
|
// it.px = (int) MercatorProjection.longitudeToPixelX(p.getLongitude(), MAX_ZOOM);
|
||||||
|
// it.py = (int) MercatorProjection.latitudeToPixelY(p.getLatitude(), MAX_ZOOM);
|
||||||
}
|
}
|
||||||
mUpdate = true;
|
mUpdate = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.util.List;
|
|||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
|
import org.oscim.core.PointD;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
import org.oscim.renderer.layer.Layer;
|
import org.oscim.renderer.layer.Layer;
|
||||||
@@ -48,10 +49,12 @@ public class PathOverlay extends Overlay {
|
|||||||
class RenderPath extends BasicOverlay {
|
class RenderPath extends BasicOverlay {
|
||||||
|
|
||||||
private static final byte MAX_ZOOM = 20;
|
private static final byte MAX_ZOOM = 20;
|
||||||
|
private final double MAX_SCALE;
|
||||||
private static final int MIN_DIST = 4;
|
private static final int MIN_DIST = 4;
|
||||||
|
|
||||||
// pre-projected points to zoomlovel 20
|
// pre-projected points to zoomlovel 20
|
||||||
private int[] mPreprojected;
|
private int[] mPreprojected;
|
||||||
|
private final PointD mMapPoint;
|
||||||
|
|
||||||
// projected points
|
// projected points
|
||||||
private float[] mPPoints;
|
private float[] mPPoints;
|
||||||
@@ -68,6 +71,8 @@ public class PathOverlay extends Overlay {
|
|||||||
mLine = new Line(Color.BLUE, 3.0f, Cap.BUTT);
|
mLine = new Line(Color.BLUE, 3.0f, Cap.BUTT);
|
||||||
mIndex = new short[1];
|
mIndex = new short[1];
|
||||||
mPPoints = new float[1];
|
mPPoints = new float[1];
|
||||||
|
mMapPoint = new PointD();
|
||||||
|
MAX_SCALE = (1 << MAX_ZOOM) * Tile.SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: this is called from GL-Thread. so check your syncs!
|
// note: this is called from GL-Thread. so check your syncs!
|
||||||
@@ -99,10 +104,9 @@ public class PathOverlay extends Overlay {
|
|||||||
|
|
||||||
for (int i = 0, j = 0; i < size; i++, j += 2) {
|
for (int i = 0, j = 0; i < size; i++, j += 2) {
|
||||||
GeoPoint p = geopoints.get(i);
|
GeoPoint p = geopoints.get(i);
|
||||||
points[j + 0] = (int) MercatorProjection.longitudeToPixelX(
|
MercatorProjection.project(p, mMapPoint);
|
||||||
p.getLongitude(), MAX_ZOOM);
|
points[j + 0] = (int) (mMapPoint.x * MAX_SCALE);
|
||||||
points[j + 1] = (int) MercatorProjection.latitudeToPixelY(
|
points[j + 1] = (int) (mMapPoint.y * MAX_SCALE);
|
||||||
p.getLatitude(), MAX_ZOOM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user