2010-04-30 16:35:33 +02:00
|
|
|
package com.osmand.map;
|
|
|
|
|
2010-07-27 20:00:44 +02:00
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStreamReader;
|
2010-04-30 16:35:33 +02:00
|
|
|
import java.text.MessageFormat;
|
|
|
|
import java.util.ArrayList;
|
2010-07-27 20:00:44 +02:00
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
|
|
|
|
import com.osmand.Algoritms;
|
|
|
|
import com.osmand.LogUtil;
|
|
|
|
import com.osmand.osm.MapUtils;
|
2010-04-30 16:35:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
public class TileSourceManager {
|
2010-07-27 20:00:44 +02:00
|
|
|
private static final Log log = LogUtil.getLog(TileSourceManager.class);
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
public static class TileSourceTemplate implements ITileSource {
|
|
|
|
private int maxZoom;
|
|
|
|
private int minZoom;
|
|
|
|
private String name;
|
2010-07-27 20:00:44 +02:00
|
|
|
protected int tileSize;
|
|
|
|
protected String urlToLoad;
|
|
|
|
protected String ext;
|
2010-04-30 16:35:33 +02:00
|
|
|
private int avgSize;
|
2010-07-19 21:28:29 +02:00
|
|
|
private int bitDensity;
|
2010-04-30 16:35:33 +02:00
|
|
|
|
2010-07-27 20:58:42 +02:00
|
|
|
// default constructor
|
|
|
|
public TileSourceTemplate(String name, String urlToLoad){
|
|
|
|
this(name, urlToLoad, ".jpg", 18, 1, 256, 16, 20000); //$NON-NLS-1$
|
|
|
|
}
|
|
|
|
|
2010-07-19 21:28:29 +02:00
|
|
|
public TileSourceTemplate(String name, String urlToLoad, String ext, int maxZoom, int minZoom, int tileSize, int bitDensity, int avgSize) {
|
2010-04-30 16:35:33 +02:00
|
|
|
this.maxZoom = maxZoom;
|
|
|
|
this.minZoom = minZoom;
|
|
|
|
this.name = name;
|
|
|
|
this.tileSize = tileSize;
|
|
|
|
this.urlToLoad = urlToLoad;
|
|
|
|
this.ext = ext;
|
|
|
|
this.avgSize = avgSize;
|
2010-07-19 21:28:29 +02:00
|
|
|
this.bitDensity = bitDensity;
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
2010-07-19 21:28:29 +02:00
|
|
|
@Override
|
|
|
|
public int getBitDensity() {
|
|
|
|
return bitDensity;
|
|
|
|
}
|
2010-04-30 16:35:33 +02:00
|
|
|
|
|
|
|
public int getAverageSize(){
|
|
|
|
return avgSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMaximumZoomSupported() {
|
|
|
|
return maxZoom;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getMinimumZoomSupported() {
|
|
|
|
return minZoom;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getTileSize() {
|
|
|
|
return tileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getTileFormat(){
|
|
|
|
return ext;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getUrlToLoad(int x, int y, int zoom) {
|
2010-06-21 00:15:47 +02:00
|
|
|
// use int to string not format numbers! (non-nls)
|
2010-07-27 20:58:42 +02:00
|
|
|
if(urlToLoad == null){
|
|
|
|
return null;
|
|
|
|
}
|
2010-06-21 00:15:47 +02:00
|
|
|
return MessageFormat.format(urlToLoad, zoom+"", x+"", y+""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
2010-07-19 21:28:29 +02:00
|
|
|
|
2010-07-27 20:58:42 +02:00
|
|
|
|
|
|
|
public String getUrlTemplate(){
|
|
|
|
return urlToLoad;
|
|
|
|
}
|
2010-07-19 21:28:29 +02:00
|
|
|
@Override
|
|
|
|
public boolean couldBeDownloadedFromInternet() {
|
2010-07-27 20:58:42 +02:00
|
|
|
return urlToLoad != null;
|
2010-07-19 21:28:29 +02:00
|
|
|
}
|
2010-05-14 13:44:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
final int prime = 31;
|
|
|
|
int result = 1;
|
|
|
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (this == obj)
|
|
|
|
return true;
|
|
|
|
if (obj == null)
|
|
|
|
return false;
|
|
|
|
if (getClass() != obj.getClass())
|
|
|
|
return false;
|
|
|
|
TileSourceTemplate other = (TileSourceTemplate) obj;
|
|
|
|
if (name == null) {
|
|
|
|
if (other.name != null)
|
|
|
|
return false;
|
|
|
|
} else if (!name.equals(other.name))
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-07-27 20:00:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static class WMSSourceTemplate extends TileSourceTemplate {
|
|
|
|
|
|
|
|
public WMSSourceTemplate(String name, String wmsUrl) {
|
|
|
|
super("WMS " + name, wmsUrl, ".jpg", 18, 3, 256, 16, 20000); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
}
|
2010-05-14 13:44:35 +02:00
|
|
|
|
2010-07-27 20:00:44 +02:00
|
|
|
@Override
|
|
|
|
public String getUrlToLoad(int x, int y, int zoom) {
|
|
|
|
double yEnd = MapUtils.getLatitudeFromTile(zoom, y + 1);
|
|
|
|
double yStart = MapUtils.getLatitudeFromTile(zoom, y );
|
|
|
|
double xStart = MapUtils.getLongitudeFromTile(zoom, x);
|
|
|
|
double xEnd = MapUtils.getLongitudeFromTile(zoom, x + 1);
|
|
|
|
StringBuilder load = new StringBuilder();
|
|
|
|
load.append(urlToLoad).append("bbox=").append(xStart).append(','). //$NON-NLS-1$
|
|
|
|
append(yEnd).append(',').append(xEnd).append(',').append(yStart);
|
|
|
|
load.append("&srs=EPSG:4326").append("&width=").append(tileSize).append("&height=").append(tileSize); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
|
|
|
return load.toString();
|
|
|
|
}
|
2010-04-30 16:35:33 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-07-27 20:00:44 +02:00
|
|
|
public static java.util.List<TileSourceTemplate> getUserDefinedTemplates(File tilesDir){
|
|
|
|
java.util.List<TileSourceTemplate> ts = new ArrayList<TileSourceTemplate>();
|
|
|
|
if (tilesDir != null) {
|
|
|
|
for (File f : tilesDir.listFiles()) {
|
|
|
|
File ch = new File(f, "url"); //$NON-NLS-1$
|
|
|
|
if (f.isDirectory() && ch.exists()) {
|
|
|
|
try {
|
|
|
|
BufferedReader read = new BufferedReader(new InputStreamReader(new FileInputStream(ch), "UTF-8")); //$NON-NLS-1$
|
|
|
|
String url = read.readLine();
|
|
|
|
read.close();
|
|
|
|
if (!Algoritms.isEmpty(url)) {
|
|
|
|
url = url.replaceAll(Pattern.quote("{$x}"), "{1}"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
url = url.replaceAll(Pattern.quote("{$z}"), "{0}"); //$NON-NLS-1$//$NON-NLS-2$
|
|
|
|
url = url.replaceAll(Pattern.quote("{$y}"), "{2}"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
|
|
TileSourceTemplate t = new TileSourceTemplate(f.getName(), url, ".jpg", 18, 1, 256, 16, 20000); //$NON-NLS-1$
|
|
|
|
ts.add(t);
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
log.info("Mailformed dir " + f.getName(), e); //$NON-NLS-1$
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
static java.util.List<TileSourceTemplate> list;
|
|
|
|
public static java.util.List<TileSourceTemplate> getKnownSourceTemplates(){
|
|
|
|
if(list == null){
|
|
|
|
list = new ArrayList<TileSourceTemplate>();
|
|
|
|
list.add(getMapnikSource());
|
|
|
|
list.add(getOsmaRenderSource());
|
|
|
|
list.add(getCycleMapSource());
|
2010-06-14 12:53:07 +02:00
|
|
|
list.add(getMapSurferSource());
|
|
|
|
list.add(getNavigationDebugSource());
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
list.add(getCloudMadeSource());
|
|
|
|
list.add(getOpenPisteMapSource());
|
|
|
|
list.add(getGoogleMapsSource());
|
2010-05-02 01:35:00 +02:00
|
|
|
list.add(getGoogleMapsSatelliteSource());
|
|
|
|
list.add(getGoogleMapsTerrainSource());
|
2010-06-14 12:53:07 +02:00
|
|
|
|
2010-05-02 01:35:00 +02:00
|
|
|
list.add(getMicrosoftMapsSource());
|
|
|
|
list.add(getMicrosoftEarthSource());
|
|
|
|
list.add(getMicrosoftHybridSource());
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
return list;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static TileSourceTemplate getMapnikSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("Mapnik", "http://tile.openstreetmap.org/{0}/{1}/{2}.png", ".png", 18, 1, 256, 8, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getOsmaRenderSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("OsmaRender", "http://tah.openstreetmap.org/Tiles/tile/{0}/{1}/{2}.png", ".png", 17, 1, 256, 8, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getCycleMapSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("CycleMap", "http://b.andy.sandbox.cloudmade.com/tiles/cycle/{0}/{1}/{2}.png", ".png", 17, 0, 256, 32, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getAerialMapSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("OpenAerialMap", "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/{0}/{1}/{2}.jpg", ".jpg", 13, 0, 256, 8, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getCloudMadeSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("Cloudmade", "http://tile.cloudmade.com/7ded028e030c5929b28bf823486ce84f/1/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 16, 18000); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
2010-06-14 12:53:07 +02:00
|
|
|
public static TileSourceTemplate getMapSurferSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("MapSurfer", "http://tiles1.mapsurfer.net/tms_r.ashx?z={0}&x={1}&y={2}", ".png", 19, 0, 256, 16, 18000);//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-06-14 12:53:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getNavigationDebugSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("NavigationDebug", "http://ec2-184-73-15-218.compute-1.amazonaws.com/6700/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 16, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-06-14 12:53:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
public static TileSourceTemplate getOpenPisteMapSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("OpenPisteMap", "http://openpistemap.org/tiles/contours/{0}/{1}/{2}.png", ".png", 17, 0, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getGoogleMapsSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("GoogleMaps", "http://mt3.google.com/vt/v=w2.97&x={1}&y={2}&z={0}", ".png", 19, 0, 256, 16, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getGoogleMapsSatelliteSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("GoogleMaps Satellite", "http://khm1.google.com/kh/v=59&x={1}&y={2}&z={0}", ".jpg", 20, 0, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getGoogleMapsTerrainSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new TileSourceTemplate("GoogleMaps Terrain", "http://mt3.google.com/vt/v=w2p.111&hl=en&x={1}&y={2}&z={0}", ".jpg", 15, 0, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|
|
|
|
|
2010-05-02 01:35:00 +02:00
|
|
|
public static TileSourceTemplate getMicrosoftMapsSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new MicrosoftTileSourceTemplate("Microsoft Maps", 'r', "png", ".png", 19, 1, 256, 16, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-05-02 01:35:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getMicrosoftEarthSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new MicrosoftTileSourceTemplate("Microsoft Earth", 'a', "jpg", ".jpg", 19, 1, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-05-02 01:35:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static TileSourceTemplate getMicrosoftHybridSource(){
|
2010-07-19 21:28:29 +02:00
|
|
|
return new MicrosoftTileSourceTemplate("Microsoft Hybrid", 'h', "jpg", ".jpg", 19, 1, 256, 32, 18000); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
2010-05-02 01:35:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-27 20:00:44 +02:00
|
|
|
// WMS layers : http://whoots.mapwarper.net/tms/{$z}/{$x}/{$y}/ {layer}/{Path}
|
|
|
|
// 1. Landsat http://onearth.jpl.nasa.gov/wms.cgi global_mosaic (NOT WORK)
|
|
|
|
// 2. Genshtab http://wms.latlon.org gshtab
|
2010-07-23 08:13:03 +02:00
|
|
|
|
2010-05-02 01:35:00 +02:00
|
|
|
protected static final char[] NUM_CHAR = { '0', '1', '2', '3' };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See: http://msdn.microsoft.com/en-us/library/bb259689.aspx
|
|
|
|
* @param zoom
|
|
|
|
* @param tilex
|
|
|
|
* @param tiley
|
|
|
|
* @return quadtree encoded tile number
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public static String encodeQuadTree(int zoom, int tilex, int tiley) {
|
|
|
|
char[] tileNum = new char[zoom];
|
|
|
|
for (int i = zoom - 1; i >= 0; i--) {
|
|
|
|
// Binary encoding using ones for tilex and twos for tiley. if a bit
|
|
|
|
// is set in tilex and tiley we get a three.
|
|
|
|
int num = (tilex % 2) | ((tiley % 2) << 1);
|
|
|
|
tileNum[i] = NUM_CHAR[num];
|
|
|
|
tilex >>= 1;
|
|
|
|
tiley >>= 1;
|
|
|
|
}
|
|
|
|
return new String(tileNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class MicrosoftTileSourceTemplate extends TileSourceTemplate {
|
|
|
|
|
|
|
|
private final char mapTypeChar;
|
|
|
|
int serverNum = 0; // 0..3
|
2010-06-19 19:13:52 +02:00
|
|
|
protected String urlBase = ".ortho.tiles.virtualearth.net/tiles/"; //$NON-NLS-1$
|
|
|
|
protected String urlAppend = "?g=45"; //$NON-NLS-1$
|
2010-05-02 01:35:00 +02:00
|
|
|
private final String tileType;
|
|
|
|
|
|
|
|
public MicrosoftTileSourceTemplate(String name, char mapTypeChar , String type,
|
2010-07-19 21:28:29 +02:00
|
|
|
String ext, int maxZoom, int minZoom, int tileSize, int bitDensity, int avgSize) {
|
|
|
|
super(name, null, ext, maxZoom, minZoom, tileSize, bitDensity, avgSize);
|
2010-05-02 01:35:00 +02:00
|
|
|
this.mapTypeChar = mapTypeChar;
|
|
|
|
this.tileType = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getUrlToLoad(int x, int y, int zoom) {
|
|
|
|
String tileNum = encodeQuadTree(zoom, x, y);
|
|
|
|
// serverNum = (serverNum + 1) % serverNumMax;
|
2010-06-19 19:13:52 +02:00
|
|
|
return "http://" + mapTypeChar + serverNum + urlBase + mapTypeChar + tileNum + "." //$NON-NLS-1$ //$NON-NLS-2$
|
2010-05-02 01:35:00 +02:00
|
|
|
+ tileType + urlAppend;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-30 16:35:33 +02:00
|
|
|
}
|