source: osm/applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractTMSTileSource.java@ 33971

Last change on this file since 33971 was 33971, checked in by donvip, 7 years ago

see #josm15713 - Add dirty-mode

  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1// License: GPL. For details, see Readme.txt file.
2package org.openstreetmap.gui.jmapviewer.tilesources;
3
4import java.awt.Point;
5import java.io.IOException;
6import java.security.MessageDigest;
7import java.security.NoSuchAlgorithmException;
8import java.util.HashMap;
9import java.util.List;
10import java.util.Map;
11import java.util.Map.Entry;
12import java.util.Set;
13
14import org.openstreetmap.gui.jmapviewer.OsmMercator;
15import org.openstreetmap.gui.jmapviewer.Tile;
16import org.openstreetmap.gui.jmapviewer.TileXY;
17import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
18
19/**
20 * Class generalizing all tile based tile sources
21 *
22 * @author Wiktor Niesiobędzki
23 *
24 */
25public abstract class AbstractTMSTileSource extends AbstractTileSource {
26
27 protected String name;
28 protected String baseUrl;
29 protected String id;
30 private final Map<String, Set<String>> noTileHeaders;
31 private final Map<String, Set<String>> noTileChecksums;
32 private final Map<String, String> metadataHeaders;
33 protected boolean dirtyMode;
34 protected int tileSize;
35
36 /**
37 * Creates an instance based on TileSource information
38 *
39 * @param info description of the Tile Source
40 */
41 public AbstractTMSTileSource(TileSourceInfo info) {
42 this.name = info.getName();
43 this.baseUrl = info.getUrl();
44 if (baseUrl != null && baseUrl.endsWith("/")) {
45 baseUrl = baseUrl.substring(0, baseUrl.length()-1);
46 }
47 this.id = info.getUrl();
48 this.noTileHeaders = info.getNoTileHeaders();
49 this.noTileChecksums = info.getNoTileChecksums();
50 this.metadataHeaders = info.getMetadataHeaders();
51 this.dirtyMode = info.isDirtyMode();
52 this.tileSize = info.getTileSize();
53 }
54
55 /**
56 * @return default tile size to use, when not set in Imagery Preferences
57 */
58 @Override
59 public int getDefaultTileSize() {
60 return OsmMercator.DEFAUL_TILE_SIZE;
61 }
62
63 @Override
64 public String getName() {
65 return name;
66 }
67
68 @Override
69 public String getId() {
70 return id;
71 }
72
73 @Override
74 public int getMaxZoom() {
75 return 21;
76 }
77
78 @Override
79 public int getMinZoom() {
80 return 0;
81 }
82
83 /**
84 * @return image extension, used for URL creation
85 */
86 public String getExtension() {
87 return "png";
88 }
89
90 /**
91 * @param zoom level of the tile
92 * @param tilex tile number in x axis
93 * @param tiley tile number in y axis
94 * @return String containg path part of URL of the tile
95 * @throws IOException when subclass cannot return the tile URL
96 */
97 public String getTilePath(int zoom, int tilex, int tiley) throws IOException {
98 return "/" + zoom + "/" + tilex + "/" + tiley + "." + getExtension();
99 }
100
101 /**
102 * @return Base part of the URL of the tile source
103 */
104 public String getBaseUrl() {
105 return this.baseUrl;
106 }
107
108 @Override
109 public String getTileUrl(int zoom, int tilex, int tiley) throws IOException {
110 return this.getBaseUrl() + getTilePath(zoom, tilex, tiley);
111 }
112
113 @Override
114 public String toString() {
115 return getName();
116 }
117
118 /*
119 * Most tilesources use OsmMercator projection.
120 */
121 @Override
122 public int getTileSize() {
123 if (tileSize <= 0) {
124 return getDefaultTileSize();
125 }
126 return tileSize;
127 }
128
129 @Override
130 public Point latLonToXY(ICoordinate point, int zoom) {
131 return latLonToXY(point.getLat(), point.getLon(), zoom);
132 }
133
134 @Override
135 public ICoordinate xyToLatLon(Point point, int zoom) {
136 return xyToLatLon(point.x, point.y, zoom);
137 }
138
139 @Override
140 public TileXY latLonToTileXY(ICoordinate point, int zoom) {
141 return latLonToTileXY(point.getLat(), point.getLon(), zoom);
142 }
143
144 @Override
145 public ICoordinate tileXYToLatLon(TileXY xy, int zoom) {
146 return tileXYToLatLon(xy.getXIndex(), xy.getYIndex(), zoom);
147 }
148
149 @Override
150 public ICoordinate tileXYToLatLon(Tile tile) {
151 return tileXYToLatLon(tile.getXtile(), tile.getYtile(), tile.getZoom());
152 }
153
154 @Override
155 public int getTileXMax(int zoom) {
156 return getTileMax(zoom);
157 }
158
159 @Override
160 public int getTileXMin(int zoom) {
161 return 0;
162 }
163
164 @Override
165 public int getTileYMax(int zoom) {
166 return getTileMax(zoom);
167 }
168
169 @Override
170 public int getTileYMin(int zoom) {
171 return 0;
172 }
173
174 @Override
175 public boolean isNoTileAtZoom(Map<String, List<String>> headers, int statusCode, byte[] content) {
176 if (noTileHeaders != null && headers != null) {
177 for (Entry<String, Set<String>> searchEntry: noTileHeaders.entrySet()) {
178 List<String> headerVals = headers.get(searchEntry.getKey());
179 if (headerVals != null) {
180 for (String headerValue: headerVals) {
181 for (String val: searchEntry.getValue()) {
182 if (headerValue.matches(val)) {
183 return true;
184 }
185 }
186 }
187 }
188 }
189 }
190 if (noTileChecksums != null && content != null) {
191 for (Entry<String, Set<String>> searchEntry: noTileChecksums.entrySet()) {
192 MessageDigest md = null;
193 try {
194 md = MessageDigest.getInstance(searchEntry.getKey());
195 } catch (NoSuchAlgorithmException e) {
196 break;
197 }
198 byte[] byteDigest = md.digest(content);
199 final int len = byteDigest.length;
200
201 char[] hexChars = new char[len * 2];
202 for (int i = 0, j = 0; i < len; i++) {
203 final int v = byteDigest[i];
204 int vn = (v & 0xf0) >> 4;
205 hexChars[j++] = (char) (vn + (vn >= 10 ? 'a'-10 : '0'));
206 vn = (v & 0xf);
207 hexChars[j++] = (char) (vn + (vn >= 10 ? 'a'-10 : '0'));
208 }
209 for (String val: searchEntry.getValue()) {
210 if (new String(hexChars).equalsIgnoreCase(val)) {
211 return true;
212 }
213 }
214 }
215 }
216 return super.isNoTileAtZoom(headers, statusCode, content);
217 }
218
219 @Override
220 public Map<String, String> getMetadata(Map<String, List<String>> headers) {
221 Map<String, String> ret = new HashMap<>();
222 if (metadataHeaders != null && headers != null) {
223 for (Entry<String, String> searchEntry: metadataHeaders.entrySet()) {
224 List<String> headerVals = headers.get(searchEntry.getKey());
225 if (headerVals != null) {
226 for (String headerValue: headerVals) {
227 ret.put(searchEntry.getValue(), headerValue);
228 }
229 }
230 }
231 }
232 return ret;
233 }
234
235 @Override
236 public String getTileId(int zoom, int tilex, int tiley) {
237 return this.baseUrl + "/" + zoom + "/" + tilex + "/" + tiley;
238 }
239
240 @Override
241 public boolean isDirtyMode() {
242 return dirtyMode;
243 }
244
245 private static int getTileMax(int zoom) {
246 return (int) Math.pow(2.0, zoom) - 1;
247 }
248}
Note: See TracBrowser for help on using the repository browser.