/** * 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 int longitudeToTileX(double longitude, byte zoomLevel) { return pixelXToTileX(longitudeToPixelX(longitude, zoomLevel, DUMMY_TILE_SIZE), zoomLevel, DUMMY_TILE_SIZE); }
@Test public void longitudeToPixelXTest() { for (int tileSize : TILE_SIZES) { for (byte zoomLevel = ZOOM_LEVEL_MIN; zoomLevel <= ZOOM_LEVEL_MAX; ++zoomLevel) { long mapSize = MercatorProjection.getMapSize(zoomLevel, tileSize); double pixelX = MercatorProjection.longitudeToPixelX(LatLongUtils.LONGITUDE_MIN, mapSize); Assert.assertEquals(0, pixelX, 0); pixelX = MercatorProjection.longitudeToPixelXWithScaleFactor(LatLongUtils.LONGITUDE_MIN, MercatorProjection.zoomLevelToScaleFactor(zoomLevel), tileSize); Assert.assertEquals(0, pixelX, 0); pixelX = MercatorProjection.longitudeToPixelX(0, mapSize); Assert.assertEquals((float) mapSize / 2, pixelX, 0); mapSize = MercatorProjection.getMapSizeWithScaleFactor(MercatorProjection.zoomLevelToScaleFactor(zoomLevel), tileSize); pixelX = MercatorProjection.longitudeToPixelXWithScaleFactor(0, MercatorProjection.zoomLevelToScaleFactor(zoomLevel), tileSize); Assert.assertEquals((float) mapSize / 2, pixelX, 0); pixelX = MercatorProjection.longitudeToPixelX(LatLongUtils.LONGITUDE_MAX, mapSize); Assert.assertEquals(mapSize, pixelX, 0); pixelX = MercatorProjection.longitudeToPixelXWithScaleFactor(LatLongUtils.LONGITUDE_MAX, MercatorProjection.zoomLevelToScaleFactor(zoomLevel), tileSize); Assert.assertEquals(mapSize, pixelX, 0); } } }
private void doWorkMove() { if (moveSteps == 0) return; double currentPixelX = MercatorProjection.longitudeToPixelX(longitude, mapSize); double currentPixelY = MercatorProjection.latitudeToPixelY(latitude, mapSize); double stepSizeX = Math.abs(targetPixelX - currentPixelX) / moveSteps; double stepSizeY = Math.abs(targetPixelY - currentPixelY) / moveSteps; double signX = Math.signum(currentPixelX - targetPixelX); double signY = Math.signum(currentPixelY - targetPixelY); --moveSteps; moveCenter(stepSizeX * signX, stepSizeY * signY); }
public static Point getPixel(LatLong latLong, long mapSize) { double pixelX = MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize); double pixelY = MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize); return new Point(pixelX, pixelY); }
public static Point getTopLeftPoint(MapPosition mapPosition, Dimension canvasDimension, int tileSize) { LatLong centerPoint = mapPosition.latLong; int halfCanvasWidth = canvasDimension.width / 2; int halfCanvasHeight = canvasDimension.height / 2; long mapSize = MercatorProjection.getMapSize(mapPosition.zoomLevel, tileSize); double pixelX = Math.round(MercatorProjection.longitudeToPixelX(centerPoint.longitude, mapSize)); double pixelY = Math.round(MercatorProjection.latitudeToPixelY(centerPoint.latitude, mapSize)); return new Point((long) pixelX - halfCanvasWidth, (long) pixelY - halfCanvasHeight); }
/** * Calculates the absolute pixel position for a map size and tile size relative to origin * * @param latLong the geographic position. * @param mapSize precomputed size of map. * @return the relative pixel position to the origin values (e.g. for a tile) */ public static Point getPixelRelative(LatLong latLong, long mapSize, double x, double y) { double pixelX = MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize) - x; double pixelY = MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize) - y; return new Point(pixelX, pixelY); }
/** * Calculates the zoom level that allows to display the {@link BoundingBox} on a view with the {@link Dimension} and * tile size. * * @param dimension the {@link Dimension} of the view. * @param boundingBox the {@link BoundingBox} to display. * @param tileSize the size of the tiles. * @return the zoom level that allows to display the {@link BoundingBox} on a view with the {@link Dimension} and * tile size. */ public static byte zoomForBounds(Dimension dimension, BoundingBox boundingBox, int tileSize) { long mapSize = MercatorProjection.getMapSize((byte) 0, tileSize); double pixelXMax = MercatorProjection.longitudeToPixelX(boundingBox.maxLongitude, mapSize); double pixelXMin = MercatorProjection.longitudeToPixelX(boundingBox.minLongitude, mapSize); double zoomX = -Math.log(Math.abs(pixelXMax - pixelXMin) / dimension.width) / Math.log(2); double pixelYMax = MercatorProjection.latitudeToPixelY(boundingBox.maxLatitude, mapSize); double pixelYMin = MercatorProjection.latitudeToPixelY(boundingBox.minLatitude, mapSize); double zoomY = -Math.log(Math.abs(pixelYMax - pixelYMin) / dimension.height) / Math.log(2); double zoom = Math.floor(Math.min(zoomX, zoomY)); if (zoom < 0) { return 0; } if (zoom > Byte.MAX_VALUE) { return Byte.MAX_VALUE; } return (byte) zoom; }
void startAnimationMove(LatLong latLong) { // TODO is this properly synchronized? mapSize = MercatorProjection.getMapSize(zoomLevel, displayModel.getTileSize()); targetPixelX = MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize); targetPixelY = MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize); moveSteps = DEFAULT_MOVE_STEPS; synchronized (this) { notify(); } }
private static double calculatePriority(Tile tile, MapPosition mapPosition, int tileSize) { double tileLatitude = MercatorProjection.tileYToLatitude(tile.tileY, tile.zoomLevel); double tileLongitude = MercatorProjection.tileXToLongitude(tile.tileX, tile.zoomLevel); int halfTileSize = tileSize / 2; long mapSize = MercatorProjection.getMapSize(mapPosition.zoomLevel, tileSize); double tilePixelX = MercatorProjection.longitudeToPixelX(tileLongitude, mapSize) + halfTileSize; double tilePixelY = MercatorProjection.latitudeToPixelY(tileLatitude, mapSize) + halfTileSize; LatLong latLong = mapPosition.latLong; double mapPixelX = MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize); double mapPixelY = MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize); double diffPixel = Math.hypot(tilePixelX - mapPixelX, tilePixelY - mapPixelY); int diffZoom = Math.abs(tile.zoomLevel - mapPosition.zoomLevel); return diffPixel + PENALTY_PER_ZOOM_LEVEL * tileSize * diffZoom; }
public static BoundingBox getBoundingBox(MapPosition mapPosition, Dimension canvasDimension, int tileSize) { long mapSize = MercatorProjection.getMapSize(mapPosition.zoomLevel, tileSize); double pixelX = MercatorProjection.longitudeToPixelX(mapPosition.latLong.longitude, mapSize); double pixelY = MercatorProjection.latitudeToPixelY(mapPosition.latLong.latitude, mapSize); int halfCanvasWidth = canvasDimension.width / 2; int halfCanvasHeight = canvasDimension.height / 2; double pixelXMin = Math.max(0, pixelX - halfCanvasWidth); double pixelYMin = Math.max(0, pixelY - halfCanvasHeight); double pixelXMax = Math.min(mapSize, pixelX + halfCanvasWidth); double pixelYMax = Math.min(mapSize, pixelY + halfCanvasHeight); double minLatitude = MercatorProjection.pixelYToLatitude(pixelYMax, mapSize); double minLongitude = MercatorProjection.pixelXToLongitude(pixelXMin, mapSize); double maxLatitude = MercatorProjection.pixelYToLatitude(pixelYMin, mapSize); double maxLongitude = MercatorProjection.pixelXToLongitude(pixelXMax, mapSize); return new BoundingBox(minLatitude, minLongitude, maxLatitude, maxLongitude); }
float x = (float) (MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize) - topLeftPoint.x); float y = (float) (MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize) - topLeftPoint.y); x = (float) (MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize) - topLeftPoint.x); y = (float) (MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize) - topLeftPoint.y);
/** * Moves the center position of the map by the given amount of pixels. * * @param moveHorizontal the amount of pixels to move this MapViewPosition horizontally. * @param moveVertical the amount of pixels to move this MapViewPosition vertically. * @param zoomLevelDiff the difference in desired zoom level. * @param animated whether the move should be animated. */ public void moveCenterAndZoom(double moveHorizontal, double moveVertical, byte zoomLevelDiff, boolean animated) { synchronized (this) { long mapSize = MercatorProjection.getMapSize(this.zoomLevel, this.displayModel.getTileSize()); double pixelX = MercatorProjection.longitudeToPixelX(this.longitude, mapSize) - moveHorizontal; double pixelY = MercatorProjection.latitudeToPixelY(this.latitude, mapSize) - moveVertical; pixelX = Math.min(Math.max(0, pixelX), mapSize); pixelY = Math.min(Math.max(0, pixelY), mapSize); double newLatitude = MercatorProjection.pixelYToLatitude(pixelY, mapSize); double newLongitude = MercatorProjection.pixelXToLongitude(pixelX, mapSize); setCenterInternal(newLatitude, newLongitude); setZoomLevelInternal(this.zoomLevel + zoomLevelDiff, animated); } notifyObservers(); }
LatLong latLong = iterator.next(); long mapSize = MercatorProjection.getMapSize(zoomLevel, displayModel.getTileSize()); float x = (float) (MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize) - topLeftPoint.x); float y = (float) (MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize) - topLeftPoint.y); path.moveTo(x, y); x = (float) (MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize) - topLeftPoint.x); y = (float) (MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize) - topLeftPoint.y); path.lineTo(x, y);
int left = (int) (MercatorProjection.longitudeToPixelX(minLongitude, mapSize) - topLeftPoint.x); int right = (int) (MercatorProjection.longitudeToPixelX(maxLongitude, mapSize) - topLeftPoint.x); int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, mapSize) - topLeftPoint.x); canvas.drawLine(pixelX, bottom, pixelX, top, this.lineBack); int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, mapSize) - topLeftPoint.x); canvas.drawLine(pixelX, bottom, pixelX, top, this.lineFront); int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, mapSize) - topLeftPoint.x) - this.textFront.getTextWidth(text) / 2; int pixelY = (canvas.getHeight() + this.textFront.getTextHeight(text)) / 2; canvas.drawText(text, pixelX, pixelY, this.textBack);
/** * Converts geographic coordinates to view x/y coordinates in the map view. * * @param in the geographic coordinates * @return x/y view coordinates for the given location */ public Point toPixels(LatLong in) { if (in == null || this.mapView.getWidth() <= 0 || this.mapView.getHeight() <= 0) { return null; } MapPosition mapPosition = this.mapView.getModel().mapViewPosition.getMapPosition(); // this means somehow the mapview is not yet properly set up, see issue #308. if (mapPosition == null) { return null; } // calculate the pixel coordinates of the top left corner LatLong latLong = mapPosition.latLong; long mapSize = MercatorProjection.getMapSize(mapPosition.zoomLevel, this.mapView.getModel().displayModel.getTileSize()); double pixelX = MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize); double pixelY = MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize); pixelX -= this.mapView.getWidth() >> 1; pixelY -= this.mapView.getHeight() >> 1; // create a new point and return it return new Point( (int) (MercatorProjection.longitudeToPixelX(in.longitude, mapSize) - pixelX), (int) (MercatorProjection.latitudeToPixelY(in.latitude, mapSize) - pixelY)); }
shadingSubrectLeft = padding + shadingInnerWidth * ((maptileLeftLng - shadingLeftLng) / shadingLngStep); } else if (maptileLeftLng < shadingLeftLng) { maptileSubrectLeft = MercatorProjection.longitudeToPixelX(shadingLeftLng + (shadingPixelOffset / shadingInnerWidth), tile.mapSize) - origin.x; maptileSubrectRight = MercatorProjection.longitudeToPixelX(shadingRightLng + (shadingPixelOffset / shadingInnerHeight), tile.mapSize) - origin.x;
@Override public synchronized void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) { if (this.latLong == null || (this.paintStroke == null && this.paintFill == null)) { return; } double latitude = this.latLong.latitude; double longitude = this.latLong.longitude; long mapSize = MercatorProjection.getMapSize(zoomLevel, displayModel.getTileSize()); int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, mapSize) - topLeftPoint.x); int pixelY = (int) (MercatorProjection.latitudeToPixelY(latitude, mapSize) - topLeftPoint.y); int radiusInPixel = getRadiusInPixels(latitude, zoomLevel); Rectangle canvasRectangle = new Rectangle(0, 0, canvas.getWidth(), canvas.getHeight()); if (!canvasRectangle.intersectsCircle(pixelX, pixelY, radiusInPixel)) { return; } if (this.paintStroke != null) { if (this.keepAligned) { this.paintStroke.setBitmapShaderShift(topLeftPoint); } canvas.drawCircle(pixelX, pixelY, radiusInPixel, this.paintStroke); } if (this.paintFill != null) { if (this.keepAligned) { this.paintFill.setBitmapShaderShift(topLeftPoint); } canvas.drawCircle(pixelX, pixelY, radiusInPixel, this.paintFill); } }
@Override public synchronized void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) { if (this.latLong == null || this.bitmap == null || this.bitmap.isDestroyed()) { return; } long mapSize = MercatorProjection.getMapSize(zoomLevel, this.displayModel.getTileSize()); double pixelX = MercatorProjection.longitudeToPixelX(this.latLong.longitude, mapSize); double pixelY = MercatorProjection.latitudeToPixelY(this.latLong.latitude, mapSize); int halfBitmapWidth = this.bitmap.getWidth() / 2; int halfBitmapHeight = this.bitmap.getHeight() / 2; int left = (int) (pixelX - topLeftPoint.x - halfBitmapWidth + this.horizontalOffset); int top = (int) (pixelY - topLeftPoint.y - halfBitmapHeight + this.verticalOffset); int right = left + this.bitmap.getWidth(); int bottom = top + this.bitmap.getHeight(); Rectangle bitmapRectangle = new Rectangle(left, top, right, bottom); Rectangle canvasRectangle = new Rectangle(0, 0, canvas.getWidth(), canvas.getHeight()); if (!canvasRectangle.intersects(bitmapRectangle)) { return; } canvas.drawBitmap(this.bitmap, left, top); }
double pixelX = MercatorProjection.longitudeToPixelX(latLong.longitude, mapSize); double pixelY = MercatorProjection.latitudeToPixelY(latLong.latitude, mapSize); pixelX -= this.mapView.getWidth() >> 1;
@Override public void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) { super.draw(boundingBox, zoomLevel, canvas, topLeftPoint); long mapSize = MercatorProjection.getMapSize(zoomLevel, this.displayModel.getTileSize()); int pixelX = (int) (MercatorProjection.longitudeToPixelX(position.longitude, mapSize) - topLeftPoint.x); int pixelY = (int) (MercatorProjection.latitudeToPixelY(position.latitude, mapSize) - topLeftPoint.y); String text = Integer.toString(count); canvas.drawText(text, pixelX - BLACK.getTextWidth(text) / 2, pixelY + BLACK.getTextHeight(text) / 2, BLACK); }