001// License: GPL. For details, see Readme.txt file. 002package org.openstreetmap.gui.jmapviewer.tilesources; 003 004import java.awt.Point; 005 006import org.openstreetmap.gui.jmapviewer.Coordinate; 007import org.openstreetmap.gui.jmapviewer.OsmMercator; 008import org.openstreetmap.gui.jmapviewer.Projected; 009import org.openstreetmap.gui.jmapviewer.Tile; 010import org.openstreetmap.gui.jmapviewer.TileRange; 011import org.openstreetmap.gui.jmapviewer.TileXY; 012import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate; 013import org.openstreetmap.gui.jmapviewer.interfaces.IProjected; 014 015/** 016 * TMS tile source. 017 */ 018public class TMSTileSource extends AbstractTMSTileSource { 019 020 protected int maxZoom; 021 protected int minZoom; 022 protected OsmMercator osmMercator; 023 024 /** 025 * Constructs a new {@code TMSTileSource}. 026 * @param info tile source information 027 */ 028 public TMSTileSource(TileSourceInfo info) { 029 super(info); 030 minZoom = info.getMinZoom(); 031 maxZoom = info.getMaxZoom(); 032 this.osmMercator = new OsmMercator(this.getTileSize()); 033 } 034 035 @Override 036 public int getMinZoom() { 037 return (minZoom == 0) ? super.getMinZoom() : minZoom; 038 } 039 040 @Override 041 public int getMaxZoom() { 042 return (maxZoom == 0) ? super.getMaxZoom() : maxZoom; 043 } 044 045 @Override 046 public double getDistance(double lat1, double lon1, double lat2, double lon2) { 047 return osmMercator.getDistance(lat1, lon1, lat2, lon2); 048 } 049 050 @Override 051 public Point latLonToXY(double lat, double lon, int zoom) { 052 return new Point( 053 (int) Math.round(osmMercator.lonToX(lon, zoom)), 054 (int) Math.round(osmMercator.latToY(lat, zoom)) 055 ); 056 } 057 058 @Override 059 public ICoordinate xyToLatLon(int x, int y, int zoom) { 060 return new Coordinate( 061 osmMercator.yToLat(y, zoom), 062 osmMercator.xToLon(x, zoom) 063 ); 064 } 065 066 @Override 067 public TileXY latLonToTileXY(double lat, double lon, int zoom) { 068 return new TileXY( 069 osmMercator.lonToX(lon, zoom) / getTileSize(), 070 osmMercator.latToY(lat, zoom) / getTileSize() 071 ); 072 } 073 074 @Override 075 public ICoordinate tileXYToLatLon(int x, int y, int zoom) { 076 return new Coordinate( 077 osmMercator.yToLat(y * getTileSize(), zoom), 078 osmMercator.xToLon(x * getTileSize(), zoom) 079 ); 080 } 081 082 @Override 083 public IProjected tileXYtoProjected(int x, int y, int zoom) { 084 double mercatorWidth = 2 * Math.PI * OsmMercator.EARTH_RADIUS; 085 double f = mercatorWidth * getTileSize() / osmMercator.getMaxPixels(zoom); 086 return new Projected(f * x - mercatorWidth / 2, -(f * y - mercatorWidth / 2)); 087 } 088 089 @Override 090 public TileXY projectedToTileXY(IProjected p, int zoom) { 091 double mercatorWidth = 2 * Math.PI * OsmMercator.EARTH_RADIUS; 092 double f = mercatorWidth * getTileSize() / osmMercator.getMaxPixels(zoom); 093 return new TileXY((p.getEast() + mercatorWidth / 2) / f, (-p.getNorth() + mercatorWidth / 2) / f); 094 } 095 096 @Override 097 public boolean isInside(Tile inner, Tile outer) { 098 int dz = inner.getZoom() - outer.getZoom(); 099 if (dz < 0) return false; 100 return outer.getXtile() == inner.getXtile() >> dz && 101 outer.getYtile() == inner.getYtile() >> dz; 102 } 103 104 @Override 105 public TileRange getCoveringTileRange(Tile tile, int newZoom) { 106 if (newZoom <= tile.getZoom()) { 107 int dz = tile.getZoom() - newZoom; 108 TileXY xy = new TileXY(tile.getXtile() >> dz, tile.getYtile() >> dz); 109 return new TileRange(xy, xy, newZoom); 110 } else { 111 int dz = newZoom - tile.getZoom(); 112 TileXY t1 = new TileXY(tile.getXtile() << dz, tile.getYtile() << dz); 113 TileXY t2 = new TileXY(t1.getX() + (1 << dz) - 1, t1.getY() + (1 << dz) - 1); 114 return new TileRange(t1, t2, newZoom); 115 } 116 } 117 118 @Override 119 public String getServerCRS() { 120 return "EPSG:3857"; 121 } 122}