source: osm/applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java@ 31122

Last change on this file since 31122 was 31122, checked in by bastik, 9 years ago

applied #josm10454 - Mapbox "empty" tile (imagery with zoom level > 17) (patch by wiktorn)

  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1// License: BSD or GPL. For details, see Readme.txt file.
2package org.openstreetmap.gui.jmapviewer.tilesources;
3
4import java.util.Random;
5
6import org.openstreetmap.gui.jmapviewer.OsmMercator;
7
8/*
9 * This tilesource uses different to OsmMercator projection.
10 *
11 * Earth is assumed an ellipsoid in this projection, unlike
12 * sphere in OsmMercator, so latitude calculation differs
13 * a lot.
14 *
15 * The longitude calculation is the same as in OsmMercator,
16 * we inherit it from AbstractTMSTileSource.
17 *
18 * TODO: correct getDistance() method.
19 */
20
21public class ScanexTileSource extends TMSTileSource {
22 private static final String DEFAULT_URL = "http://maps.kosmosnimki.ru";
23 private static final int DEFAULT_MAXZOOM = 14;
24 private static String API_KEY = "4018C5A9AECAD8868ED5DEB2E41D09F7";
25
26 private enum ScanexLayer {
27 IRS("irs", "/TileSender.ashx?ModeKey=tile&MapName=F7B8CF651682420FA1749D894C8AD0F6&LayerName=BAC78D764F0443BD9AF93E7A998C9F5B"),
28 SPOT("spot", "/TileSender.ashx?ModeKey=tile&MapName=F7B8CF651682420FA1749D894C8AD0F6&LayerName=F51CE95441284AF6B2FC319B609C7DEC");
29
30 private String name;
31 private String uri;
32
33 ScanexLayer(String name, String uri) {
34 this.name = name;
35 this.uri = uri;
36 }
37 public String getName() {
38 return name;
39 }
40 public String getUri() {
41 return uri;
42 }
43 }
44
45 /* IRS by default */
46 private ScanexLayer Layer = ScanexLayer.IRS;
47
48 public ScanexTileSource(TileSourceInfo info) {
49 super(info);
50 String url = info.getUrl();
51
52 for (ScanexLayer layer : ScanexLayer.values()) {
53 if (url.equalsIgnoreCase(layer.getName())) {
54 this.Layer = layer;
55 /*
56 * Override baseUrl and maxZoom in base class.
57 */
58 this.baseUrl = DEFAULT_URL;
59 if (maxZoom == 0)
60 this.maxZoom = DEFAULT_MAXZOOM;
61 break;
62 }
63 }
64 }
65
66 @Override
67 public String getExtension() {
68 return("jpeg");
69 }
70
71 @Override
72 public String getTilePath(int zoom, int tilex, int tiley) {
73 int tmp = (int)Math.pow(2.0, zoom - 1);
74
75 tilex = tilex - tmp;
76 tiley = tmp - tiley - 1;
77
78 return this.Layer.getUri() + "&apikey=" + API_KEY + "&x=" + tilex + "&y=" + tiley + "&z=" + zoom;
79 }
80
81 @Override
82 public TileUpdate getTileUpdate() {
83 return TileUpdate.IfNoneMatch;
84 }
85
86
87 /*
88 * Latitude to Y and back calculations.
89 */
90 private static double RADIUS_E = 6378137; /* radius of Earth at equator, m */
91 private static double EQUATOR = 40075016.68557849; /* equator length, m */
92 private static double E = 0.0818191908426; /* eccentricity of Earth's ellipsoid */
93
94 @Override
95 public int LatToY(double lat, int zoom) {
96 return (int )(latToTileY(lat, zoom) * OsmMercator.TILE_SIZE);
97 }
98
99 @Override
100 public double YToLat(int y, int zoom) {
101 return tileYToLat((double )y / OsmMercator.TILE_SIZE, zoom);
102 }
103
104 @Override
105 public double latToTileY(double lat, int zoom) {
106 double tmp = Math.tan(Math.PI/4 * (1 + lat/90));
107 double pow = Math.pow(Math.tan(Math.PI/4 + Math.asin(E * Math.sin(Math.toRadians(lat)))/2), E);
108
109 return (EQUATOR/2 - (RADIUS_E * Math.log(tmp/pow))) * Math.pow(2.0, zoom) / EQUATOR;
110 }
111
112 @Override
113 public double tileYToLat(int y, int zoom) {
114 return tileYToLat((double )y, zoom);
115 }
116
117 /*
118 * To solve inverse formula latitude = f(y) we use
119 * Newton's method. We cache previous calculated latitude,
120 * because new one is usually close to the old one. In case
121 * if solution gets out of bounds, we reset to a new random
122 * value.
123 */
124 private double cached_lat = 0;
125 private double tileYToLat(double y, int zoom) {
126 double lat0, lat;
127
128 lat = cached_lat;
129 do {
130 lat0 = lat;
131 lat = lat - Math.toDegrees(NextTerm(Math.toRadians(lat), y, zoom));
132 if (lat > OsmMercator.MAX_LAT || lat < OsmMercator.MIN_LAT) {
133 Random r = new Random();
134 lat = OsmMercator.MIN_LAT +
135 r.nextInt((int )(OsmMercator.MAX_LAT - OsmMercator.MIN_LAT));
136 }
137 } while ((Math.abs(lat0 - lat) > 0.000001));
138
139 cached_lat = lat;
140
141 return (lat);
142 }
143
144 /* Next term in Newton's polynomial */
145 private double NextTerm(double lat, double y, int zoom) {
146 double sinl=Math.sin(lat);
147 double cosl=Math.cos(lat);
148 double ec, f, df;
149
150 zoom = (int )Math.pow(2.0, zoom - 1);
151 ec = Math.exp((1 - y/zoom)*Math.PI);
152
153 f = (Math.tan(Math.PI/4+lat/2) -
154 ec * Math.pow(Math.tan(Math.PI/4 + Math.asin(E * sinl)/2), E));
155 df = 1/(1 - sinl) - ec * E * cosl/((1 - E * sinl) *
156 (Math.sqrt (1 - E * E * sinl * sinl)));
157
158 return (f/df);
159 }
160}
Note: See TracBrowser for help on using the repository browser.