-use absolute x/y position and scale in MapPosition

- scale calculations look much nicer now, better always
   use 'double' unless you are sure about precision required
- finally got rid of zoomLevel relative coordinates
- cleanup MapPosition and MercatorProjection API functions
This commit is contained in:
Hannes Janetzek
2013-04-07 15:58:45 +02:00
parent a6a729244f
commit 8e01dce85e
29 changed files with 658 additions and 710 deletions

View File

@@ -19,7 +19,6 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tag;
import org.oscim.core.Tile;
import org.oscim.database.IMapDatabase;
@@ -443,6 +442,8 @@ public class MapDatabase implements IMapDatabase {
}
private void processBlocks(IMapDatabaseCallback mapDatabaseCallback,
QueryParameters queryParameters,
SubFileParameter subFileParameter) throws IOException {
@@ -527,10 +528,10 @@ public class MapDatabase implements IMapDatabase {
}
// calculate the top-left coordinates of the underlying tile
double tileLatitudeDeg = MercatorProjection.tileYToLatitude(
double tileLatitudeDeg = Projection.tileYToLatitude(
subFileParameter.boundaryTileTop + row,
subFileParameter.baseZoomLevel);
double tileLongitudeDeg = MercatorProjection.tileXToLongitude(
double tileLongitudeDeg = Projection.tileXToLongitude(
subFileParameter.boundaryTileLeft
+ column, subFileParameter.baseZoomLevel);
mTileLatitude = (int) (tileLatitudeDeg * 1000000);
@@ -590,9 +591,8 @@ public class MapDatabase implements IMapDatabase {
Tag[] tags = null;
Tag[] curTags;
long x = mTile.pixelX;
long y = mTile.pixelY + Tile.TILE_SIZE;
long x = mTile.tileX * Tile.TILE_SIZE;
long y = mTile.tileY * Tile.TILE_SIZE + Tile.TILE_SIZE;
long z = Tile.TILE_SIZE << mTile.zoomLevel;
long dx = (x - (z >> 1));
@@ -917,7 +917,7 @@ public class MapDatabase implements IMapDatabase {
int add = (hasName ? 1 : 0) + (hasHouseNr ? 1 : 0) + (hasRef ? 1 : 0);
int addTag = tags.length;
if (add > 0){
if (add > 0) {
curTags = new Tag[tags.length + add];
System.arraycopy(tags, 0, curTags, 0, tags.length);
}
@@ -1055,8 +1055,8 @@ public class MapDatabase implements IMapDatabase {
private boolean projectToTile(float[] coords, short[] indices) {
long x = mTile.pixelX;
long y = mTile.pixelY + Tile.TILE_SIZE;
long x = mTile.tileX * Tile.TILE_SIZE;
long y = mTile.tileY * Tile.TILE_SIZE + Tile.TILE_SIZE;
long z = Tile.TILE_SIZE << mTile.zoomLevel;
double divx, divy = 0;

View File

@@ -0,0 +1,108 @@
/*
* 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.database.mapfile;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tile;
public class Projection {
/**
* 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, int zoomLevel) {
return MercatorProjection.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, int zoomLevel) {
return MercatorProjection.pixelYToLatitude(tileY * Tile.TILE_SIZE, 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, int zoomLevel) {
return pixelYToTileY(MercatorProjection.latitudeToPixelY(latitude, zoomLevel), 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, int zoomLevel) {
return pixelXToTileX(MercatorProjection.longitudeToPixelX(longitude, zoomLevel), zoomLevel);
}
/**
* 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, int zoomLevel) {
return (int) Math.min(Math.max(pixelX / Tile.TILE_SIZE, 0),
Math.pow(2, zoomLevel) - 1);
}
/**
* 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, int zoomLevel) {
return (int) Math.min(Math.max(pixelY / Tile.TILE_SIZE, 0),
Math.pow(2, zoomLevel) - 1);
}
private Projection(){
}
}

View File

@@ -14,7 +14,7 @@
*/
package org.oscim.database.mapfile.header;
import org.oscim.core.MercatorProjection;
import org.oscim.database.mapfile.Projection;
/**
* Holds all parameters of a sub-file.
@@ -110,6 +110,7 @@ public class SubFileParameter {
*/
private final int hashCodeValue;
SubFileParameter(SubFileParameterBuilder subFileParameterBuilder) {
this.startAddress = subFileParameterBuilder.startAddress;
this.indexStartAddress = subFileParameterBuilder.indexStartAddress;
@@ -120,16 +121,16 @@ public class SubFileParameter {
this.hashCodeValue = calculateHashCode();
// calculate the XY numbers of the boundary tiles in this sub-file
this.boundaryTileBottom = MercatorProjection.latitudeToTileY(
this.boundaryTileBottom = Projection.latitudeToTileY(
subFileParameterBuilder.boundingBox.minLatitudeE6
/ COORDINATES_DIVISOR, this.baseZoomLevel);
this.boundaryTileLeft = MercatorProjection.longitudeToTileX(
this.boundaryTileLeft = Projection.longitudeToTileX(
subFileParameterBuilder.boundingBox.minLongitudeE6
/ COORDINATES_DIVISOR, this.baseZoomLevel);
this.boundaryTileTop = MercatorProjection.latitudeToTileY(
this.boundaryTileTop = Projection.latitudeToTileY(
subFileParameterBuilder.boundingBox.maxLatitudeE6
/ COORDINATES_DIVISOR, this.baseZoomLevel);
this.boundaryTileRight = MercatorProjection.longitudeToTileX(
this.boundaryTileRight = Projection.longitudeToTileX(
subFileParameterBuilder.boundingBox.maxLongitudeE6
/ COORDINATES_DIVISOR, this.baseZoomLevel);