001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.projection;
003
004import java.util.Map;
005
006import org.openstreetmap.josm.data.ProjectionBounds;
007import org.openstreetmap.josm.data.coor.EastNorth;
008import org.openstreetmap.josm.data.coor.ILatLon;
009import org.openstreetmap.josm.data.coor.LatLon;
010
011/**
012 * Classes implementing this are able to project between screen (east/north) and {@link LatLon} coordinates.
013 * <p>
014 * Each instance is backed by a base projection but may e.g. offset the resulting position.
015 * @author Michael Zangl
016 * @since 10805
017 */
018public interface Projecting {
019
020    /**
021     * Convert from lat/lon to easting/northing.
022     * <p>
023     * This method exists to not break binary compatibility with old plugins
024     *
025     * @param ll the geographical point to convert (in WGS84 lat/lon)
026     * @return the corresponding east/north coordinates
027     * @see ILatLon#getEastNorth(Projecting)
028     */
029    default EastNorth latlon2eastNorth(LatLon ll) {
030        return latlon2eastNorth((ILatLon) ll);
031    }
032
033    /**
034     * Convert from lat/lon to easting/northing. This method uses the newer {@link ILatLon} interface.
035     *
036     * @param ll the geographical point to convert (in WGS84 lat/lon)
037     * @return the corresponding east/north coordinates
038     * @see ILatLon#getEastNorth(Projecting) as shorthand.
039     * @since 12161
040     */
041    EastNorth latlon2eastNorth(ILatLon ll);
042
043    /**
044     * Convert a east/north coordinate to the {@link LatLon} coordinate.
045     * This method clamps the lat/lon coordinate to the nearest point in the world bounds.
046     * @param en east/north
047     * @return The lat/lon coordinate.
048     */
049    LatLon eastNorth2latlonClamped(EastNorth en);
050
051    /**
052     * Gets the base projection instance used.
053     * This may be the same as this one or a different one if this one is translated in east/north space.
054     * @return The projection.
055     */
056    Projection getBaseProjection();
057
058    /**
059     * Returns an map or (subarea, projecting) paris that contains projecting instances to convert the coordinates inside the given area.
060     * This can be used by projections to support continuous projections.
061     *
062     * It is possible that the area covered by the map is bigger than the one given as area. There may be holes.
063     * @param area The base area
064     * @return a map of non-overlapping {@link ProjectionBounds} instances mapped to the {@link Projecting} object to use for that area.
065     */
066    Map<ProjectionBounds, Projecting> getProjectingsForArea(ProjectionBounds area);
067
068    /**
069     * Gets the object used as cache identifier when caching results of this projection.
070     * @return The object to use as cache key
071     * @since 10827
072     */
073    default Object getCacheKey() {
074        return this;
075    }
076}