001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.projection;
003
004import org.openstreetmap.josm.data.Bounds;
005import org.openstreetmap.josm.data.ProjectionBounds;
006import org.openstreetmap.josm.data.coor.EastNorth;
007import org.openstreetmap.josm.data.coor.LatLon;
008
009/**
010 * A projection, i.e. a class that supports conversion from lat/lon
011 * to east/north and back.
012 *
013 * The conversion from east/north to the screen coordinates is simply a scale
014 * factor and x/y offset.
015 */
016public interface Projection extends Projecting {
017    /**
018     * The default scale factor in east/north units per pixel
019     * ({@link org.openstreetmap.josm.gui.NavigatableComponent#getState})).
020     * FIXME: misnomer
021     * @return the scale factor
022     */
023    double getDefaultZoomInPPD();
024
025    /**
026     * Convert from easting/norting to lat/lon.
027     *
028     * @param en the geographical point to convert (in projected coordinates)
029     * @return the corresponding lat/lon (WGS84)
030     */
031    LatLon eastNorth2latlon(EastNorth en);
032
033    /**
034     * Describe the projection in one or two words.
035     * @return the name / description
036     */
037    @Override
038    String toString();
039
040    /**
041     * Return projection code.
042     *
043     * This should be a unique identifier.
044     * If projection supports parameters, return a different code
045     * for each set of parameters.
046     *
047     * The EPSG code can be used (if defined for the projection).
048     *
049     * @return the projection identifier
050     */
051    String toCode();
052
053    /**
054     * Get a filename compatible string (for the cache directory).
055     * @return the cache directory name (base name)
056     */
057    String getCacheDirectoryName();
058
059    /**
060     * Get the bounds of the world.
061     * @return the supported lat/lon rectangle for this projection
062     */
063    Bounds getWorldBoundsLatLon();
064
065    /**
066     * Get an approximate EastNorth box around the lat/lon world bounds.
067     *
068     * Note: The projection is only valid within the bounds returned by
069     * {@link #getWorldBoundsLatLon()}. The lat/lon bounds need not be a
070     * rectangular shape in east/north space. This method returns a box that
071     * contains this shape.
072     *
073     * @return EastNorth box around the lat/lon world bounds
074     */
075    ProjectionBounds getWorldBoundsBoxEastNorth();
076
077    /**
078     * Find lat/lon-box containing all the area of a given rectangle in
079     * east/north space.
080     *
081     * This is an approximate method. Points outside of the world should be ignored.
082     *
083     * @param pb the rectangle in projected space
084     * @return minimum lat/lon box, that when projected, covers <code>pb</code>
085     */
086    Bounds getLatLonBoundsBox(ProjectionBounds pb);
087
088    /**
089     * Get the number of meters per unit of this projection. This more
090     * defines the scale of the map, than real conversion of unit to meters
091     * as this value is more less correct only along certain lines of true scale.
092     *
093     * Used by WMTS to properly scale tiles
094     * @return meters per unit of projection
095     */
096    double getMetersPerUnit();
097
098    /**
099     * Does this projection natural order of coordinates is North East,
100     * instead of East North
101     *
102     * @return true if natural order of coordinates is North East, false if East North
103     */
104    boolean switchXY();
105
106    /**
107     * Gets the object used as cache identifier when caching results of this projection.
108     * @return The object to use as cache key
109     * @since 10827
110     */
111    default Object getCacheKey() {
112        return this;
113    }
114}