001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.coor;
003
004import java.io.Serializable;
005
006import org.openstreetmap.josm.data.osm.BBox;
007
008/**
009 * Base class of points of both coordinate systems.
010 *
011 * The variables are default package protected to allow routines in the
012 * data package to access them directly.
013 *
014 * As the class itself is package protected too, it is not visible
015 * outside of the data package. Routines there should only use LatLon or
016 * EastNorth.
017 *
018 * @since 6162
019 */
020abstract class Coordinate implements Serializable {
021
022    protected final double x;
023    protected final double y;
024
025    /**
026     * Construct the point with latitude / longitude values.
027     *
028     * @param x X coordinate of the point.
029     * @param y Y coordinate of the point.
030     */
031    Coordinate(double x, double y) {
032        this.x = x; this.y = y;
033    }
034
035    public double getX() {
036        return x;
037    }
038
039    public double getY() {
040        return y;
041    }
042
043    /**
044     * Returns the euclidean distance from this {@code Coordinate} to a specified {@code Coordinate}.
045     * 
046     * @param coor the specified coordinate to be measured against this {@code Coordinate}
047     * @return the euclidean distance from this {@code Coordinate} to a specified {@code Coordinate}
048     * @since 6166
049     */
050    protected final double distance(final Coordinate coor) {
051        return distance(coor.x, coor.y);
052    }
053   
054    /**
055     * Returns the euclidean distance from this {@code Coordinate} to a specified coordinate.
056     * 
057     * @param px the X coordinate of the specified point to be measured against this {@code Coordinate}
058     * @param py the Y coordinate of the specified point to be measured against this {@code Coordinate}
059     * @return the euclidean distance from this {@code Coordinate} to a specified coordinate
060     * @since 6166
061     */
062    public final double distance(final double px, final double py) {
063        final double dx = this.x-px;
064        final double dy = this.y-py;
065        return Math.sqrt(dx*dx + dy*dy);
066    }
067   
068    /**
069     * Returns the square of the euclidean distance from this {@code Coordinate} to a specified {@code Coordinate}.
070     * 
071     * @param coor the specified coordinate to be measured against this {@code Coordinate}
072     * @return the square of the euclidean distance from this {@code Coordinate} to a specified {@code Coordinate}
073     * @since 6166
074     */
075    protected final double distanceSq(final Coordinate coor) {
076        return distanceSq(coor.x, coor.y);
077    }
078
079    /**
080     * Returns the square of euclidean distance from this {@code Coordinate} to a specified coordinate.
081     * 
082     * @param px the X coordinate of the specified point to be measured against this {@code Coordinate}
083     * @param py the Y coordinate of the specified point to be measured against this {@code Coordinate}
084     * @return the square of the euclidean distance from this {@code Coordinate} to a specified coordinate
085     * @since 6166
086     */
087    public final double distanceSq(final double px, final double py) {
088        final double dx = this.x-px;
089        final double dy = this.y-py;
090        return dx*dx + dy*dy;
091    }
092
093    /**
094     * Converts to single point BBox.
095     * 
096     * @return single point BBox defined by this coordinate.
097     * @since 6203
098     */
099    public BBox toBBox() {
100        return new BBox(x, y);
101    }
102    
103    /**
104     * Creates bbox around this coordinate. Coordinate defines
105     * center of bbox, its edge will be 2*r.
106     * 
107     * @param r size
108     * @return BBox around this coordinate
109     * @since 6203
110     */
111    public BBox toBBox(final double r) {
112        return new BBox(x - r, y - r, x + r, y + r);
113    }
114
115    @Override
116    public int hashCode() {
117        final int prime = 31;
118        int result = 1;
119        long temp;
120        temp = java.lang.Double.doubleToLongBits(x);
121        result = prime * result + (int) (temp ^ (temp >>> 32));
122        temp = java.lang.Double.doubleToLongBits(y);
123        result = prime * result + (int) (temp ^ (temp >>> 32));
124        return result;
125    }
126
127    @Override
128    public boolean equals(Object obj) {
129        if (this == obj)
130            return true;
131        if (obj == null || getClass() != obj.getClass())
132            return false;
133        Coordinate other = (Coordinate) obj;
134        if (java.lang.Double.doubleToLongBits(x) != java.lang.Double.doubleToLongBits(other.x))
135            return false;
136        if (java.lang.Double.doubleToLongBits(y) != java.lang.Double.doubleToLongBits(other.y))
137            return false;
138        return true;
139    }
140}