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 * Converts to single point BBox. 096 * 097 * @return single point BBox defined by this coordinate. 098 * @since 6203 099 */ 100 public BBox toBBox() { 101 return new BBox(x, y); 102 } 103 104 /** 105 * Creates bbox around this coordinate. Coordinate defines 106 * center of bbox, its edge will be 2*r. 107 * 108 * @param r size 109 * @return BBox around this coordinate 110 * @since 6203 111 */ 112 public BBox toBBox(final double r) { 113 return new BBox(x - r, y - r, x + r, y + r); 114 } 115 116 @Override 117 public int hashCode() { 118 return Objects.hash(x, y); 119 } 120 121 @Override 122 public boolean equals(Object obj) { 123 if (this == obj) return true; 124 if (obj == null || getClass() != obj.getClass()) return false; 125 Coordinate that = (Coordinate) obj; 126 return Double.compare(that.x, x) == 0 && 127 Double.compare(that.y, y) == 0; 128 } 129}