id summary reporter owner description type status priority milestone component version resolution keywords cc 12889 Rewrite MapView coordinate conversion to be more universal michael2402 team "I plan to move all coordinate conversion out of MapView into an extra class. This will be one of the main tasks of this year's GSoC. == MapViewState == That class will then contain the current MapView state (size, position, coordinate system) and has methods to convert between all coordinate systems: - Screen coordinates - Window coordinates - MapView coordinates (used for drawing) - EastNorth coordinates - LatLon coordinates (using the current coordinate system) [[Image(josm-coord-systems.png)]] The following conversion methods exist: - Convert any Point/EastNorth/LatLon object into a universal position object - Fast methods to convert LatLon -> Point, EastNorth -> Point, ... (whatever we need to be fast) - Convert LatLon rectangle to Polygon Whenever the MapView changes, a new MapViewState object is created. That way we can track view changes easilly. With this, we can add layer draw result caching or asynchronous rendering in the future. It has a getBounds() method that replaces the current bounding box that is passed on to Layer#paint() The center and other (corner, ...) positions are returned as MapViewPoint to make their use universal. == MapViewPoint == This object can be constructed from a position in any coordinate system. It is the universal representation of that point on the screen. You can convert it to any other coordinate system. This should not be used during drawing because it is slow but it makes much code easier to read and conversion between coordinate systems a lot smoother. Methods: - getOnScreen(): Point2D - getInWindow(): Point2D - getInMapView(): Point2D - getEastNorth(): EastNorth - getLatLon(): LatLon or null, but may wrap around at 180° if coordinate system supports it - getLatLonUnwrapped(): LatLon or null, prevents wrapping - if needed: getLatLonForced(): LatLon. Forces a LatLon conversion, returns something as useful as possible outside the coordinate system. - if needed: getLatLonClamped(): LatLon. The closest point inside the coordinate system. == Painting == I plan to add a new Layer#paint mechanism while doing this: - paint(Graphics2D, MapViewState) paints the whole layer and should not be overriden. It is split into: - beforePaint() sets up Graphics2D (anti-aliasing, opacity filters, ...) - paintData() the real paint method - paintSubLayers() if/when it is implemented. == 180° Problem == The center of the screen is always in the Range -180°...180°. When 180° wrapping is active and if the coordinate systems tells us that it supports it, LatLon coordinates will be mapped to the respective EastNorth coordinates. We do not paint anything twice, so if the user scrolled out too much we only draw 360° EastNort <-> LatLon conversion will do everything for simple nodes. We add a new method isAroundScreenWrap(LatLon, LatLon). It returns true if the horizontal distance between two LatLon objects would be more than 180° on the screen. We do not paint those (to avoid lines through the whole view when having zoomed out). Imagery is something special, I'll have a look on how to do it there. Converting Areas is more difficult. We do not need this often, mostly for e.g. computing bounds. The OsmDataLayer needs to handle this in a special way (split the bounds at 180° and search primitives twice). Other layers only get the bigger of the two bounds for backword compatibility if they do not implement the new paint(). They will not support painting over 180° but the user can move the view so that the other side of the world will get painted. == Implementation == (1) Implement MapViewPoint - done (2) Implement MapViewState and add a temporary `getState()` to the MapView that uses scale/center to compute a ViewState - done (3) Change MapView to only use the last MapViewState for view position handling. - done (4) Change the layer class to use that view state. (5) Change view undo/redo system to use that state." enhancement closed normal 16.08 Core fixed gsoc-core Don-vip bastiK stoecker