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 protected final int computeHashCode(int init) { 116 final int prime = 31; 117 int result = init; 118 long temp; 119 temp = java.lang.Double.doubleToLongBits(x); 120 result = prime * result + (int) (temp ^ (temp >>> 32)); 121 temp = java.lang.Double.doubleToLongBits(y); 122 result = prime * result + (int) (temp ^ (temp >>> 32)); 123 return result; 124 } 125 126 @Override 127 public int hashCode() { 128 return computeHashCode(1); 129 } 130 131 @Override 132 public boolean equals(Object obj) { 133 if (this == obj) 134 return true; 135 if (obj == null || getClass() != obj.getClass()) 136 return false; 137 Coordinate other = (Coordinate) obj; 138 if (java.lang.Double.doubleToLongBits(x) != java.lang.Double.doubleToLongBits(other.x)) 139 return false; 140 if (java.lang.Double.doubleToLongBits(y) != java.lang.Double.doubleToLongBits(other.y)) 141 return false; 142 return true; 143 } 144}