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