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