/*+-------------+----------------------------------------------------------*
*| | |_|_|_|_| Fraunhofer-Institut fuer Graphische Datenverarbeitung *
*|__|__|_|_|_|_| (Fraunhofer Institute for Computer Graphics) *
*| | |_|_|_|_| *
*|__|__|_|_|_|_| *
*| __ | ___| *
*| /_ /_ / _ | Fraunhoferstrasse 5 *
*|/ / / /__/ | D-64283 Darmstadt, Germany *
*+-------------+----------------------------------------------------------*/
package org.jdesktop.swingx.mapviewer;
import java.awt.geom.Point2D;
/**
* Google Mercator projection converter providing WGS84 GeoPositions. Usable
* with world maps using Google like Mercator projection.
*
* @author Simon Templer
*/
public class GoogleMercatorConverter extends AbstractPixelConverter {
private final TileProvider tileProvider;
/**
* Constructor
*
* @param tileProvider the tile provider
* @param geoConverter the geo converter
*/
public GoogleMercatorConverter(TileProvider tileProvider, GeoConverter geoConverter) {
super(geoConverter);
this.tileProvider = tileProvider;
}
private double getLongitudeDegreeWidthInPixels(int zoom) {
return tileProvider.getMapWidthInTiles(zoom) * tileProvider.getTileWidth(zoom) / 360.0;
}
private double getLongitudeRadianWidthInPixels(int zoom) {
return tileProvider.getMapWidthInTiles(zoom) * tileProvider.getTileWidth(zoom)
/ (2.0 * Math.PI);
}
/**
* @see PixelConverter#geoToPixel(GeoPosition, int)
*/
@Override
public Point2D geoToPixel(GeoPosition pos, int zoom) throws IllegalGeoPositionException {
// convert to WGS84 long/lat
pos = geoConverter.convert(pos, GeoPosition.WGS_84_EPSG);
double x = TileProviderUtils.getMapCenterInPixels(tileProvider, zoom).getX()
+ pos.getX() /* long */ * getLongitudeDegreeWidthInPixels(zoom);
double e = Math.sin(pos.getY() /* lat */ * (Math.PI / 180.0));
if (e > 0.9999) {
e = 0.9999;
}
if (e < -0.9999) {
e = -0.9999;
}
double y = TileProviderUtils.getMapCenterInPixels(tileProvider, zoom).getY()
+ 0.5 * Math.log((1 + e) / (1 - e)) * -1 * (getLongitudeRadianWidthInPixels(zoom));
return new Point2D.Double(x, y);
}
/**
* @see PixelConverter#pixelToGeo(Point2D, int)
*/
@Override
public GeoPosition pixelToGeo(Point2D pixelCoordinate, int zoom) {
double wx = pixelCoordinate.getX();
double wy = pixelCoordinate.getY();
// this reverses getBitmapCoordinates
double flon = (wx - TileProviderUtils.getMapCenterInPixels(tileProvider, zoom).getX())
/ getLongitudeDegreeWidthInPixels(zoom);
double e1 = (wy - TileProviderUtils.getMapCenterInPixels(tileProvider, zoom).getY())
/ (-1 * getLongitudeRadianWidthInPixels(zoom));
double e2 = (2 * Math.atan(Math.exp(e1)) - Math.PI / 2) / (Math.PI / 180.0);
double flat = e2;
GeoPosition wc = new GeoPosition(flon, flat, GeoPosition.WGS_84_EPSG);
return wc;
}
/**
* @see PixelConverter#getMapEpsg()
*/
@Override
public int getMapEpsg() {
return GeoPosition.WGS_84_EPSG;
}
/**
* @see PixelConverter#supportsBoundingBoxes()
*/
@Override
public boolean supportsBoundingBoxes() {
return false;
}
}