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 {
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 lat/lon to easting/northing.
027     *
028     * @param ll the geographical point to convert (in WGS84 lat/lon)
029     * @return the corresponding east/north coordinates
030     */
031    EastNorth latlon2eastNorth(LatLon ll);
032
033    /**
034     * Convert from easting/norting to lat/lon.
035     *
036     * @param en the geographical point to convert (in projected coordinates)
037     * @return the corresponding lat/lon (WGS84)
038     */
039    LatLon eastNorth2latlon(EastNorth en);
040
041    /**
042     * Describe the projection in one or two words.
043     * @return the name / description
044     */
045    @Override
046    String toString();
047
048    /**
049     * Return projection code.
050     *
051     * This should be a unique identifier.
052     * If projection supports parameters, return a different code
053     * for each set of parameters.
054     *
055     * The EPSG code can be used (if defined for the projection).
056     *
057     * @return the projection identifier
058     */
059    String toCode();
060
061    /**
062     * Get a filename compatible string (for the cache directory).
063     * @return the cache directory name (base name)
064     */
065    String getCacheDirectoryName();
066
067    /**
068     * Get the bounds of the world.
069     * @return the supported lat/lon rectangle for this projection
070     */
071    Bounds getWorldBoundsLatLon();
072
073    /**
074     * Get an approximate EastNorth box around the lat/lon world bounds.
075     *
076     * Note: The projection is only valid within the bounds returned by
077     * {@link #getWorldBoundsLatLon()}. The lat/lon bounds need not be a
078     * rectangular shape in east/north space. This method returns a box that
079     * contains this shape.
080     *
081     * @return EastNorth box around the lat/lon world bounds
082     */
083    ProjectionBounds getWorldBoundsBoxEastNorth();
084
085    /**
086     * Find lat/lon-box containing all the area of a given rectangle in
087     * east/north space.
088     *
089     * This is an approximate method. Points outside of the world should be ignored.
090     *
091     * @param pb the rectangle in projected space
092     * @return minimum lat/lon box, that when projected, covers <code>pb</code>
093     */
094    Bounds getLatLonBoundsBox(ProjectionBounds pb);
095
096    /**
097     * Get the number of meters per unit of this projection. This more
098     * defines the scale of the map, than real conversion of unit to meters
099     * as this value is more less correct only along certain lines of true scale.
100     *
101     * Used by WMTS to properly scale tiles
102     * @return meters per unit of projection
103     */
104    double getMetersPerUnit();
105
106    /**
107     * Does this projection natural order of coordinates is North East,
108     * instead of East North
109     *
110     * @return true if natural order of coordinates is North East, false if East North
111     */
112    boolean switchXY();
113}