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     * TODO: @since
086     */
087    int getDefaultTileSize();
088
089    /**
090     * Gets the distance using Spherical law of cosines.
091     * @param la1 latitude of first point
092     * @param lo1 longitude of first point
093     * @param la2 latitude of second point
094     * @param lo2 longitude of second point
095     * @return the distance betwen first and second point, in m.
096     */
097    double getDistance(double la1, double lo1, double la2, double lo2);
098
099    /**
100     * Transforms longitude and latitude to pixel space (as if all tiles at specified zoom level where joined).
101     * @param lon longitude
102     * @param lat latitude
103     * @param zoom zoom level
104     * @return the pixel coordinates
105     */
106    Point latLonToXY(double lat, double lon, int zoom);
107
108    /**
109     * Transforms longitude and latitude to pixel space (as if all tiles at specified zoom level where joined).
110     * @param point point
111     * @param zoom zoom level
112     * @return the pixel coordinates
113     */
114    Point latLonToXY(ICoordinate point, int zoom);
115
116    /**
117     * Transforms a point in pixel space to longitude/latitude (WGS84).
118     * @param point point
119     * @param zoom zoom level
120     * @return WGS84 Coordinates of given point
121     */
122    ICoordinate xyToLatLon(Point point, int zoom);
123
124    /**
125     * Transforms a point in pixel space to longitude/latitude (WGS84).
126     * @param x X coordinate
127     * @param y Y coordinate
128     * @param zoom zoom level
129     * @return WGS84 Coordinates of given point
130     */
131    ICoordinate xyToLatLon(int x, int y, int zoom);
132
133    /**
134     * Transforms longitude and latitude to tile indices.
135     * @param lon longitude
136     * @param lat latitude
137     * @param zoom zoom level
138     * @return x and y tile indices
139     */
140    TileXY latLonToTileXY(double lat, double lon, int zoom);
141
142    /**
143     * Transforms longitude and latitude to tile indices.
144     * @param point point
145     * @param zoom zoom level
146     * @return x and y tile indices
147     */
148    TileXY latLonToTileXY(ICoordinate point, int zoom);
149
150    /**
151     * Transforms tile indices to longitude and latitude.
152     * @param xy X/Y tile indices
153     * @param zoom zoom level
154     * @return WGS84 coordinates of given tile
155     */
156    ICoordinate tileXYToLatLon(TileXY xy, int zoom);
157
158    /**
159     * Determines to longitude and latitude of a tile.
160     * (Refers to the tile origin - upper left tile corner)
161     * @param tile Tile
162     * @return WGS84 coordinates of given tile
163     */
164    ICoordinate tileXYToLatLon(Tile tile);
165
166    /**
167     * Transforms tile indices to longitude and latitude.
168     * @param x x tile index
169     * @param y y tile index
170     * @param zoom zoom level
171     * @return WGS84 coordinates of given tile
172     */
173    ICoordinate tileXYToLatLon(int x, int y, int zoom);
174
175    /**
176     * Get maximum x index of tile for specified zoom level.
177     * @param zoom zoom level
178     * @return maximum x index of tile for specified zoom level
179     */
180    int getTileXMax(int zoom);
181
182    /**
183     * Get minimum x index of tile for specified zoom level.
184     * @param zoom zoom level
185     * @return minimum x index of tile for specified zoom level
186     */
187    int getTileXMin(int zoom);
188
189    /**
190     * Get maximum y index of tile for specified zoom level.
191     * @param zoom zoom level
192     * @return maximum y index of tile for specified zoom level
193     */
194    int getTileYMax(int zoom);
195
196    /**
197     * Get minimum y index of tile for specified zoom level
198     * @param zoom zoom level
199     * @return minimum y index of tile for specified zoom level
200     */
201    int getTileYMin(int zoom);
202
203    /**
204     * Determines, if the returned data from TileSource represent "no tile at this zoom level" situation. Detection
205     * algorithms differ per TileSource, so each TileSource should implement each own specific way.
206     *
207     * @param headers HTTP headers from response from TileSource server
208     * @param statusCode HTTP status code
209     * @param content byte array representing the data returned from the server
210     * @return true, if "no tile at this zoom level" situation detected
211     */
212    boolean isNoTileAtZoom(Map<String, List<String>> headers, int statusCode, byte[] content);
213
214    /**
215     * Extracts metadata about the tile based on HTTP headers
216     *
217     * @param headers HTTP headers from Tile Source server
218     * @return tile metadata
219     */
220    Map<String, String> getMetadata(Map<String, List<String>> headers);
221
222    /**
223     * Convert tile indices (x/y/zoom) into projected coordinates of the tile origin.
224     * @param x x tile index
225     * @param y z tile index
226     * @param zoom zoom level
227     * @return projected coordinates of the tile origin
228     */
229    IProjected tileXYtoProjected(int x, int y, int zoom);
230
231    /**
232     * Convert projected coordinates to tile indices.
233     * @param p projected coordinates
234     * @param zoom zoom level
235     * @return corresponding tile index x/y (floating point, truncate to integer
236     * for tile index)
237     */
238    TileXY projectedToTileXY(IProjected p, int zoom);
239
240    /**
241     * Check if one tile is inside another tile.
242     * @param inner the tile that is suspected to be inside the other tile
243     * @param outer the tile that might contain the first tile
244     * @return true if first tile is inside second tile (or both are identical),
245     * false otherwise
246     */
247    boolean isInside(Tile inner, Tile outer);
248
249    /**
250     * Returns a range of tiles, that cover a given tile, which is
251     * usually at a different zoom level.
252     *
253     * In standard tile layout, 4 tiles cover a tile one zoom lower, 16 tiles
254     * cover a tile 2 zoom levels below etc.
255     * If the zoom level of the covering tiles is greater or equal, a single
256     * tile suffices.
257     *
258     * @param tile the tile to cover
259     * @param newZoom zoom level of the covering tiles
260     * @return TileRange of all covering tiles at zoom <code>newZoom</code>
261     */
262    TileRange getCoveringTileRange(Tile tile, int newZoom);
263
264    /**
265     * Get coordinate reference system for this tile source.
266     *
267     * E.g. "EPSG:3857" for Google-Mercator.
268     * @return code for the coordinate reference system in use
269     */
270    String getServerCRS();
271
272    /**
273     * Determines if this imagery supports "/dirty" mode (tile re-rendering).
274     * @return <code>true</code> if it supports "/dirty" mode (tile re-rendering)
275     */
276    default boolean isModTileFeatures() {
277        return false;
278    }
279}