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