// License: GPL. For details, see Readme.txt file.
package org.openstreetmap.gui.jmapviewer.tilesources;
import java.awt.Point;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.OsmMercator;
import org.openstreetmap.gui.jmapviewer.Projected;
import org.openstreetmap.gui.jmapviewer.Tile;
import org.openstreetmap.gui.jmapviewer.TileRange;
import org.openstreetmap.gui.jmapviewer.TileXY;
import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
import org.openstreetmap.gui.jmapviewer.interfaces.IProjected;
/**
* TMS tile source.
*/
public class TMSTileSource extends AbstractTMSTileSource {
protected int maxZoom;
protected int minZoom;
protected OsmMercator osmMercator;
/**
* Constructs a new {@code TMSTileSource}.
* @param info tile source information
*/
public TMSTileSource(TileSourceInfo info) {
super(info);
minZoom = info.getMinZoom();
maxZoom = info.getMaxZoom();
this.osmMercator = new OsmMercator(this.getTileSize());
}
@Override
public int getMinZoom() {
return (minZoom == 0) ? super.getMinZoom() : minZoom;
}
@Override
public int getMaxZoom() {
return (maxZoom == 0) ? super.getMaxZoom() : maxZoom;
}
@Override
public double getDistance(double lat1, double lon1, double lat2, double lon2) {
return osmMercator.getDistance(lat1, lon1, lat2, lon2);
}
@Override
public Point latLonToXY(double lat, double lon, int zoom) {
return new Point(
(int) osmMercator.lonToX(lon, zoom),
(int) osmMercator.latToY(lat, zoom)
);
}
@Override
public ICoordinate xyToLatLon(int x, int y, int zoom) {
return new Coordinate(
osmMercator.yToLat(y, zoom),
osmMercator.xToLon(x, zoom)
);
}
@Override
public TileXY latLonToTileXY(double lat, double lon, int zoom) {
return new TileXY(
osmMercator.lonToX(lon, zoom) / getTileSize(),
osmMercator.latToY(lat, zoom) / getTileSize()
);
}
@Override
public ICoordinate tileXYToLatLon(int x, int y, int zoom) {
return new Coordinate(
osmMercator.yToLat(y * getTileSize(), zoom),
osmMercator.xToLon(x * getTileSize(), zoom)
);
}
@Override
public IProjected tileXYtoProjected(int x, int y, int zoom) {
double mercatorWidth = 2 * Math.PI * OsmMercator.EARTH_RADIUS;
double f = mercatorWidth * getTileSize() / osmMercator.getMaxPixels(zoom);
return new Projected(f * x - mercatorWidth / 2, -(f * y - mercatorWidth / 2));
}
@Override
public TileXY projectedToTileXY(IProjected p, int zoom) {
double mercatorWidth = 2 * Math.PI * OsmMercator.EARTH_RADIUS;
double f = mercatorWidth * getTileSize() / osmMercator.getMaxPixels(zoom);
return new TileXY((p.getEast() + mercatorWidth / 2) / f , (-p.getNorth() + mercatorWidth / 2) / f);
}
@Override
public boolean isInside(Tile inner, Tile outer) {
int dz = inner.getZoom() - outer.getZoom();
if (dz < 0) return false;
return outer.getXtile() == inner.getXtile() >> dz &&
outer.getYtile() == inner.getYtile() >> dz;
}
@Override
public TileRange getCoveringTileRange(Tile tile, int newZoom) {
if (newZoom <= tile.getZoom()) {
int dz = tile.getZoom() - newZoom;
TileXY xy = new TileXY(tile.getXtile() >> dz, tile.getYtile() >> dz);
return new TileRange(xy, xy, newZoom);
} else {
int dz = newZoom - tile.getZoom();
TileXY t1 = new TileXY(tile.getXtile() << dz, tile.getYtile() << dz);
TileXY t2 = new TileXY(t1.getX() + (1 << dz) - 1, t1.getY() + (1 << dz) - 1);
return new TileRange(t1, t2, newZoom);
}
}
@Override
public String getServerCRS() {
return "EPSG:3857";
}
}