001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.imagery; 003 004import java.awt.geom.AffineTransform; 005import java.awt.geom.Point2D; 006 007import org.openstreetmap.gui.jmapviewer.interfaces.IProjected; 008 009/** 010 * Class that fixes the position of a tile in a given coordinate space. 011 * 012 * This is done by storing the coordinates of the tile origin and the opposite 013 * tile corner. 014 * <p> 015 * It may represent a reprojected tile, i.e. the tile is rotated / deformed in an 016 * arbitrary way. In general, the tile origin cannot be expected to be the 017 * upper left corner of the rectangle that is spanned by the 2 points. 018 * <p> 019 * The coordinate space may be 020 * <ul> 021 * <li>pixel coordinates of the image file</li> 022 * <li>projected coordinates (east / north)</li> 023 * <li>screen pixel coordinates</li> 024 * </ul> 025 * @since 11846 026 */ 027public class TileAnchor { 028 029 protected final Point2D tileOrigin, nextTileOrigin; 030 031 /** 032 * Create a new tile anchor. 033 * @param tileOrigin position of the tile origin 034 * @param nextTileOrigin position of the opposite tile corner, i.e. the 035 * origin of the tile with index (x+1,y+1), when current tile has index (x,y) 036 */ 037 public TileAnchor(Point2D tileOrigin, Point2D nextTileOrigin) { 038 this.tileOrigin = tileOrigin; 039 this.nextTileOrigin = nextTileOrigin; 040 } 041 042 public TileAnchor(IProjected tileOrigin, IProjected nextTileOrigin) { 043 this.tileOrigin = new Point2D.Double(tileOrigin.getEast(), tileOrigin.getNorth()); 044 this.nextTileOrigin = new Point2D.Double(nextTileOrigin.getEast(), nextTileOrigin.getNorth()); 045 } 046 047 public Point2D getTileOrigin() { 048 return tileOrigin; 049 } 050 051 public Point2D getNextTileOrigin() { 052 return nextTileOrigin; 053 } 054 055 @Override 056 public String toString() { 057 return "TileAnchor{" + tileOrigin + "; " + nextTileOrigin + '}'; 058 } 059 060 /** 061 * Create a transformation that converts points from this coordinate space 062 * to another coordinate space. 063 * @param other tile anchor of the tile in the target coordinate space 064 * @return affine transformation from this coordinate space to the target 065 * coordinate space 066 */ 067 public AffineTransform convert(TileAnchor other) { 068 Point2D src1 = this.getTileOrigin(); 069 Point2D src2 = this.getNextTileOrigin(); 070 Point2D dest1 = other.getTileOrigin(); 071 Point2D dest2 = other.getNextTileOrigin(); 072 073 double scaleX = (dest2.getX() - dest1.getX()) / (src2.getX() - src1.getX()); 074 double scaleY = (dest2.getY() - dest1.getY()) / (src2.getY() - src1.getY()); 075 double offsetX0 = dest1.getX() - scaleX * src1.getX(); 076 double offsetY0 = dest1.getY() - scaleY * src1.getY(); 077 return new AffineTransform(scaleX, 0, 0, scaleY, offsetX0, offsetY0); 078 } 079}