mirror of https://github.com/apache/lucene.git
LUCENE-8095: Improve javadocs for circle constructors, and rename some variables.
This commit is contained in:
parent
952f4c4e59
commit
8b732099c7
|
@ -26,27 +26,40 @@ public class GeoCircleFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a GeoCircle of the right kind given the specified bounds.
|
||||
* Create a GeoCircle from a center and a cutoff angle. The resulting shape is a circle in spherical
|
||||
* planets, otherwise is an ellipse. It is the most efficient shape to represent a circle on a sphere.
|
||||
*
|
||||
* @param planetModel is the planet model.
|
||||
* @param latitude is the center latitude.
|
||||
* @param longitude is the center longitude.
|
||||
* @param radius is the radius angle.
|
||||
* @param cutoffAngle is the cutoff angle.
|
||||
* @return a GeoCircle corresponding to what was specified.
|
||||
*/
|
||||
public static GeoCircle makeGeoCircle(final PlanetModel planetModel, final double latitude, final double longitude, final double radius) {
|
||||
if (radius < Vector.MINIMUM_ANGULAR_RESOLUTION) {
|
||||
public static GeoCircle makeGeoCircle(final PlanetModel planetModel, final double latitude, final double longitude, final double cutoffAngle) {
|
||||
if (cutoffAngle < Vector.MINIMUM_ANGULAR_RESOLUTION) {
|
||||
return new GeoDegeneratePoint(planetModel, latitude, longitude);
|
||||
}
|
||||
return new GeoStandardCircle(planetModel, latitude, longitude, radius);
|
||||
return new GeoStandardCircle(planetModel, latitude, longitude, cutoffAngle);
|
||||
}
|
||||
|
||||
/** Create an exact GeoCircle given specified bounds and desired accuracy.
|
||||
/**
|
||||
* Create an GeoCircle from a center, a radius and a desired accuracy. It is the most accurate shape to represent
|
||||
* a circle in non-spherical planets.
|
||||
* <p>
|
||||
* The accuracy of the circle is defined as the maximum linear distance between any point on the
|
||||
* surface circle and planes that describe the circle. Therefore, with planet model WSG84, since the
|
||||
* radius of earth is 6,371,000 meters, an accuracy of 1e-6 corresponds to 6.3 meters.
|
||||
* For an accuracy of 1.0 meters, the accuracy value would be 1.6e-7. The maximum accuracy possible is 1e-12.
|
||||
* <p>
|
||||
* Note that this method may thrown an IllegalArgumentException if the circle being specified cannot be
|
||||
* represented by plane approximation given the planet model provided.
|
||||
*
|
||||
* @param planetModel is the planet model.
|
||||
* @param latitude is the center latitude.
|
||||
* @param longitude is the center longitude.
|
||||
* @param radius is the radius surface distance.
|
||||
* @param accuracy is the maximum linear distance between the circle approximation and the real circle, as computed using
|
||||
* the Vincenty formula.
|
||||
* @param accuracy is the maximum linear distance between the circle approximation and the real circle,
|
||||
* as computed using the Vincenty formula.
|
||||
* @return a GeoCircle corresponding to what was specified.
|
||||
*/
|
||||
public static GeoCircle makeExactGeoCircle(final PlanetModel planetModel, final double latitude, final double longitude, final double radius, final double accuracy) {
|
||||
|
|
|
@ -24,44 +24,47 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Circular area with a center and radius.
|
||||
* Circular area with a center and a radius that represents the surface distance to the center.
|
||||
* The circle is divided in sectors where the circle edge is approximated using Vincenty formulae.
|
||||
* The higher is the precision the more sectors are needed to describe the shape and therefore a penalty
|
||||
* in performance.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
class GeoExactCircle extends GeoBaseCircle {
|
||||
/** Center of circle */
|
||||
protected final GeoPoint center;
|
||||
/** Cutoff angle of circle (not quite the same thing as radius) */
|
||||
protected final double cutoffAngle;
|
||||
/** Radius of circle */
|
||||
protected final double radius;
|
||||
/** Actual accuracy */
|
||||
protected final double actualAccuracy;
|
||||
/** A point that is on the world and on the circle plane */
|
||||
/** A point that is on the edge of the circle */
|
||||
protected final GeoPoint[] edgePoints;
|
||||
/** Slices of the circle. */
|
||||
/** Slices of the circle */
|
||||
protected final List<CircleSlice> circleSlices;
|
||||
|
||||
/** Constructor.
|
||||
*@param planetModel is the planet model.
|
||||
*@param lat is the center latitude.
|
||||
*@param lon is the center longitude.
|
||||
*@param cutoffAngle is the surface radius for the circle.
|
||||
*@param accuracy is the allowed error value (linear distance).
|
||||
*@param radius is the surface radius for the circle.
|
||||
*@param accuracy is the allowed error value (linear distance). Maximum accuracy is 1e-12.
|
||||
*/
|
||||
public GeoExactCircle(final PlanetModel planetModel, final double lat, final double lon, final double cutoffAngle, final double accuracy) {
|
||||
public GeoExactCircle(final PlanetModel planetModel, final double lat, final double lon, final double radius, final double accuracy) {
|
||||
super(planetModel);
|
||||
if (lat < -Math.PI * 0.5 || lat > Math.PI * 0.5)
|
||||
throw new IllegalArgumentException("Latitude out of bounds");
|
||||
if (lon < -Math.PI || lon > Math.PI)
|
||||
throw new IllegalArgumentException("Longitude out of bounds");
|
||||
if (cutoffAngle < 0.0)
|
||||
throw new IllegalArgumentException("Cutoff angle out of bounds");
|
||||
if (cutoffAngle < Vector.MINIMUM_RESOLUTION)
|
||||
throw new IllegalArgumentException("Cutoff angle cannot be effectively zero");
|
||||
if (planetModel.minimumPoleDistance - cutoffAngle < Vector.MINIMUM_RESOLUTION)
|
||||
throw new IllegalArgumentException("Cutoff angle out of bounds. It cannot be bigger than " + planetModel.minimumPoleDistance + " for this planet model");
|
||||
if (radius < 0.0)
|
||||
throw new IllegalArgumentException("Radius out of bounds");
|
||||
if (radius < Vector.MINIMUM_RESOLUTION)
|
||||
throw new IllegalArgumentException("Radius cannot be effectively zero");
|
||||
if (planetModel.minimumPoleDistance - radius < Vector.MINIMUM_RESOLUTION)
|
||||
throw new IllegalArgumentException("Radius out of bounds. It cannot be bigger than " + planetModel.minimumPoleDistance + " for this planet model");
|
||||
|
||||
this.center = new GeoPoint(planetModel, lat, lon);
|
||||
this.cutoffAngle = cutoffAngle;
|
||||
this.radius = radius;
|
||||
|
||||
if (accuracy < Vector.MINIMUM_RESOLUTION) {
|
||||
actualAccuracy = Vector.MINIMUM_RESOLUTION;
|
||||
|
@ -72,10 +75,10 @@ class GeoExactCircle extends GeoBaseCircle {
|
|||
// We construct approximation planes until we have a low enough error estimate
|
||||
final List<ApproximationSlice> slices = new ArrayList<>(100);
|
||||
// Construct four cardinal points, and then we'll build the first two planes
|
||||
final GeoPoint northPoint = planetModel.surfacePointOnBearing(center, cutoffAngle, 0.0);
|
||||
final GeoPoint southPoint = planetModel.surfacePointOnBearing(center, cutoffAngle, Math.PI);
|
||||
final GeoPoint eastPoint = planetModel.surfacePointOnBearing(center, cutoffAngle, Math.PI * 0.5);
|
||||
final GeoPoint westPoint = planetModel.surfacePointOnBearing(center, cutoffAngle, Math.PI * 1.5);
|
||||
final GeoPoint northPoint = planetModel.surfacePointOnBearing(center, radius, 0.0);
|
||||
final GeoPoint southPoint = planetModel.surfacePointOnBearing(center, radius, Math.PI);
|
||||
final GeoPoint eastPoint = planetModel.surfacePointOnBearing(center, radius, Math.PI * 0.5);
|
||||
final GeoPoint westPoint = planetModel.surfacePointOnBearing(center, radius, Math.PI * 1.5);
|
||||
|
||||
final GeoPoint edgePoint;
|
||||
if (planetModel.c > planetModel.ab) {
|
||||
|
@ -101,9 +104,9 @@ class GeoExactCircle extends GeoBaseCircle {
|
|||
// To do this, we need to look at the part of the circle that will have the greatest error.
|
||||
// We will need to compute bearing points for these.
|
||||
final double interpPoint1Bearing = (thisSlice.point1Bearing + thisSlice.middlePointBearing) * 0.5;
|
||||
final GeoPoint interpPoint1 = planetModel.surfacePointOnBearing(center, cutoffAngle, interpPoint1Bearing);
|
||||
final GeoPoint interpPoint1 = planetModel.surfacePointOnBearing(center, radius, interpPoint1Bearing);
|
||||
final double interpPoint2Bearing = (thisSlice.point2Bearing + thisSlice.middlePointBearing) * 0.5;
|
||||
final GeoPoint interpPoint2 = planetModel.surfacePointOnBearing(center, cutoffAngle, interpPoint2Bearing);
|
||||
final GeoPoint interpPoint2 = planetModel.surfacePointOnBearing(center, radius, interpPoint2Bearing);
|
||||
|
||||
// Is this point on the plane? (that is, is the approximation good enough?)
|
||||
if (!thisSlice.mustSplit && Math.abs(thisSlice.plane.evaluate(interpPoint1)) < actualAccuracy && Math.abs(thisSlice.plane.evaluate(interpPoint2)) < actualAccuracy) {
|
||||
|
@ -145,13 +148,13 @@ class GeoExactCircle extends GeoBaseCircle {
|
|||
public void write(final OutputStream outputStream) throws IOException {
|
||||
SerializableObject.writeDouble(outputStream, center.getLatitude());
|
||||
SerializableObject.writeDouble(outputStream, center.getLongitude());
|
||||
SerializableObject.writeDouble(outputStream, cutoffAngle);
|
||||
SerializableObject.writeDouble(outputStream, radius);
|
||||
SerializableObject.writeDouble(outputStream, actualAccuracy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRadius() {
|
||||
return cutoffAngle;
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -235,14 +238,14 @@ class GeoExactCircle extends GeoBaseCircle {
|
|||
if (!(o instanceof GeoExactCircle))
|
||||
return false;
|
||||
GeoExactCircle other = (GeoExactCircle) o;
|
||||
return super.equals(other) && other.center.equals(center) && other.cutoffAngle == cutoffAngle && other.actualAccuracy == actualAccuracy;
|
||||
return super.equals(other) && other.center.equals(center) && other.radius == radius && other.actualAccuracy == actualAccuracy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + center.hashCode();
|
||||
long temp = Double.doubleToLongBits(cutoffAngle);
|
||||
long temp = Double.doubleToLongBits(radius);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(actualAccuracy);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
|
@ -251,7 +254,7 @@ class GeoExactCircle extends GeoBaseCircle {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GeoExactCircle: {planetmodel=" + planetModel+", center=" + center + ", radius=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + "), accuracy=" + actualAccuracy + "}";
|
||||
return "GeoExactCircle: {planetmodel=" + planetModel+", center=" + center + ", radius=" + radius + "(" + radius * 180.0 / Math.PI + "), accuracy=" + actualAccuracy + "}";
|
||||
}
|
||||
|
||||
/** A temporary description of a section of circle.
|
||||
|
|
|
@ -21,7 +21,9 @@ import java.io.OutputStream;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Circular area with a center and radius.
|
||||
* Circular area with a center and cutoff angle that represents the latitude and longitude distance
|
||||
* from the center where the planet will be cut. The resulting area is a circle for spherical
|
||||
* planets and an ellipse otherwise.
|
||||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue