001// License: GPL. For details, see Readme.txt file.
002package org.openstreetmap.gui.jmapviewer.interfaces;
003
004import java.awt.Point;
005import java.io.IOException;
006import java.util.List;
007import java.util.Map;
008
009import org.openstreetmap.gui.jmapviewer.JMapViewer;
010import org.openstreetmap.gui.jmapviewer.Tile;
011import org.openstreetmap.gui.jmapviewer.TileRange;
012import org.openstreetmap.gui.jmapviewer.TileXY;
013
014/**
015 *
016 * @author Jan Peter Stotz
017 */
018public interface TileSource extends Attributed {
019
020    /**
021     * Specifies the maximum zoom value. The number of zoom levels is [0..
022     * {@link #getMaxZoom()}].
023     *
024     * @return maximum zoom value that has to be smaller or equal to
025     *         {@link JMapViewer#MAX_ZOOM}
026     */
027    int getMaxZoom();
028
029    /**
030     * Specifies the minimum zoom value. This value is usually 0.
031     * Only for maps that cover a certain region up to a limited zoom level
032     * this method should return a value different than 0.
033     *
034     * @return minimum zoom value - usually 0
035     */
036    int getMinZoom();
037
038    /**
039     * A tile layer name as displayed to the user.
040     *
041     * @return Name of the tile layer
042     */
043    String getName();
044
045    /**
046     * A unique id for this tile source.
047     *
048     * Unlike the name it has to be unique and has to consist only of characters
049     * valid for filenames.
050     *
051     * @return the id
052     */
053    String getId();
054
055    /**
056     * Constructs the tile url.
057     *
058     * @param zoom zoom level
059     * @param tilex X coordinate
060     * @param tiley Y coordinate
061     * @return fully qualified url for downloading the specified tile image
062     * @throws IOException if any I/O error occurs
063     */
064    String getTileUrl(int zoom, int tilex, int tiley) throws IOException;
065
066    /**
067     * Creates tile identifier that is unique among all tile sources, but the same tile will always
068     * get the same identifier. Used for creation of cache key.
069     *
070     * @param zoom zoom level
071     * @param tilex X coordinate
072     * @param tiley Y coordinate
073     * @return tile identifier
074     */
075    String getTileId(int zoom, int tilex, int tiley);
076
077    /**
078     * Specifies how large each tile is.
079     * @return The size of a single tile in pixels. -1 if default size should be used
080     */
081    int getTileSize();
082
083    /**
084     * @return default tile size, for this tile source
085     */
086    int getDefaultTileSize();
087
088    /**
089     * Gets the distance using Spherical law of cosines.
090     * @param la1 latitude of first point
091     * @param lo1 longitude of first point
092     * @param la2 latitude of second point
093     * @param lo2 longitude of second point
094     * @return the distance between first and second point, in m.
095     */
096    double getDistance(double la1, double lo1, double la2, double lo2);
097
098    /**
099     * Transforms longitude and latitude to pixel space (as if all tiles at specified zoom level where joined).
100     * @param lon longitude
101     * @param lat latitude
102     * @param zoom zoom level
103     * @return the pixel coordinates
104     */
105    Point latLonToXY(double lat, double lon, int zoom);
106
107    /**
108     * Transforms longitude and latitude to pixel space (as if all tiles at specified zoom level where joined).
109     * @param point point
110     * @param zoom zoom level
111     * @return the pixel coordinates
112     */
113    Point latLonToXY(ICoordinate point, int zoom);
114
115    /**
116     * Transforms a point in pixel space to longitude/latitude (WGS84).
117     * @param point point
118     * @param zoom zoom level
119     * @return WGS84 Coordinates of given point
120     */
121    ICoordinate xyToLatLon(Point point, int zoom);
122
123    /**
124     * Transforms a point in pixel space to longitude/latitude (WGS84).
125     * @param x X coordinate
126     * @param y Y coordinate
127     * @param zoom zoom level
128     * @return WGS84 Coordinates of given point
129     */
130    ICoordinate xyToLatLon(int x, int y, int zoom);
131
132    /**
133     * Transforms longitude and latitude to tile indices.
134     * @param lon longitude
135     * @param lat latitude
136     * @param zoom zoom level
137     * @return x and y tile indices
138     */
139    TileXY latLonToTileXY(double lat, double lon, int zoom);
140
141    /**
142     * Transforms longitude and latitude to tile indices.
143     * @param point point
144     * @param zoom zoom level
145     * @return x and y tile indices
146     */
147    TileXY latLonToTileXY(ICoordinate point, int zoom);
148
149    /**
150     * Transforms tile indices to longitude and latitude.
151     * @param xy X/Y tile indices
152     * @param zoom zoom level
153     * @return WGS84 coordinates of given tile
154     */
155    ICoordinate tileXYToLatLon(TileXY xy, int zoom);
156
157    /**
158     * Determines to longitude and latitude of a tile.
159     * (Refers to the tile origin - upper left tile corner)
160     * @param tile Tile
161     * @return WGS84 coordinates of given tile
162     */
163    ICoordinate tileXYToLatLon(Tile tile);
164
165    /**
166     * Transforms tile indices to longitude and latitude.
167     * @param x x tile index
168     * @param y y tile index
169     * @param zoom zoom level
170     * @return WGS84 coordinates of given tile
171     */
172    ICoordinate tileXYToLatLon(int x, int y, int zoom);
173
174    /**
175     * Get maximum x index of tile for specified zoom level.
176     * @param zoom zoom level
177     * @return maximum x index of tile for specified zoom level
178     */
179    int getTileXMax(int zoom);
180
181    /**
182     * Get minimum x index of tile for specified zoom level.
183     * @param zoom zoom level
184     * @return minimum x index of tile for specified zoom level
185     */
186    int getTileXMin(int zoom);
187
188    /**
189     * Get maximum y index of tile for specified zoom level.
190     * @param zoom zoom level
191     * @return maximum y index of tile for specified zoom level
192     */
193    int getTileYMax(int zoom);
194
195    /**
196     * Get minimum y index of tile for specified zoom level
197     * @param zoom zoom level
198     * @return minimum y index of tile for specified zoom level
199     */
200    int getTileYMin(int zoom);
201
202    /**
203     * Determines, if the returned data from TileSource represent "no tile at this zoom level" situation. Detection
204     * algorithms differ per TileSource, so each TileSource should implement each own specific way.
205     *
206     * @param headers HTTP headers from response from TileSource server
207     * @param statusCode HTTP status code
208     * @param content byte array representing the data returned from the server
209     * @return true, if "no tile at this zoom level" situation detected
210     */
211    boolean isNoTileAtZoom(Map<String, List<String>> headers, int statusCode, byte[] content);
212
213    /**
214     * Extracts metadata about the tile based on HTTP headers
215     *
216     * @param headers HTTP headers from Tile Source server
217     * @return tile metadata
218     */
219    Map<String, String> getMetadata(Map<String, List<String>> headers);
220
221    /**
222     * Convert tile indices (x/y/zoom) into projected coordinates of the tile origin.
223     * @param x x tile index
224     * @param y z tile index
225     * @param zoom zoom level
226     * @return projected coordinates of the tile origin
227     */
228    IProjected tileXYtoProjected(int x, int y, int zoom);
229
230    /**
231     * Convert projected coordinates to tile indices.
232     * @param p projected coordinates
233     * @param zoom zoom level
234     * @return corresponding tile index x/y (floating point, truncate to integer
235     * for tile index)
236     */
237    TileXY projectedToTileXY(IProjected p, int zoom);
238
239    /**
240     * Check if one tile is inside another tile.
241     * @param inner the tile that is suspected to be inside the other tile
242     * @param outer the tile that might contain the first tile
243     * @return true if first tile is inside second tile (or both are identical),
244     * false otherwise
245     */
246    boolean isInside(Tile inner, Tile outer);
247
248    /**
249     * Returns a range of tiles, that cover a given tile, which is
250     * usually at a different zoom level.
251     *
252     * In standard tile layout, 4 tiles cover a tile one zoom lower, 16 tiles
253     * cover a tile 2 zoom levels below etc.
254     * If the zoom level of the covering tiles is greater or equal, a single
255     * tile suffices.
256     *
257     * @param tile the tile to cover
258     * @param newZoom zoom level of the covering tiles
259     * @return TileRange of all covering tiles at zoom <code>newZoom</code>
260     */
261    TileRange getCoveringTileRange(Tile tile, int newZoom);
262
263    /**
264     * Get coordinate reference system for this tile source.
265     *
266     * E.g. "EPSG:3857" for Google-Mercator.
267     * @return code for the coordinate reference system in use
268     */
269    String getServerCRS();
270
271    /**
272     * Determines if this imagery supports "/dirty" mode (tile re-rendering).
273     * @return <code>true</code> if it supports "/dirty" mode (tile re-rendering)
274     */
275    default boolean isModTileFeatures() {
276        return false;
277    }
278}