Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	(revision 30247)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	(revision 30248)
@@ -87,5 +87,5 @@
     protected ZOOM_BUTTON_STYLE zoomButtonStyle;
 
-    private TileSource tileSource;
+    protected TileSource tileSource;
 
     protected AttributionSupport attribution = new AttributionSupport();
@@ -211,6 +211,6 @@
      */
     public void setDisplayPosition(Point mapPoint, Coordinate to, int zoom) {
-        int x = OsmMercator.LonToX(to.getLon(), zoom);
-        int y = OsmMercator.LatToY(to.getLat(), zoom);
+        int x = tileSource.LonToX(to.getLon(), zoom);
+        int y = tileSource.LatToY(to.getLat(), zoom);
         setDisplayPosition(mapPoint, x, y, zoom);
     }
@@ -269,6 +269,6 @@
             for (MapMarker marker : mapMarkerList) {
                 if(marker.isVisible()){
-                    int x = OsmMercator.LonToX(marker.getLon(), mapZoomMax);
-                    int y = OsmMercator.LatToY(marker.getLat(), mapZoomMax);
+                    int x = tileSource.LonToX(marker.getLon(), mapZoomMax);
+                    int y = tileSource.LatToY(marker.getLat(), mapZoomMax);
                     x_max = Math.max(x_max, x);
                     y_max = Math.max(y_max, y);
@@ -282,8 +282,8 @@
             for (MapRectangle rectangle : mapRectangleList) {
                 if(rectangle.isVisible()){
-                    x_max = Math.max(x_max, OsmMercator.LonToX(rectangle.getBottomRight().getLon(), mapZoomMax));
-                    y_max = Math.max(y_max, OsmMercator.LatToY(rectangle.getTopLeft().getLat(), mapZoomMax));
-                    x_min = Math.min(x_min, OsmMercator.LonToX(rectangle.getTopLeft().getLon(), mapZoomMax));
-                    y_min = Math.min(y_min, OsmMercator.LatToY(rectangle.getBottomRight().getLat(), mapZoomMax));
+                    x_max = Math.max(x_max, tileSource.LonToX(rectangle.getBottomRight().getLon(), mapZoomMax));
+                    y_max = Math.max(y_max, tileSource.LatToY(rectangle.getTopLeft().getLat(), mapZoomMax));
+                    x_min = Math.min(x_min, tileSource.LonToX(rectangle.getTopLeft().getLon(), mapZoomMax));
+                    y_min = Math.min(y_min, tileSource.LatToY(rectangle.getBottomRight().getLat(), mapZoomMax));
                 }
             }
@@ -294,6 +294,6 @@
                 if(polygon.isVisible()){
                     for (ICoordinate c : polygon.getPoints()) {
-                        int x = OsmMercator.LonToX(c.getLon(), mapZoomMax);
-                        int y = OsmMercator.LatToY(c.getLat(), mapZoomMax);
+                        int x = tileSource.LonToX(c.getLon(), mapZoomMax);
+                        int y = tileSource.LatToY(c.getLat(), mapZoomMax);
                         x_max = Math.max(x_max, x);
                         y_max = Math.max(y_max, y);
@@ -369,6 +369,6 @@
      */
     public Coordinate getPosition() {
-        double lon = OsmMercator.XToLon(center.x, zoom);
-        double lat = OsmMercator.YToLat(center.y, zoom);
+        double lon = tileSource.XToLon(center.x, zoom);
+        double lat = tileSource.YToLat(center.y, zoom);
         return new Coordinate(lat, lon);
     }
@@ -398,6 +398,6 @@
         int x = center.x + mapPointX - getWidth() / 2;
         int y = center.y + mapPointY - getHeight() / 2;
-        double lon = OsmMercator.XToLon(x, zoom);
-        double lat = OsmMercator.YToLat(y, zoom);
+        double lon = tileSource.XToLon(x, zoom);
+        double lat = tileSource.YToLat(y, zoom);
         return new Coordinate(lat, lon);
     }
@@ -413,6 +413,6 @@
      */
     public Point getMapPosition(double lat, double lon, boolean checkOutside) {
-        int x = OsmMercator.LonToX(lon, zoom);
-        int y = OsmMercator.LatToY(lat, zoom);
+        int x = tileSource.LonToX(lon, zoom);
+        int y = tileSource.LatToY(lat, zoom);
         x -= center.x - getWidth() / 2;
         y -= center.y - getHeight() / 2;
@@ -433,5 +433,5 @@
      */
     public Integer getLatOffset(double lat, double offset, boolean checkOutside) {
-        int y = OsmMercator.LatToY(lat+offset, zoom);
+        int y = tileSource.LatToY(lat+offset, zoom);
         y -= center.y - getHeight() / 2;
         if (checkOutside) {
@@ -511,5 +511,5 @@
         Coordinate centerCoord=getPosition(center);
 
-        double mDistance=OsmMercator.getDistance(originCoord.getLat(), originCoord.getLon(),
+        double mDistance = tileSource.getDistance(originCoord.getLat(), originCoord.getLon(),
                 centerCoord.getLat(), centerCoord.getLon());
 
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java	(revision 30247)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java	(revision 30248)
@@ -11,5 +11,5 @@
 public class OsmMercator {
 
-    private static int TILE_SIZE = 256;
+    public static int TILE_SIZE = 256;
     public static final double MAX_LAT = 85.05112877980659;
     public static final double MIN_LAT = -85.05112877980659;
@@ -101,9 +101,8 @@
      * @author Jan Peter Stotz
      */
-    public static int LonToX(double aLongitude, int aZoomlevel) {
+    public static double LonToX(double aLongitude, int aZoomlevel) {
         int mp = getMaxPixels(aZoomlevel);
-        int x = (int) ((mp * (aLongitude + 180l)) / 360l);
-        x = Math.min(x, mp - 1);
-        return x;
+        double x = (mp * (aLongitude + 180l)) / 360l;
+        return Math.min(x, mp - 1);
     }
 
@@ -126,5 +125,5 @@
      * @author Jan Peter Stotz
      */
-    public static int LatToY(double aLat, int aZoomlevel) {
+    public static double LatToY(double aLat, int aZoomlevel) {
         if (aLat < MIN_LAT)
             aLat = MIN_LAT;
@@ -134,7 +133,6 @@
         double log = Math.log((1.0 + sinLat) / (1.0 - sinLat));
         int mp = getMaxPixels(aZoomlevel);
-        int y = (int) (mp * (0.5 - (log / (4.0 * Math.PI))));
-        y = Math.min(y, mp - 1);
-        return y;
+        double y = mp * (0.5 - (log / (4.0 * Math.PI)));
+        return Math.min(y, mp - 1);
     }
 
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileSource.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileSource.java	(revision 30247)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileSource.java	(revision 30248)
@@ -94,10 +94,56 @@
     int getTileSize();
 
+    /**
+     * Gets the distance using Spherical law of cosines.
+     *  @return the distance, m.
+     */
+    double getDistance(double la1, double lo1, double la2, double lo2);
+
+    /**
+     * Transform longitude to pixelspace.
+     * @return [0..2^Zoomlevel*TILE_SIZE[
+     */
+    int LonToX(double aLongitude, int aZoomlevel);
+
+    /**
+     * Transforms latitude to pixelspace.
+     * @return [0..2^Zoomlevel*TILE_SIZE[
+     */
+    int LatToY(double aLat, int aZoomlevel);
+
+    /**
+     * Transforms pixel coordinate X to longitude
+     * @return ]-180..180[
+     */
+    double XToLon(int aX, int aZoomlevel);
+
+    /**
+     * Transforms pixel coordinate Y to latitude.
+     * @return [MIN_LAT..MAX_LAT]
+     */
+    double YToLat(int aY, int aZoomlevel);
+
+    /**
+     * Transforms longitude to X tile coordinate.
+     * @return [0..2^Zoomlevel[
+     */
+    double lonToTileX(double lon, int zoom);
+
+    /**
+     * Transforms latitude to Y tile coordinate.
+     * @return [0..2^Zoomlevel[
+     */
     double latToTileY(double lat, int zoom);
 
-    double lonToTileX(double lon, int zoom);
+    /**
+     * Transforms tile X coordinate to longitude.
+     * @return ]-180..180[
+     */
+    double tileXToLon(int x, int zoom);
 
+    /**
+     * Transforms tile Y coordinate to latitude.
+     * @return [MIN_LAT..MAX_LAT]
+     */
     double tileYToLat(int y, int zoom);
-
-    double tileXToLon(int x, int zoom);
 }
Index: /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTMSTileSource.java
===================================================================
--- /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTMSTileSource.java	(revision 30247)
+++ /applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTMSTileSource.java	(revision 30248)
@@ -3,4 +3,6 @@
 
 import java.io.IOException;
+
+import org.openstreetmap.gui.jmapviewer.OsmMercator;
 
 public abstract class AbstractTMSTileSource extends AbstractTileSource {
@@ -62,29 +64,55 @@
     }
 
+    /*
+     * Most tilesources use OsmMercator projection.
+     */
     @Override
     public int getTileSize() {
-        return 256;
+        return OsmMercator.TILE_SIZE;
+    }
+
+    @Override
+    public double getDistance(double lat1, double lon1, double lat2, double lon2) {
+        return OsmMercator.getDistance(lat1, lon1, lat2, lon2);
+    }
+
+    @Override
+    public int LonToX(double lon, int zoom) {
+        return (int )OsmMercator.LonToX(lon, zoom);
+    }
+
+    @Override
+    public int LatToY(double lat, int zoom) {
+        return (int )OsmMercator.LatToY(lat, zoom);
+    }
+
+    @Override
+    public double XToLon(int x, int zoom) {
+        return OsmMercator.XToLon(x, zoom);
+    }
+
+    @Override
+    public double YToLat(int y, int zoom) {
+        return OsmMercator.YToLat(y, zoom);
     }
 
     @Override
     public double latToTileY(double lat, int zoom) {
-        double l = lat / 180 * Math.PI;
-        double pf = Math.log(Math.tan(l) + (1 / Math.cos(l)));
-        return Math.pow(2.0, zoom - 1) * (Math.PI - pf) / Math.PI;
+        return OsmMercator.LatToY(lat, zoom) / OsmMercator.TILE_SIZE;
     }
 
     @Override
     public double lonToTileX(double lon, int zoom) {
-        return Math.pow(2.0, zoom - 3) * (lon + 180.0) / 45.0;
+        return OsmMercator.LonToX(lon, zoom) / OsmMercator.TILE_SIZE;
     }
 
     @Override
     public double tileYToLat(int y, int zoom) {
-        return Math.atan(Math.sinh(Math.PI - (Math.PI * y / Math.pow(2.0, zoom - 1)))) * 180 / Math.PI;
+        return OsmMercator.YToLat(y * OsmMercator.TILE_SIZE, zoom);
     }
 
     @Override
     public double tileXToLon(int x, int zoom) {
-        return x * 45.0 / Math.pow(2.0, zoom - 3) - 180.0;
+        return OsmMercator.XToLon(x * OsmMercator.TILE_SIZE, zoom);
     }
 }
