Ignore:
Timestamp:
2014-01-31T14:23:11+01:00 (11 years ago)
Author:
glebius
Message:

o JMapViewer should not use OsmMercator directly to solve tiles to

geocoordinates and vice versa, because not all tile sources work
in OsmMercator projection. Make JMapViewer use tileSource for that.

o Extend TileSource interface with the following methods, borrowing

API from OsmMercator:

int LonToX(double lon, int zoom)
int LatToY(double lat, int zoom)
double XToLon(int x, int zoom)
double YToLat(int y, int zoom)

o Implement those methods in AbstractTMSTileSource. The latter already

had own formulae to solve those equations, but API was a bit different.
The formulae in OsmMercator seemed better to me and they are better
documented, so now AbstractTMSTileSource uses OsmMercator as its
projection. Extraneous implementation deleted.

This is a prerequisite to fix #7017.

Location:
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java

    r30245 r30248  
    8787    protected ZOOM_BUTTON_STYLE zoomButtonStyle;
    8888
    89     private TileSource tileSource;
     89    protected TileSource tileSource;
    9090
    9191    protected AttributionSupport attribution = new AttributionSupport();
     
    211211     */
    212212    public void setDisplayPosition(Point mapPoint, Coordinate to, int zoom) {
    213         int x = OsmMercator.LonToX(to.getLon(), zoom);
    214         int y = OsmMercator.LatToY(to.getLat(), zoom);
     213        int x = tileSource.LonToX(to.getLon(), zoom);
     214        int y = tileSource.LatToY(to.getLat(), zoom);
    215215        setDisplayPosition(mapPoint, x, y, zoom);
    216216    }
     
    269269            for (MapMarker marker : mapMarkerList) {
    270270                if(marker.isVisible()){
    271                     int x = OsmMercator.LonToX(marker.getLon(), mapZoomMax);
    272                     int y = OsmMercator.LatToY(marker.getLat(), mapZoomMax);
     271                    int x = tileSource.LonToX(marker.getLon(), mapZoomMax);
     272                    int y = tileSource.LatToY(marker.getLat(), mapZoomMax);
    273273                    x_max = Math.max(x_max, x);
    274274                    y_max = Math.max(y_max, y);
     
    282282            for (MapRectangle rectangle : mapRectangleList) {
    283283                if(rectangle.isVisible()){
    284                     x_max = Math.max(x_max, OsmMercator.LonToX(rectangle.getBottomRight().getLon(), mapZoomMax));
    285                     y_max = Math.max(y_max, OsmMercator.LatToY(rectangle.getTopLeft().getLat(), mapZoomMax));
    286                     x_min = Math.min(x_min, OsmMercator.LonToX(rectangle.getTopLeft().getLon(), mapZoomMax));
    287                     y_min = Math.min(y_min, OsmMercator.LatToY(rectangle.getBottomRight().getLat(), mapZoomMax));
     284                    x_max = Math.max(x_max, tileSource.LonToX(rectangle.getBottomRight().getLon(), mapZoomMax));
     285                    y_max = Math.max(y_max, tileSource.LatToY(rectangle.getTopLeft().getLat(), mapZoomMax));
     286                    x_min = Math.min(x_min, tileSource.LonToX(rectangle.getTopLeft().getLon(), mapZoomMax));
     287                    y_min = Math.min(y_min, tileSource.LatToY(rectangle.getBottomRight().getLat(), mapZoomMax));
    288288                }
    289289            }
     
    294294                if(polygon.isVisible()){
    295295                    for (ICoordinate c : polygon.getPoints()) {
    296                         int x = OsmMercator.LonToX(c.getLon(), mapZoomMax);
    297                         int y = OsmMercator.LatToY(c.getLat(), mapZoomMax);
     296                        int x = tileSource.LonToX(c.getLon(), mapZoomMax);
     297                        int y = tileSource.LatToY(c.getLat(), mapZoomMax);
    298298                        x_max = Math.max(x_max, x);
    299299                        y_max = Math.max(y_max, y);
     
    369369     */
    370370    public Coordinate getPosition() {
    371         double lon = OsmMercator.XToLon(center.x, zoom);
    372         double lat = OsmMercator.YToLat(center.y, zoom);
     371        double lon = tileSource.XToLon(center.x, zoom);
     372        double lat = tileSource.YToLat(center.y, zoom);
    373373        return new Coordinate(lat, lon);
    374374    }
     
    398398        int x = center.x + mapPointX - getWidth() / 2;
    399399        int y = center.y + mapPointY - getHeight() / 2;
    400         double lon = OsmMercator.XToLon(x, zoom);
    401         double lat = OsmMercator.YToLat(y, zoom);
     400        double lon = tileSource.XToLon(x, zoom);
     401        double lat = tileSource.YToLat(y, zoom);
    402402        return new Coordinate(lat, lon);
    403403    }
     
    413413     */
    414414    public Point getMapPosition(double lat, double lon, boolean checkOutside) {
    415         int x = OsmMercator.LonToX(lon, zoom);
    416         int y = OsmMercator.LatToY(lat, zoom);
     415        int x = tileSource.LonToX(lon, zoom);
     416        int y = tileSource.LatToY(lat, zoom);
    417417        x -= center.x - getWidth() / 2;
    418418        y -= center.y - getHeight() / 2;
     
    433433     */
    434434    public Integer getLatOffset(double lat, double offset, boolean checkOutside) {
    435         int y = OsmMercator.LatToY(lat+offset, zoom);
     435        int y = tileSource.LatToY(lat+offset, zoom);
    436436        y -= center.y - getHeight() / 2;
    437437        if (checkOutside) {
     
    511511        Coordinate centerCoord=getPosition(center);
    512512
    513         double mDistance=OsmMercator.getDistance(originCoord.getLat(), originCoord.getLon(),
     513        double mDistance = tileSource.getDistance(originCoord.getLat(), originCoord.getLon(),
    514514                centerCoord.getLat(), centerCoord.getLon());
    515515
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java

    r30223 r30248  
    1111public class OsmMercator {
    1212
    13     private static int TILE_SIZE = 256;
     13    public static int TILE_SIZE = 256;
    1414    public static final double MAX_LAT = 85.05112877980659;
    1515    public static final double MIN_LAT = -85.05112877980659;
     
    101101     * @author Jan Peter Stotz
    102102     */
    103     public static int LonToX(double aLongitude, int aZoomlevel) {
     103    public static double LonToX(double aLongitude, int aZoomlevel) {
    104104        int mp = getMaxPixels(aZoomlevel);
    105         int x = (int) ((mp * (aLongitude + 180l)) / 360l);
    106         x = Math.min(x, mp - 1);
    107         return x;
     105        double x = (mp * (aLongitude + 180l)) / 360l;
     106        return Math.min(x, mp - 1);
    108107    }
    109108
     
    126125     * @author Jan Peter Stotz
    127126     */
    128     public static int LatToY(double aLat, int aZoomlevel) {
     127    public static double LatToY(double aLat, int aZoomlevel) {
    129128        if (aLat < MIN_LAT)
    130129            aLat = MIN_LAT;
     
    134133        double log = Math.log((1.0 + sinLat) / (1.0 - sinLat));
    135134        int mp = getMaxPixels(aZoomlevel);
    136         int y = (int) (mp * (0.5 - (log / (4.0 * Math.PI))));
    137         y = Math.min(y, mp - 1);
    138         return y;
     135        double y = mp * (0.5 - (log / (4.0 * Math.PI)));
     136        return Math.min(y, mp - 1);
    139137    }
    140138
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileSource.java

    r30223 r30248  
    9494    int getTileSize();
    9595
     96    /**
     97     * Gets the distance using Spherical law of cosines.
     98     *  @return the distance, m.
     99     */
     100    double getDistance(double la1, double lo1, double la2, double lo2);
     101
     102    /**
     103     * Transform longitude to pixelspace.
     104     * @return [0..2^Zoomlevel*TILE_SIZE[
     105     */
     106    int LonToX(double aLongitude, int aZoomlevel);
     107
     108    /**
     109     * Transforms latitude to pixelspace.
     110     * @return [0..2^Zoomlevel*TILE_SIZE[
     111     */
     112    int LatToY(double aLat, int aZoomlevel);
     113
     114    /**
     115     * Transforms pixel coordinate X to longitude
     116     * @return ]-180..180[
     117     */
     118    double XToLon(int aX, int aZoomlevel);
     119
     120    /**
     121     * Transforms pixel coordinate Y to latitude.
     122     * @return [MIN_LAT..MAX_LAT]
     123     */
     124    double YToLat(int aY, int aZoomlevel);
     125
     126    /**
     127     * Transforms longitude to X tile coordinate.
     128     * @return [0..2^Zoomlevel[
     129     */
     130    double lonToTileX(double lon, int zoom);
     131
     132    /**
     133     * Transforms latitude to Y tile coordinate.
     134     * @return [0..2^Zoomlevel[
     135     */
    96136    double latToTileY(double lat, int zoom);
    97137
    98     double lonToTileX(double lon, int zoom);
     138    /**
     139     * Transforms tile X coordinate to longitude.
     140     * @return ]-180..180[
     141     */
     142    double tileXToLon(int x, int zoom);
    99143
     144    /**
     145     * Transforms tile Y coordinate to latitude.
     146     * @return [MIN_LAT..MAX_LAT]
     147     */
    100148    double tileYToLat(int y, int zoom);
    101 
    102     double tileXToLon(int x, int zoom);
    103149}
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTMSTileSource.java

    r30241 r30248  
    33
    44import java.io.IOException;
     5
     6import org.openstreetmap.gui.jmapviewer.OsmMercator;
    57
    68public abstract class AbstractTMSTileSource extends AbstractTileSource {
     
    6264    }
    6365
     66    /*
     67     * Most tilesources use OsmMercator projection.
     68     */
    6469    @Override
    6570    public int getTileSize() {
    66         return 256;
     71        return OsmMercator.TILE_SIZE;
     72    }
     73
     74    @Override
     75    public double getDistance(double lat1, double lon1, double lat2, double lon2) {
     76        return OsmMercator.getDistance(lat1, lon1, lat2, lon2);
     77    }
     78
     79    @Override
     80    public int LonToX(double lon, int zoom) {
     81        return (int )OsmMercator.LonToX(lon, zoom);
     82    }
     83
     84    @Override
     85    public int LatToY(double lat, int zoom) {
     86        return (int )OsmMercator.LatToY(lat, zoom);
     87    }
     88
     89    @Override
     90    public double XToLon(int x, int zoom) {
     91        return OsmMercator.XToLon(x, zoom);
     92    }
     93
     94    @Override
     95    public double YToLat(int y, int zoom) {
     96        return OsmMercator.YToLat(y, zoom);
    6797    }
    6898
    6999    @Override
    70100    public double latToTileY(double lat, int zoom) {
    71         double l = lat / 180 * Math.PI;
    72         double pf = Math.log(Math.tan(l) + (1 / Math.cos(l)));
    73         return Math.pow(2.0, zoom - 1) * (Math.PI - pf) / Math.PI;
     101        return OsmMercator.LatToY(lat, zoom) / OsmMercator.TILE_SIZE;
    74102    }
    75103
    76104    @Override
    77105    public double lonToTileX(double lon, int zoom) {
    78         return Math.pow(2.0, zoom - 3) * (lon + 180.0) / 45.0;
     106        return OsmMercator.LonToX(lon, zoom) / OsmMercator.TILE_SIZE;
    79107    }
    80108
    81109    @Override
    82110    public double tileYToLat(int y, int zoom) {
    83         return Math.atan(Math.sinh(Math.PI - (Math.PI * y / Math.pow(2.0, zoom - 1)))) * 180 / Math.PI;
     111        return OsmMercator.YToLat(y * OsmMercator.TILE_SIZE, zoom);
    84112    }
    85113
    86114    @Override
    87115    public double tileXToLon(int x, int zoom) {
    88         return x * 45.0 / Math.pow(2.0, zoom - 3) - 180.0;
     116        return OsmMercator.XToLon(x * OsmMercator.TILE_SIZE, zoom);
    89117    }
    90118}
Note: See TracChangeset for help on using the changeset viewer.