LUCENE-6487: Geo3D with WGS84 patch from Karl: GeoPoint.getLat & getLon.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene6487@1682021 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
David Wayne Smiley 2015-05-27 13:34:52 +00:00
parent 560f3a1a01
commit 0a00734a60
4 changed files with 67 additions and 10 deletions

View File

@ -24,30 +24,79 @@ package org.apache.lucene.spatial.spatial4j.geo3d;
*/
public class GeoPoint extends Vector {
/** This is the lazily-evaluated magnitude. Some constructors include it, but others don't, and
* we try not to create extra computation by always computing it. */
protected double magnitude = Double.NEGATIVE_INFINITY;
/** Construct a GeoPoint from the trig functions of a lat and lon pair.
* @param planetModel is the planetModel to put the point on.
* @param sinLat is the sin of the latitude.
* @param sinLon is the sin of the longitude.
* @param cosLat is the cos of the latitude.
* @param cosLon is the cos of the longitude.
*/
public GeoPoint(final PlanetModel planetModel, final double sinLat, final double sinLon, final double cosLat, final double cosLon) {
this(computeMagnitude(planetModel, cosLat * cosLon, cosLat * sinLon, sinLat),
this(computeDesiredEllipsoidMagnitude(planetModel, cosLat * cosLon, cosLat * sinLon, sinLat),
cosLat * cosLon, cosLat * sinLon, sinLat);
}
/** Construct a GeoPoint from a latitude/longitude pair.
* @param planetModel is the planetModel to put the point on.
* @param lat is the latitude.
* @param lon is the longitude.
*/
public GeoPoint(final PlanetModel planetModel, final double lat, final double lon) {
this(planetModel, Math.sin(lat), Math.sin(lon), Math.cos(lat), Math.cos(lon));
}
/** Construct a GeoPoint from a unit (x,y,z) vector and a magnitude.
* @param magnitude is the desired magnitude, provided to put the point on the ellipsoid.
* @param x is the unit x value.
* @param y is the unit y value.
* @param z is the unit z value.
*/
public GeoPoint(final double magnitude, final double x, final double y, final double z) {
super(x * magnitude, y * magnitude, z * magnitude);
this.magnitude = magnitude;
}
/** Construct a GeoPoint from an (x,y,z) value.
* The (x,y,z) tuple must be on the desired ellipsoid.
* @param x is the ellipsoid point x value.
* @param y is the ellipsoid point y value.
* @param z is the ellipsoid point z value.
*/
public GeoPoint(final double x, final double y, final double z) {
super(x, y, z);
}
/** Compute an arc distance between two points.
* @param v is the second point.
* @return the angle, in radians, between the two points.
*/
public double arcDistance(final GeoPoint v) {
return Tools.safeAcos(dotProduct(v)/(magnitude() * v.magnitude()));
}
/** Compute the latitude for the point.
*@return the latitude.
*/
public double getLatitude() {
return Math.asin(z / magnitude() );
}
/** Compute the longitude for the point.
* @return the longitude value. Uses 0.0 if there is no computable longitude.
*/
public double getLongitude() {
if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(y) < MINIMUM_RESOLUTION)
return 0.0;
return Math.atan2(y,z);
}
/** Compute the linear magnitude of the point.
* @return the magnitude.
*/
@Override
public double magnitude() {
if (this.magnitude == Double.NEGATIVE_INFINITY) {

View File

@ -56,7 +56,7 @@ public class Plane extends Vector {
*/
public Plane(final PlanetModel planetModel, final double sinLat) {
super(0.0, 0.0, 1.0);
D = -sinLat * computeMagnitude(planetModel, sinLat);
D = -sinLat * computeDesiredEllipsoidMagnitude(planetModel, sinLat);
}
/**

View File

@ -307,20 +307,28 @@ public class Vector {
return Math.sqrt(x * x + y * y + z * z);
}
/** Compute the magnitude of a vector projected to a given
/** Compute the desired magnitude of a unit vector projected to a given
* planet model.
* @param planetModel is the planet model.
* @param x is the unit vector x value.
* @param y is the unit vector y value.
* @param z is the unit vector z value.
* @return a magnitude value for that (x,y,z) that projects the vector onto the specified ellipsoid.
*/
protected static double computeMagnitude(final PlanetModel planetModel, final double x, final double y, final double z) {
protected static double computeDesiredEllipsoidMagnitude(final PlanetModel planetModel, final double x, final double y, final double z) {
return 1.0 / Math.sqrt(x*x*planetModel.inverseAbSquared + y*y*planetModel.inverseAbSquared + z*z*planetModel.inverseCSquared);
}
/** Compute the magnitude of a vector projected to a given
* planet model.
/** Compute the desired magnitude of a unit vector projected to a given
* planet model. The unit vector is specified only by a z value.
* @param planetModel is the planet model.
* @param z is the unit vector z value.
* @return a magnitude value for that z value that projects the vector onto the specified ellipsoid.
*/
protected static double computeMagnitude(final PlanetModel planetModel, final double z) {
protected static double computeDesiredEllipsoidMagnitude(final PlanetModel planetModel, final double z) {
return 1.0 / Math.sqrt((1.0-z*z)*planetModel.inverseAbSquared + z*z*planetModel.inverseCSquared);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Vector))

View File

@ -237,7 +237,7 @@ public abstract class Geo3dShapeRectRelationTestCase extends RandomizedShapeTest
}
private Point geoPointToSpatial4jPoint(GeoPoint geoPoint) {
return ctx.makePoint(geoPoint.x * DistanceUtils.RADIANS_TO_DEGREES,
geoPoint.y * DistanceUtils.RADIANS_TO_DEGREES);
return ctx.makePoint(geoPoint.getLongitude() * DistanceUtils.RADIANS_TO_DEGREES,
geoPoint.getLongitude() * DistanceUtils.RADIANS_TO_DEGREES);
}
}