You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2016/03/09 17:00:12 UTC
[01/50] [abbrv] lucene-solr git commit: fix smoke tester to
understand newly old index
Repository: lucene-solr
Updated Branches:
refs/heads/apiv2 943f2709a -> ec4889a2b
fix smoke tester to understand newly old index
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/9617d3d4
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/9617d3d4
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/9617d3d4
Branch: refs/heads/apiv2
Commit: 9617d3d400ea4d6b3e00cf0b3a2c94598647bb4e
Parents: 9082d5f
Author: Mike McCandless <mi...@apache.org>
Authored: Mon Mar 7 10:38:04 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Mon Mar 7 10:38:04 2016 -0500
----------------------------------------------------------------------
dev-tools/scripts/smokeTestRelease.py | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9617d3d4/dev-tools/scripts/smokeTestRelease.py
----------------------------------------------------------------------
diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py
index aa367f6..87a772f 100644
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -1306,6 +1306,8 @@ def confirmAllReleasesAreTestedForBackCompat(smokeVersion, unpackPath):
# Mixed version test case; ignore it for our purposes because we only
# tally up the "tests single Lucene version" indices
continue
+ elif name == '5.0.0.singlesegment':
+ tup = 5, 0, 0
else:
raise RuntimeError('could not parse version %s' % name)
[21/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPath.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPath.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPath.java
deleted file mode 100755
index bc5b9cf..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPath.java
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * GeoShape representing a path across the surface of the globe,
- * with a specified half-width. Path is described by a series of points.
- * Distances are measured from the starting point along the path, and then at right
- * angles to the path.
- *
- * @lucene.experimental
- */
-public class GeoPath extends GeoBaseDistanceShape {
- /** The cutoff angle (width) */
- protected final double cutoffAngle;
-
- /** Sine of cutoff angle */
- protected final double sinAngle;
- /** Cosine of cutoff angle */
- protected final double cosAngle;
-
- /** The original list of path points */
- protected final List<GeoPoint> points = new ArrayList<GeoPoint>();
-
- /** A list of SegmentEndpoints */
- protected List<SegmentEndpoint> endPoints;
- /** A list of PathSegments */
- protected List<PathSegment> segments;
-
- /** A point on the edge */
- protected GeoPoint[] edgePoints;
-
- /** Set to true if path has been completely constructed */
- protected boolean isDone = false;
-
- /** Constructor.
- *@param planetModel is the planet model.
- *@param maxCutoffAngle is the width of the path, measured as an angle.
- *@param pathPoints are the points in the path.
- */
- public GeoPath(final PlanetModel planetModel, final double maxCutoffAngle, final GeoPoint[] pathPoints) {
- this(planetModel, maxCutoffAngle);
- Collections.addAll(points, pathPoints);
- done();
- }
-
- /** Piece-wise constructor. Use in conjunction with addPoint() and done().
- *@param planetModel is the planet model.
- *@param maxCutoffAngle is the width of the path, measured as an angle.
- */
- public GeoPath(final PlanetModel planetModel, final double maxCutoffAngle) {
- super(planetModel);
- if (maxCutoffAngle <= 0.0 || maxCutoffAngle > Math.PI * 0.5)
- throw new IllegalArgumentException("Cutoff angle out of bounds");
- this.cutoffAngle = maxCutoffAngle;
- this.cosAngle = Math.cos(maxCutoffAngle);
- this.sinAngle = Math.sin(maxCutoffAngle);
- }
-
- /** Add a point to the path.
- *@param lat is the latitude of the point.
- *@param lon is the longitude of the point.
- */
- public void addPoint(final double lat, final double lon) {
- if (isDone)
- throw new IllegalStateException("Can't call addPoint() if done() already called");
- points.add(new GeoPoint(planetModel, lat, lon));
- }
-
- /** Complete the path.
- */
- public void done() {
- if (isDone)
- throw new IllegalStateException("Can't call done() twice");
- if (points.size() == 0)
- throw new IllegalArgumentException("Path must have at least one point");
- isDone = true;
-
- endPoints = new ArrayList<>(points.size());
- segments = new ArrayList<>(points.size());
- // Compute an offset to use for all segments. This will be based on the minimum magnitude of
- // the entire ellipsoid.
- final double cutoffOffset = this.sinAngle * planetModel.getMinimumMagnitude();
-
- // First, build all segments. We'll then go back and build corresponding segment endpoints.
- GeoPoint lastPoint = null;
- for (final GeoPoint end : points) {
- if (lastPoint != null) {
- final Plane normalizedConnectingPlane = new Plane(lastPoint, end);
- if (normalizedConnectingPlane == null) {
- continue;
- }
- segments.add(new PathSegment(planetModel, lastPoint, end, normalizedConnectingPlane, cutoffOffset));
- }
- lastPoint = end;
- }
-
- if (segments.size() == 0) {
- // Simple circle
- double lat = points.get(0).getLatitude();
- double lon = points.get(0).getLongitude();
- // Compute two points on the circle, with the right angle from the center. We'll use these
- // to obtain the perpendicular plane to the circle.
- double upperLat = lat + cutoffAngle;
- double upperLon = lon;
- if (upperLat > Math.PI * 0.5) {
- upperLon += Math.PI;
- if (upperLon > Math.PI)
- upperLon -= 2.0 * Math.PI;
- upperLat = Math.PI - upperLat;
- }
- double lowerLat = lat - cutoffAngle;
- double lowerLon = lon;
- if (lowerLat < -Math.PI * 0.5) {
- lowerLon += Math.PI;
- if (lowerLon > Math.PI)
- lowerLon -= 2.0 * Math.PI;
- lowerLat = -Math.PI - lowerLat;
- }
- final GeoPoint upperPoint = new GeoPoint(planetModel, upperLat, upperLon);
- final GeoPoint lowerPoint = new GeoPoint(planetModel, lowerLat, lowerLon);
- final GeoPoint point = points.get(0);
-
- // Construct normal plane
- final Plane normalPlane = Plane.constructNormalizedZPlane(upperPoint, lowerPoint, point);
-
- final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(point, normalPlane, upperPoint, lowerPoint);
- endPoints.add(onlyEndpoint);
- this.edgePoints = new GeoPoint[]{onlyEndpoint.circlePlane.getSampleIntersectionPoint(planetModel, normalPlane)};
- return;
- }
-
- // Create segment endpoints. Use an appropriate constructor for the start and end of the path.
- for (int i = 0; i < segments.size(); i++) {
- final PathSegment currentSegment = segments.get(i);
-
- if (i == 0) {
- // Starting endpoint
- final SegmentEndpoint startEndpoint = new SegmentEndpoint(currentSegment.start,
- currentSegment.startCutoffPlane, currentSegment.ULHC, currentSegment.LLHC);
- endPoints.add(startEndpoint);
- this.edgePoints = new GeoPoint[]{currentSegment.ULHC};
- continue;
- }
-
- // General intersection case
- final PathSegment prevSegment = segments.get(i-1);
- // We construct four separate planes, and evaluate which one includes all interior points with least overlap
- final SidedPlane candidate1 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, prevSegment.URHC, currentSegment.ULHC, currentSegment.LLHC);
- final SidedPlane candidate2 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, currentSegment.ULHC, currentSegment.LLHC, prevSegment.LRHC);
- final SidedPlane candidate3 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, currentSegment.LLHC, prevSegment.LRHC, prevSegment.URHC);
- final SidedPlane candidate4 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, prevSegment.LRHC, prevSegment.URHC, currentSegment.ULHC);
-
- if (candidate1 == null && candidate2 == null && candidate3 == null && candidate4 == null) {
- // The planes are identical. We wouldn't need a circle at all except for the possibility of
- // backing up, which is hard to detect here.
- final SegmentEndpoint midEndpoint = new SegmentEndpoint(currentSegment.start,
- prevSegment.endCutoffPlane, currentSegment.startCutoffPlane, currentSegment.ULHC, currentSegment.LLHC);
- //don't need a circle at all. Special constructor...
- endPoints.add(midEndpoint);
- } else {
- endPoints.add(new SegmentEndpoint(currentSegment.start,
- prevSegment.endCutoffPlane, currentSegment.startCutoffPlane,
- prevSegment.URHC, prevSegment.LRHC,
- currentSegment.ULHC, currentSegment.LLHC,
- candidate1, candidate2, candidate3, candidate4));
- }
- }
- // Do final endpoint
- final PathSegment lastSegment = segments.get(segments.size()-1);
- endPoints.add(new SegmentEndpoint(lastSegment.end,
- lastSegment.endCutoffPlane, lastSegment.URHC, lastSegment.LRHC));
-
- }
-
- @Override
- protected double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- // Algorithm:
- // (1) If the point is within any of the segments along the path, return that value.
- // (2) If the point is within any of the segment end circles along the path, return that value.
- double currentDistance = 0.0;
- for (PathSegment segment : segments) {
- double distance = segment.pathDistance(planetModel, distanceStyle, x,y,z);
- if (distance != Double.MAX_VALUE)
- return currentDistance + distance;
- currentDistance += segment.fullPathDistance(distanceStyle);
- }
-
- int segmentIndex = 0;
- currentDistance = 0.0;
- for (SegmentEndpoint endpoint : endPoints) {
- double distance = endpoint.pathDistance(distanceStyle, x, y, z);
- if (distance != Double.MAX_VALUE)
- return currentDistance + distance;
- if (segmentIndex < segments.size())
- currentDistance += segments.get(segmentIndex++).fullPathDistance(distanceStyle);
- }
-
- return Double.MAX_VALUE;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- double minDistance = Double.MAX_VALUE;
- for (final SegmentEndpoint endpoint : endPoints) {
- final double newDistance = endpoint.outsideDistance(distanceStyle, x,y,z);
- if (newDistance < minDistance)
- minDistance = newDistance;
- }
- for (final PathSegment segment : segments) {
- final double newDistance = segment.outsideDistance(planetModel, distanceStyle, x, y, z);
- if (newDistance < minDistance)
- minDistance = newDistance;
- }
- return minDistance;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- for (SegmentEndpoint pathPoint : endPoints) {
- if (pathPoint.isWithin(x, y, z))
- return true;
- }
- for (PathSegment pathSegment : segments) {
- if (pathSegment.isWithin(x, y, z))
- return true;
- }
- return false;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
- // We look for an intersection with any of the exterior edges of the path.
- // We also have to look for intersections with the cones described by the endpoints.
- // Return "true" if any such intersections are found.
-
- // For plane intersections, the basic idea is to come up with an equation of the line that is
- // the intersection (if any). Then, find the intersections with the unit sphere (if any). If
- // any of the intersection points are within the bounds, then we've detected an intersection.
- // Well, sort of. We can detect intersections also due to overlap of segments with each other.
- // But that's an edge case and we won't be optimizing for it.
- //System.err.println(" Looking for intersection of plane "+plane+" with path "+this);
- for (final SegmentEndpoint pathPoint : endPoints) {
- if (pathPoint.intersects(planetModel, plane, notablePoints, bounds)) {
- return true;
- }
- }
-
- for (final PathSegment pathSegment : segments) {
- if (pathSegment.intersects(planetModel, plane, notablePoints, bounds)) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- // For building bounds, order matters. We want to traverse
- // never more than 180 degrees longitude at a pop or we risk having the
- // bounds object get itself inverted. So do the edges first.
- for (PathSegment pathSegment : segments) {
- pathSegment.getBounds(planetModel, bounds);
- }
- for (SegmentEndpoint pathPoint : endPoints) {
- pathPoint.getBounds(planetModel, bounds);
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoPath))
- return false;
- GeoPath p = (GeoPath) o;
- if (!super.equals(p))
- return false;
- if (cutoffAngle != p.cutoffAngle)
- return false;
- return points.equals(p.points);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp = Double.doubleToLongBits(cutoffAngle);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- result = 31 * result + points.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoPath: {planetmodel=" + planetModel+", width=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + "), points={" + points + "}}";
- }
-
- /**
- * This is precalculated data for segment endpoint.
- * Note well: This is not necessarily a circle. There are four cases:
- * (1) The path consists of a single endpoint. In this case, we build a simple circle with the proper cutoff offset.
- * (2) This is the end of a path. The circle plane must be constructed to go through two supplied points and be perpendicular to a connecting plane.
- * (2.5) Intersection, but the path on both sides is linear. We generate a circle, but we use the cutoff planes to limit its influence in the straight line case.
- * (3) This is an intersection in a path. We are supplied FOUR planes. If there are intersections within bounds for both upper and lower, then
- * we generate no circle at all. If there is one intersection only, then we generate a plane that includes that intersection, as well as the remaining
- * cutoff plane/edge plane points.
- */
- public static class SegmentEndpoint {
- /** The center point of the endpoint */
- public final GeoPoint point;
- /** A plane describing the circle */
- public final SidedPlane circlePlane;
- /** Pertinent cutoff planes from adjoining segments */
- public final Membership[] cutoffPlanes;
- /** Notable points for this segment endpoint */
- public final GeoPoint[] notablePoints;
- /** No notable points from the circle itself */
- public final static GeoPoint[] circlePoints = new GeoPoint[0];
- /** Null membership */
- public final static Membership[] NO_MEMBERSHIP = new Membership[0];
-
- /** Base case. Does nothing at all.
- */
- public SegmentEndpoint(final GeoPoint point) {
- this.point = point;
- this.circlePlane = null;
- this.cutoffPlanes = null;
- this.notablePoints = null;
- }
-
- /** Constructor for case (1).
- * Generate a simple circle cutoff plane.
- *@param point is the center point.
- *@param upperPoint is a point that must be on the circle plane.
- *@param lowerPoint is another point that must be on the circle plane.
- */
- public SegmentEndpoint(final GeoPoint point, final Plane normalPlane, final GeoPoint upperPoint, final GeoPoint lowerPoint) {
- this.point = point;
- // Construct a sided plane that goes through the two points and whose normal is in the normalPlane.
- this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, normalPlane, upperPoint, lowerPoint);
- this.cutoffPlanes = NO_MEMBERSHIP;
- this.notablePoints = circlePoints;
- }
-
- /** Constructor for case (2).
- * Generate an endpoint, given a single cutoff plane plus upper and lower edge points.
- *@param point is the center point.
- *@param cutoffPlane is the plane from the adjoining path segment marking the boundary between this endpoint and that segment.
- *@param topEdgePoint is a point on the cutoffPlane that should be also on the circle plane.
- *@param bottomEdgePoint is another point on the cutoffPlane that should be also on the circle plane.
- */
- public SegmentEndpoint(final GeoPoint point,
- final SidedPlane cutoffPlane, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) {
- this.point = point;
- this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane)};
- this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint};
- // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
- this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane, topEdgePoint, bottomEdgePoint);
- }
-
- /** Constructor for case (2.5).
- * Generate an endpoint, given two cutoff planes plus upper and lower edge points.
- *@param point is the center.
- *@param cutoffPlane1 is one adjoining path segment cutoff plane.
- *@param cutoffPlane2 is another adjoining path segment cutoff plane.
- *@param topEdgePoint is a point on the cutoffPlane that should be also on the circle plane.
- *@param bottomEdgePoint is another point on the cutoffPlane that should be also on the circle plane.
- */
- public SegmentEndpoint(final GeoPoint point,
- final SidedPlane cutoffPlane1, final SidedPlane cutoffPlane2, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) {
- this.point = point;
- this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)};
- this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint};
- // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
- this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane1, topEdgePoint, bottomEdgePoint);
- }
-
- /** Constructor for case (3).
- * Generate an endpoint for an intersection, given four points.
- *@param point is the center.
- *@param prevCutoffPlane is the previous adjoining segment cutoff plane.
- *@param nextCutoffPlane is the next path segment cutoff plane.
- *@param notCand2Point is a point NOT on candidate2.
- *@param notCand1Point is a point NOT on candidate1.
- *@param notCand3Point is a point NOT on candidate3.
- *@param notCand4Point is a point NOT on candidate4.
- *@param candidate1 one of four candidate circle planes.
- *@param candidate2 one of four candidate circle planes.
- *@param candidate3 one of four candidate circle planes.
- *@param candidate4 one of four candidate circle planes.
- */
- public SegmentEndpoint(final GeoPoint point,
- final SidedPlane prevCutoffPlane, final SidedPlane nextCutoffPlane,
- final GeoPoint notCand2Point, final GeoPoint notCand1Point,
- final GeoPoint notCand3Point, final GeoPoint notCand4Point,
- final SidedPlane candidate1, final SidedPlane candidate2, final SidedPlane candidate3, final SidedPlane candidate4) {
- // Note: What we really need is a single plane that goes through all four points.
- // Since that's not possible in the ellipsoid case (because three points determine a plane, not four), we
- // need an approximation that at least creates a boundary that has no interruptions.
- // There are three obvious choices for the third point: either (a) one of the two remaining points, or (b) the top or bottom edge
- // intersection point. (a) has no guarantee of continuity, while (b) is capable of producing something very far from a circle if
- // the angle between segments is acute.
- // The solution is to look for the side (top or bottom) that has an intersection within the shape. We use the two points from
- // the opposite side to determine the plane, AND we pick the third to be either of the two points on the intersecting side
- // PROVIDED that the other point is within the final circle we come up with.
- this.point = point;
-
- // We construct four separate planes, and evaluate which one includes all interior points with least overlap
- // (Constructed beforehand because we need them for degeneracy check)
-
- final boolean cand1IsOtherWithin = candidate1!=null?candidate1.isWithin(notCand1Point):false;
- final boolean cand2IsOtherWithin = candidate2!=null?candidate2.isWithin(notCand2Point):false;
- final boolean cand3IsOtherWithin = candidate3!=null?candidate3.isWithin(notCand3Point):false;
- final boolean cand4IsOtherWithin = candidate4!=null?candidate4.isWithin(notCand4Point):false;
-
- if (cand1IsOtherWithin && cand2IsOtherWithin && cand3IsOtherWithin && cand4IsOtherWithin) {
- // The only way we should see both within is if all four points are coplanar. In that case, we default to the simplest treatment.
- this.circlePlane = candidate1; // doesn't matter which
- this.notablePoints = new GeoPoint[]{notCand2Point, notCand3Point, notCand1Point, notCand4Point};
- this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane), new SidedPlane(nextCutoffPlane)};
- } else if (cand1IsOtherWithin) {
- // Use candidate1, and DON'T include prevCutoffPlane in the cutoff planes list
- this.circlePlane = candidate1;
- this.notablePoints = new GeoPoint[]{notCand2Point, notCand3Point, notCand4Point};
- this.cutoffPlanes = new Membership[]{new SidedPlane(nextCutoffPlane)};
- } else if (cand2IsOtherWithin) {
- // Use candidate2
- this.circlePlane = candidate2;
- this.notablePoints = new GeoPoint[]{notCand3Point, notCand4Point, notCand1Point};
- this.cutoffPlanes = new Membership[]{new SidedPlane(nextCutoffPlane)};
- } else if (cand3IsOtherWithin) {
- this.circlePlane = candidate3;
- this.notablePoints = new GeoPoint[]{notCand4Point, notCand1Point, notCand2Point};
- this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane)};
- } else if (cand4IsOtherWithin) {
- this.circlePlane = candidate4;
- this.notablePoints = new GeoPoint[]{notCand1Point, notCand2Point, notCand3Point};
- this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane)};
- } else {
- // dunno what happened
- throw new RuntimeException("Couldn't come up with a plane through three points that included the fourth");
- }
- }
-
- /** Check if point is within this endpoint.
- *@param point is the point.
- *@return true of within.
- */
- public boolean isWithin(final Vector point) {
- if (circlePlane == null)
- return false;
- if (!circlePlane.isWithin(point))
- return false;
- for (final Membership m : cutoffPlanes) {
- if (!m.isWithin(point)) {
- return false;
- }
- }
- return true;
- }
-
- /** Check if point is within this endpoint.
- *@param x is the point x.
- *@param y is the point y.
- *@param z is the point z.
- *@return true of within.
- */
- public boolean isWithin(final double x, final double y, final double z) {
- if (circlePlane == null)
- return false;
- if (!circlePlane.isWithin(x, y, z))
- return false;
- for (final Membership m : cutoffPlanes) {
- if (!m.isWithin(x,y,z)) {
- return false;
- }
- }
- return true;
- }
-
- /** Compute interior path distance.
- *@param distanceStyle is the distance style.
- *@param x is the point x.
- *@param y is the point y.
- *@param z is the point z.
- *@return the distance metric.
- */
- public double pathDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x,y,z))
- return Double.MAX_VALUE;
- return distanceStyle.computeDistance(this.point, x, y, z);
- }
-
- /** Compute external distance.
- *@param distanceStyle is the distance style.
- *@param x is the point x.
- *@param y is the point y.
- *@param z is the point z.
- *@return the distance metric.
- */
- public double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(this.point, x, y, z);
- }
-
- /** Determine if this endpoint intersects a specified plane.
- *@param planetModel is the planet model.
- *@param p is the plane.
- *@param notablePoints are the points associated with the plane.
- *@param bounds are any bounds which the intersection must lie within.
- *@return true if there is a matching intersection.
- */
- public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
- //System.err.println(" looking for intersection between plane "+p+" and circle "+circlePlane+" on proper side of "+cutoffPlanes+" within "+bounds);
- if (circlePlane == null)
- return false;
- return circlePlane.intersects(planetModel, p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
- }
-
- /** Get the bounds for a segment endpoint.
- *@param planetModel is the planet model.
- *@param bounds are the bounds to be modified.
- */
- public void getBounds(final PlanetModel planetModel, Bounds bounds) {
- bounds.addPoint(point);
- if (circlePlane == null)
- return;
- bounds.addPlane(planetModel, circlePlane);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof SegmentEndpoint))
- return false;
- SegmentEndpoint other = (SegmentEndpoint) o;
- return point.equals(other.point);
- }
-
- @Override
- public int hashCode() {
- return point.hashCode();
- }
-
- @Override
- public String toString() {
- return point.toString();
- }
- }
-
- /**
- * This is the pre-calculated data for a path segment.
- */
- public static class PathSegment {
- /** Starting point of the segment */
- public final GeoPoint start;
- /** End point of the segment */
- public final GeoPoint end;
- /** Place to keep any complete segment distances we've calculated so far */
- public final Map<DistanceStyle,Double> fullDistanceCache = new HashMap<DistanceStyle,Double>();
- /** Normalized plane connecting the two points and going through world center */
- public final Plane normalizedConnectingPlane;
- /** Cutoff plane parallel to connecting plane representing one side of the path segment */
- public final SidedPlane upperConnectingPlane;
- /** Cutoff plane parallel to connecting plane representing the other side of the path segment */
- public final SidedPlane lowerConnectingPlane;
- /** Plane going through the center and start point, marking the start edge of the segment */
- public final SidedPlane startCutoffPlane;
- /** Plane going through the center and end point, marking the end edge of the segment */
- public final SidedPlane endCutoffPlane;
- /** Upper right hand corner of segment */
- public final GeoPoint URHC;
- /** Lower right hand corner of segment */
- public final GeoPoint LRHC;
- /** Upper left hand corner of segment */
- public final GeoPoint ULHC;
- /** Lower left hand corner of segment */
- public final GeoPoint LLHC;
- /** Notable points for the upper connecting plane */
- public final GeoPoint[] upperConnectingPlanePoints;
- /** Notable points for the lower connecting plane */
- public final GeoPoint[] lowerConnectingPlanePoints;
- /** Notable points for the start cutoff plane */
- public final GeoPoint[] startCutoffPlanePoints;
- /** Notable points for the end cutoff plane */
- public final GeoPoint[] endCutoffPlanePoints;
-
- /** Construct a path segment.
- *@param planetModel is the planet model.
- *@param start is the starting point.
- *@param end is the ending point.
- *@param normalizedConnectingPlane is the connecting plane.
- *@param planeBoundingOffset is the linear offset from the connecting plane to either side.
- */
- public PathSegment(final PlanetModel planetModel, final GeoPoint start, final GeoPoint end,
- final Plane normalizedConnectingPlane, final double planeBoundingOffset) {
- this.start = start;
- this.end = end;
- this.normalizedConnectingPlane = normalizedConnectingPlane;
-
- // Either start or end should be on the correct side
- upperConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, -planeBoundingOffset);
- lowerConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, planeBoundingOffset);
- // Cutoff planes use opposite endpoints as correct side examples
- startCutoffPlane = new SidedPlane(end, normalizedConnectingPlane, start);
- endCutoffPlane = new SidedPlane(start, normalizedConnectingPlane, end);
- final Membership[] upperSide = new Membership[]{upperConnectingPlane};
- final Membership[] lowerSide = new Membership[]{lowerConnectingPlane};
- final Membership[] startSide = new Membership[]{startCutoffPlane};
- final Membership[] endSide = new Membership[]{endCutoffPlane};
- GeoPoint[] points;
- points = upperConnectingPlane.findIntersections(planetModel, startCutoffPlane, lowerSide, endSide);
- if (points.length == 0) {
- throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
- }
- this.ULHC = points[0];
- points = upperConnectingPlane.findIntersections(planetModel, endCutoffPlane, lowerSide, startSide);
- if (points.length == 0) {
- throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
- }
- this.URHC = points[0];
- points = lowerConnectingPlane.findIntersections(planetModel, startCutoffPlane, upperSide, endSide);
- if (points.length == 0) {
- throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
- }
- this.LLHC = points[0];
- points = lowerConnectingPlane.findIntersections(planetModel, endCutoffPlane, upperSide, startSide);
- if (points.length == 0) {
- throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
- }
- this.LRHC = points[0];
- upperConnectingPlanePoints = new GeoPoint[]{ULHC, URHC};
- lowerConnectingPlanePoints = new GeoPoint[]{LLHC, LRHC};
- startCutoffPlanePoints = new GeoPoint[]{ULHC, LLHC};
- endCutoffPlanePoints = new GeoPoint[]{URHC, LRHC};
- }
-
- /** Compute the full distance along this path segment.
- *@param distanceStyle is the distance style.
- *@return the distance metric.
- */
- public double fullPathDistance(final DistanceStyle distanceStyle) {
- synchronized (fullDistanceCache) {
- Double dist = fullDistanceCache.get(distanceStyle);
- if (dist == null) {
- dist = new Double(distanceStyle.computeDistance(start, end.x, end.y, end.z));
- fullDistanceCache.put(distanceStyle, dist);
- }
- return dist.doubleValue();
- }
- }
-
- /** Check if point is within this segment.
- *@param point is the point.
- *@return true of within.
- */
- public boolean isWithin(final Vector point) {
- return startCutoffPlane.isWithin(point) &&
- endCutoffPlane.isWithin(point) &&
- upperConnectingPlane.isWithin(point) &&
- lowerConnectingPlane.isWithin(point);
- }
-
- /** Check if point is within this segment.
- *@param x is the point x.
- *@param y is the point y.
- *@param z is the point z.
- *@return true of within.
- */
- public boolean isWithin(final double x, final double y, final double z) {
- return startCutoffPlane.isWithin(x, y, z) &&
- endCutoffPlane.isWithin(x, y, z) &&
- upperConnectingPlane.isWithin(x, y, z) &&
- lowerConnectingPlane.isWithin(x, y, z);
- }
-
- /** Compute interior path distance.
- *@param planetModel is the planet model.
- *@param distanceStyle is the distance style.
- *@param x is the point x.
- *@param y is the point y.
- *@param z is the point z.
- *@return the distance metric.
- */
- public double pathDistance(final PlanetModel planetModel, final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x,y,z))
- return Double.MAX_VALUE;
-
- // (1) Compute normalizedPerpPlane. If degenerate, then return point distance from start to point.
- // Want no allocations or expensive operations! so we do this the hard way
- final double perpX = normalizedConnectingPlane.y * z - normalizedConnectingPlane.z * y;
- final double perpY = normalizedConnectingPlane.z * x - normalizedConnectingPlane.x * z;
- final double perpZ = normalizedConnectingPlane.x * y - normalizedConnectingPlane.y * x;
- final double magnitude = Math.sqrt(perpX * perpX + perpY * perpY + perpZ * perpZ);
- if (Math.abs(magnitude) < Vector.MINIMUM_RESOLUTION)
- return distanceStyle.computeDistance(start, x,y,z);
- final double normFactor = 1.0/magnitude;
- final Plane normalizedPerpPlane = new Plane(perpX * normFactor, perpY * normFactor, perpZ * normFactor, 0.0);
-
- // Old computation: too expensive, because it calculates the intersection point twice.
- //return distanceStyle.computeDistance(planetModel, normalizedConnectingPlane, x, y, z, startCutoffPlane, endCutoffPlane) +
- // distanceStyle.computeDistance(planetModel, normalizedPerpPlane, start.x, start.y, start.z, upperConnectingPlane, lowerConnectingPlane);
-
- final GeoPoint[] intersectionPoints = normalizedConnectingPlane.findIntersections(planetModel, normalizedPerpPlane);
- GeoPoint thePoint;
- if (intersectionPoints.length == 0)
- throw new RuntimeException("Can't find world intersection for point x="+x+" y="+y+" z="+z);
- else if (intersectionPoints.length == 1)
- thePoint = intersectionPoints[0];
- else {
- if (startCutoffPlane.isWithin(intersectionPoints[0]) && endCutoffPlane.isWithin(intersectionPoints[0]))
- thePoint = intersectionPoints[0];
- else if (startCutoffPlane.isWithin(intersectionPoints[1]) && endCutoffPlane.isWithin(intersectionPoints[1]))
- thePoint = intersectionPoints[1];
- else
- throw new RuntimeException("Can't find world intersection for point x="+x+" y="+y+" z="+z);
- }
- return distanceStyle.computeDistance(thePoint, x, y, z) + distanceStyle.computeDistance(start, thePoint.x, thePoint.y, thePoint.z);
- }
-
- /** Compute external distance.
- *@param planetModel is the planet model.
- *@param distanceStyle is the distance style.
- *@param x is the point x.
- *@param y is the point y.
- *@param z is the point z.
- *@return the distance metric.
- */
- public double outsideDistance(final PlanetModel planetModel, final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double upperDistance = distanceStyle.computeDistance(planetModel, upperConnectingPlane, x,y,z, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
- final double lowerDistance = distanceStyle.computeDistance(planetModel, lowerConnectingPlane, x,y,z, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
- final double startDistance = distanceStyle.computeDistance(planetModel, startCutoffPlane, x,y,z, endCutoffPlane, lowerConnectingPlane, upperConnectingPlane);
- final double endDistance = distanceStyle.computeDistance(planetModel, endCutoffPlane, x,y,z, startCutoffPlane, lowerConnectingPlane, upperConnectingPlane);
- final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
- final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
- final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
- final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
- return Math.min(
- Math.min(
- Math.min(upperDistance,lowerDistance),
- Math.min(startDistance,endDistance)),
- Math.min(
- Math.min(ULHCDistance, URHCDistance),
- Math.min(LLHCDistance, LRHCDistance)));
- }
-
- /** Determine if this endpoint intersects a specified plane.
- *@param planetModel is the planet model.
- *@param p is the plane.
- *@param notablePoints are the points associated with the plane.
- *@param bounds are any bounds which the intersection must lie within.
- *@return true if there is a matching intersection.
- */
- public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
- return upperConnectingPlane.intersects(planetModel, p, notablePoints, upperConnectingPlanePoints, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
- lowerConnectingPlane.intersects(planetModel, p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
- }
-
- /** Get the bounds for a segment endpoint.
- *@param planetModel is the planet model.
- *@param bounds are the bounds to be modified.
- */
- public void getBounds(final PlanetModel planetModel, Bounds bounds) {
- // We need to do all bounding planes as well as corner points
- bounds.addPoint(start).addPoint(end).addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC);
- bounds.addPlane(planetModel, upperConnectingPlane, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
- bounds.addPlane(planetModel, lowerConnectingPlane, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
- bounds.addPlane(planetModel, startCutoffPlane, endCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
- bounds.addPlane(planetModel, endCutoffPlane, startCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPoint.java
deleted file mode 100755
index e8a265d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPoint.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * This class represents a point on the surface of a sphere or ellipsoid.
- *
- * @lucene.experimental
- */
-public class GeoPoint extends Vector {
-
- // By making lazily-evaluated variables be "volatile", we guarantee atomicity when they
- // are updated. This is necessary if we are using these classes in a multi-thread fashion,
- // because we don't try to synchronize for the lazy computation.
-
- /** 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. Does not need to be
- * synchronized for thread safety, because depends wholly on immutable variables of this class. */
- protected volatile double magnitude = Double.NEGATIVE_INFINITY;
- /** Lazily-evaluated latitude. Does not need to be
- * synchronized for thread safety, because depends wholly on immutable variables of this class. */
- protected volatile double latitude = Double.NEGATIVE_INFINITY;
- /** Lazily-evaluated longitude. Does not need to be
- * synchronized for thread safety, because depends wholly on immutable variables of this class. */
- protected volatile double longitude = 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.
- * @param lat is the latitude.
- * @param lon is the longitude.
- */
- public GeoPoint(final PlanetModel planetModel, final double sinLat, final double sinLon, final double cosLat, final double cosLon, final double lat, final double lon) {
- this(computeDesiredEllipsoidMagnitude(planetModel, cosLat * cosLon, cosLat * sinLon, sinLat),
- cosLat * cosLon, cosLat * sinLon, sinLat, lat, lon);
- }
-
- /** 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(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), lat, 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.
- * @param lat is the latitude.
- * @param lon is the longitude.
- */
- public GeoPoint(final double magnitude, final double x, final double y, final double z, double lat, double lon) {
- super(x * magnitude, y * magnitude, z * magnitude);
- this.magnitude = magnitude;
- if (lat > Math.PI * 0.5 || lat < -Math.PI * 0.5) {
- throw new IllegalArgumentException("Latitude " + lat + " is out of range: must range from -Math.PI/2 to Math.PI/2");
- }
- if (lon < -Math.PI || lon > Math.PI) {
- throw new IllegalArgumentException("Longitude " + lon + " is out of range: must range from -Math.PI to Math.PI");
- }
- this.latitude = lat;
- this.longitude = 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.
- * Note: this is an angular distance, and not a surface distance, and is therefore independent of planet model.
- * For surface distance, see {@link org.apache.lucene.geo3d.PlanetModel#surfaceDistance(GeoPoint, GeoPoint)}
- * @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 an arc distance between two points.
- * @param x is the x part of the second point.
- * @param y is the y part of the second point.
- * @param z is the z part of the second point.
- * @return the angle, in radians, between the two points.
- */
- public double arcDistance(final double x, final double y, final double z) {
- return Tools.safeAcos(dotProduct(x,y,z)/(magnitude() * Vector.magnitude(x,y,z)));
- }
-
- /** Compute the latitude for the point.
- * @return the latitude.
- */
- public double getLatitude() {
- double lat = this.latitude;//volatile-read once
- if (lat == Double.NEGATIVE_INFINITY)
- this.latitude = lat = Math.asin(z / magnitude());
- return lat;
- }
-
- /** Compute the longitude for the point.
- * @return the longitude value. Uses 0.0 if there is no computable longitude.
- */
- public double getLongitude() {
- double lon = this.longitude;//volatile-read once
- if (lon == Double.NEGATIVE_INFINITY) {
- if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(y) < MINIMUM_RESOLUTION)
- this.longitude = lon = 0.0;
- else
- this.longitude = lon = Math.atan2(y,x);
- }
- return lon;
- }
-
- /** Compute the linear magnitude of the point.
- * @return the magnitude.
- */
- @Override
- public double magnitude() {
- double mag = this.magnitude;//volatile-read once
- if (mag == Double.NEGATIVE_INFINITY) {
- this.magnitude = mag = super.magnitude();
- }
- return mag;
- }
-
- /** Compute whether point matches another.
- *@param x is the x value
- *@param y is the y value
- *@param z is the z value
- *@return true if the same.
- */
- public boolean isIdentical(final double x, final double y, final double z) {
- return Math.abs(this.x - x) < MINIMUM_RESOLUTION &&
- Math.abs(this.y - y) < MINIMUM_RESOLUTION &&
- Math.abs(this.z - z) < MINIMUM_RESOLUTION;
- }
-
- @Override
- public String toString() {
- if (this.longitude == Double.NEGATIVE_INFINITY) {
- return super.toString();
- }
- return "[lat="+getLatitude()+", lon="+getLongitude()+"]";
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygon.java
deleted file mode 100644
index 634406d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygon.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * GeoPolygon interface description.
- *
- * @lucene.experimental
- */
-public interface GeoPolygon extends GeoMembershipShape {
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygonFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygonFactory.java
deleted file mode 100755
index 0dc70a5..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoPolygonFactory.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-
-/**
- * Class which constructs a GeoMembershipShape representing an arbitrary polygon.
- *
- * @lucene.experimental
- */
-public class GeoPolygonFactory {
- private GeoPolygonFactory() {
- }
-
- /**
- * Create a GeoMembershipShape of the right kind given the specified bounds.
- *
- * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of.
- * @param convexPointIndex is the index of a single convex point whose conformation with
- * its neighbors determines inside/outside for the entire polygon.
- * @return a GeoPolygon corresponding to what was specified.
- */
- public static GeoPolygon makeGeoPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final int convexPointIndex) {
- // The basic operation uses a set of points, two points determining one particular edge, and a sided plane
- // describing membership.
- return buildPolygonShape(planetModel, pointList, convexPointIndex, getLegalIndex(convexPointIndex + 1, pointList.size()),
- new SidedPlane(pointList.get(getLegalIndex(convexPointIndex - 1, pointList.size())),
- pointList.get(convexPointIndex), pointList.get(getLegalIndex(convexPointIndex + 1, pointList.size()))),
- false);
- }
-
- /** Build a GeoMembershipShape given points, starting edge, and whether starting edge is internal or not.
- * @param pointsList is a list of the GeoPoints to build an arbitrary polygon out of.
- * @param startPointIndex is one of the points constituting the starting edge.
- * @param endPointIndex is another of the points constituting the starting edge.
- * @param startingEdge is the plane describing the starting edge.
- * @param isInternalEdge is true if the specified edge is an internal one.
- * @return a GeoMembershipShape corresponding to what was specified.
- */
- public static GeoPolygon buildPolygonShape(final PlanetModel planetModel, final List<GeoPoint> pointsList, final int startPointIndex, final int endPointIndex, final SidedPlane startingEdge, final boolean isInternalEdge) {
- // Algorithm as follows:
- // Start with sided edge. Go through all points in some order. For each new point, determine if the point is within all edges considered so far.
- // If not, put it into a list of points for recursion. If it is within, add new edge and keep going.
- // Once we detect a point that is within, if there are points put aside for recursion, then call recursively.
-
- // Current composite. This is what we'll actually be returning.
- final GeoCompositePolygon rval = new GeoCompositePolygon();
-
- final List<GeoPoint> recursionList = new ArrayList<GeoPoint>();
- final List<GeoPoint> currentList = new ArrayList<GeoPoint>();
- final BitSet internalEdgeList = new BitSet();
- final List<SidedPlane> currentPlanes = new ArrayList<SidedPlane>();
-
- // Initialize the current list and current planes
- currentList.add(pointsList.get(startPointIndex));
- currentList.add(pointsList.get(endPointIndex));
- internalEdgeList.set(currentPlanes.size(), isInternalEdge);
- currentPlanes.add(startingEdge);
-
- // Now, scan all remaining points, in order. We'll use an index and just add to it.
- for (int i = 0; i < pointsList.size() - 2; i++) {
- GeoPoint newPoint = pointsList.get(getLegalIndex(i + endPointIndex + 1, pointsList.size()));
- if (isWithin(newPoint, currentPlanes)) {
- // Construct a sided plane based on the last two points, and the previous point
- SidedPlane newBoundary = new SidedPlane(currentList.get(currentList.size() - 2), newPoint, currentList.get(currentList.size() - 1));
- // Construct a sided plane based on the return trip
- SidedPlane returnBoundary = new SidedPlane(currentList.get(currentList.size() - 1), currentList.get(0), newPoint);
- // Verify that none of the points beyond the new point in the list are inside the polygon we'd
- // be creating if we stopped making the current polygon right now.
- boolean pointInside = false;
- for (int j = i + 1; j < pointsList.size() - 2; j++) {
- GeoPoint checkPoint = pointsList.get(getLegalIndex(j + endPointIndex + 1, pointsList.size()));
- boolean isInside = true;
- if (isInside && !newBoundary.isWithin(checkPoint))
- isInside = false;
- if (isInside && !returnBoundary.isWithin(checkPoint))
- isInside = false;
- if (isInside) {
- for (SidedPlane plane : currentPlanes) {
- if (!plane.isWithin(checkPoint)) {
- isInside = false;
- break;
- }
- }
- }
- if (isInside) {
- pointInside = true;
- break;
- }
- }
- if (!pointInside) {
- // Any excluded points?
- boolean isInternalBoundary = recursionList.size() > 0;
- if (isInternalBoundary) {
- // Handle exclusion
- recursionList.add(newPoint);
- recursionList.add(currentList.get(currentList.size() - 1));
- if (recursionList.size() == pointsList.size()) {
- // We are trying to recurse with a list the same size as the one we started with.
- // Clearly, the polygon cannot be constructed
- throw new IllegalArgumentException("Polygon is illegal; cannot be decomposed into convex parts");
- }
- // We want the other side for the recursion
- SidedPlane otherSideNewBoundary = new SidedPlane(newBoundary);
- rval.addShape(buildPolygonShape(planetModel, recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
- recursionList.clear();
- }
- currentList.add(newPoint);
- internalEdgeList.set(currentPlanes.size(), isInternalBoundary);
- currentPlanes.add(newBoundary);
- } else {
- recursionList.add(newPoint);
- }
- } else {
- recursionList.add(newPoint);
- }
- }
-
- boolean returnEdgeInternalBoundary = recursionList.size() > 0;
- if (returnEdgeInternalBoundary) {
- // The last step back to the start point had a recursion, so take care of that before we complete our work
- recursionList.add(currentList.get(0));
- recursionList.add(currentList.get(currentList.size() - 1));
- if (recursionList.size() == pointsList.size()) {
- // We are trying to recurse with a list the same size as the one we started with.
- // Clearly, the polygon cannot be constructed
- throw new IllegalArgumentException("Polygon is illegal; cannot be decomposed into convex parts");
- }
- // Construct a sided plane based on these two points, and the previous point
- SidedPlane newBoundary = new SidedPlane(currentList.get(currentList.size() - 2), currentList.get(0), currentList.get(currentList.size() - 1));
- // We want the other side for the recursion
- SidedPlane otherSideNewBoundary = new SidedPlane(newBoundary);
- rval.addShape(buildPolygonShape(planetModel, recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
- recursionList.clear();
- }
- // Now, add in the current shape.
- rval.addShape(new GeoConvexPolygon(planetModel, currentList, internalEdgeList, returnEdgeInternalBoundary));
- //System.out.println("Done creating polygon");
- return rval;
- }
-
- /** Check if a point is within a described list of planes.
- *@param newPoint is the point.
- *@param currentPlanes is the list of planes.
- *@return true if within.
- */
- protected static boolean isWithin(final GeoPoint newPoint, final List<SidedPlane> currentPlanes) {
- for (SidedPlane p : currentPlanes) {
- if (!p.isWithin(newPoint))
- return false;
- }
- return true;
- }
-
- /** Convert raw point index into valid array position.
- *@param index is the array index.
- *@param size is the array size.
- *@return an updated index.
- */
- protected static int getLegalIndex(int index, int size) {
- while (index < 0) {
- index += size;
- }
- while (index >= size) {
- index -= size;
- }
- return index;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoRectangle.java
deleted file mode 100755
index fc2a531..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoRectangle.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box limited on four sides (top lat, bottom lat, left lon, right lon).
- * The left-right maximum extent for this shape is PI; for anything larger, use
- * GeoWideRectangle.
- *
- * @lucene.internal
- */
-public class GeoRectangle extends GeoBaseBBox {
- /** The top latitude of the rect */
- protected final double topLat;
- /** The bottom latitude of the rect */
- protected final double bottomLat;
- /** The left longitude of the rect */
- protected final double leftLon;
- /** The right longitude of the rect */
- protected final double rightLon;
- /** The cosine of a middle latitude */
- protected final double cosMiddleLat;
-
- /** The upper left hand corner point */
- protected final GeoPoint ULHC;
- /** The upper right hand corner point */
- protected final GeoPoint URHC;
- /** The lower right hand corner point */
- protected final GeoPoint LRHC;
- /** The lower left hand corner point */
- protected final GeoPoint LLHC;
-
- /** The top plane */
- protected final SidedPlane topPlane;
- /** The bottom plane */
- protected final SidedPlane bottomPlane;
- /** The left plane */
- protected final SidedPlane leftPlane;
- /** The right plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for the top plane */
- protected final GeoPoint[] topPlanePoints;
- /** Notable points for the bottom plane */
- protected final GeoPoint[] bottomPlanePoints;
- /** Notable points for the left plane */
- protected final GeoPoint[] leftPlanePoints;
- /** Notable points for the right plane */
- protected final GeoPoint[] rightPlanePoints;
-
- /** Center point */
- protected final GeoPoint centerPoint;
-
- /** Edge point for this rectangle */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *@param planetModel is the planet model.
- *@param topLat is the top latitude.
- *@param bottomLat is the bottom latitude.
- *@param leftLon is the left longitude.
- *@param rightLon is the right longitude.
- */
- public GeoRectangle(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Top latitude out of range");
- if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Bottom latitude out of range");
- if (topLat < bottomLat)
- throw new IllegalArgumentException("Top latitude less than bottom latitude");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent > Math.PI)
- throw new IllegalArgumentException("Width of rectangle too great");
-
- this.topLat = topLat;
- this.bottomLat = bottomLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinTopLat = Math.sin(topLat);
- final double cosTopLat = Math.cos(topLat);
- final double sinBottomLat = Math.sin(bottomLat);
- final double cosBottomLat = Math.cos(bottomLat);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the four points
- this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
- this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
- this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
- this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
-
- final double middleLat = (topLat + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.cosMiddleLat = Math.cos(middleLat);
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
-
- this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
- this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
- this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
- this.leftPlanePoints = new GeoPoint[]{ULHC, LLHC};
- this.rightPlanePoints = new GeoPoint[]{URHC, LRHC};
-
- this.edgePoints = new GeoPoint[]{ULHC};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = bottomLat - angle;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return topPlane.isWithin(x, y, z) &&
- bottomPlane.isWithin(x, y, z) &&
- leftPlane.isWithin(x, y, z) &&
- rightPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
- final double topAngle = centerPoint.arcDistance(URHC);
- final double bottomAngle = centerPoint.arcDistance(LLHC);
- return Math.max(centerAngle, Math.max(topAngle, bottomAngle));
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, leftPlane, rightPlane) ||
- p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, leftPlane, rightPlane) ||
- p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane, bottomPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.addHorizontalPlane(planetModel, topLat, topPlane, bottomPlane, leftPlane, rightPlane)
- .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane, bottomPlane, leftPlane)
- .addHorizontalPlane(planetModel, bottomLat, bottomPlane, topPlane, leftPlane, rightPlane)
- .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane, bottomPlane, rightPlane)
- .addPoint(ULHC).addPoint(URHC).addPoint(LLHC).addPoint(LRHC);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(ULHC);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
- path.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane, rightPlane) ||
- path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, leftPlane, rightPlane);
- final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, leftPlane, rightPlane);
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane, bottomPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, topPlane, bottomPlane);
-
- final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
- final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
- final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
- final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
-
- return Math.min(
- Math.min(
- Math.min(topDistance, bottomDistance),
- Math.min(leftDistance, rightDistance)),
- Math.min(
- Math.min(ULHCDistance, URHCDistance),
- Math.min(LRHCDistance, LLHCDistance)));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoRectangle))
- return false;
- GeoRectangle other = (GeoRectangle) o;
- return super.equals(other) && other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + ULHC.hashCode();
- result = 31 * result + LRHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoShape.java
deleted file mode 100755
index 21cdba3..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoShape.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Generic shape. This describes methods that help GeoAreas figure out
- * how they interact with a shape, for the purposes of coming up with a
- * set of geo hash values.
- *
- * @lucene.experimental
- */
-public interface GeoShape extends Membership {
-
- /**
- * Return a sample point that is on the outside edge/boundary of the shape.
- *
- * @return samples of all edge points from distinct edge sections. Typically one point
- * is returned, but zero or two are also possible.
- */
- public GeoPoint[] getEdgePoints();
-
- /**
- * Assess whether a plane, within the provided bounds, intersects
- * with the shape. Note well that this method is allowed to return "true"
- * if there are internal edges of a composite shape which intersect the plane.
- * Doing this can cause getRelationship() for most GeoBBox shapes to return
- * OVERLAPS rather than the more correct CONTAINS, but that cannot be
- * helped for some complex shapes that are built out of overlapping parts.
- *
- * @param plane is the plane to assess for intersection with the shape's edges or
- * bounding curves.
- * @param notablePoints represents the intersections of the plane with the supplied
- * bounds. These are used to disambiguate when two planes are identical and it needs
- * to be determined whether any points exist that fulfill all the bounds.
- * @param bounds are a set of bounds that define an area that an
- * intersection must be within in order to qualify (provided by a GeoArea).
- * @return true if there's such an intersection, false if not.
- */
- public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds);
-
- /**
- * Compute bounds for the shape.
- *
- * @param bounds is the input bounds object.
- * The input object will be modified.
- */
- public void getBounds(final Bounds bounds);
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSizeable.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSizeable.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSizeable.java
deleted file mode 100755
index e8c0ebb..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSizeable.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Some shapes can compute radii of a geocircle in which they are inscribed.
- *
- * @lucene.experimental
- */
-public interface GeoSizeable {
- /**
- * Returns the radius of a circle into which the GeoSizeable area can
- * be inscribed.
- *
- * @return the radius.
- */
- public double getRadius();
-
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
- public GeoPoint getCenter();
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthLatitudeZone.java
deleted file mode 100644
index 439dc1b..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthLatitudeZone.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * This GeoBBox represents an area rectangle limited only in north latitude.
- *
- * @lucene.internal
- */
-public class GeoSouthLatitudeZone extends GeoBaseBBox {
- /** The top latitude of the zone */
- protected final double topLat;
- /** The cosine of the top latitude of the zone */
- protected final double cosTopLat;
- /** The top plane of the zone */
- protected final SidedPlane topPlane;
- /** An interior point of the zone */
- protected final GeoPoint interiorPoint;
- /** Notable points for the plane (none) */
- protected final static GeoPoint[] planePoints = new GeoPoint[0];
- /** A point on the top boundary */
- protected final GeoPoint topBoundaryPoint;
- /** Edge points; a reference to the topBoundaryPoint */
- protected final GeoPoint[] edgePoints;
-
- /** Constructor.
- *@param planetModel is the planet model.
- *@param topLat is the top latitude of the zone.
- */
- public GeoSouthLatitudeZone(final PlanetModel planetModel, final double topLat) {
- super(planetModel);
- this.topLat = topLat;
-
- final double sinTopLat = Math.sin(topLat);
- this.cosTopLat = Math.cos(topLat);
-
- // Compute an interior point. Pick one whose lat is between top and bottom.
- final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
- this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0);
-
- this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat);
-
- this.edgePoints = new GeoPoint[]{topBoundaryPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = -Math.PI * 0.5;
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return topPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
- // would contain all the bounding box points, when starting in the "center".
- if (topLat > 0.0)
- return Math.PI;
- double maxCosLat = cosTopLat;
- return maxCosLat * Math.PI;
- }
-
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, topPlane, notablePoints, planePoints, bounds);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds
- .addHorizontalPlane(planetModel, topLat, topPlane);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(topBoundaryPoint);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(topPlane, planePoints))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(planetModel, topPlane, x,y,z);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoSouthLatitudeZone))
- return false;
- GeoSouthLatitudeZone other = (GeoSouthLatitudeZone) o;
- return super.equals(other) && other.topBoundaryPoint.equals(topBoundaryPoint);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + topBoundaryPoint.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoSouthLatitudeZone: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + ")}";
- }
-}
-
[35/50] [abbrv] lucene-solr git commit: LUCENE-7075: clean up
LegacyNumeric* in .document javadocs
Posted by no...@apache.org.
LUCENE-7075: clean up LegacyNumeric* in .document javadocs
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/75f18ad4
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/75f18ad4
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/75f18ad4
Branch: refs/heads/apiv2
Commit: 75f18ad40461d9d9a0936a12cc18fe3d8294eb89
Parents: dcb7a88
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 8 10:54:29 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 8 10:55:13 2016 -0500
----------------------------------------------------------------------
.../org/apache/lucene/document/Document.java | 6 ++----
.../java/org/apache/lucene/document/Field.java | 19 ++++++++++++++-----
.../org/apache/lucene/document/TestDocument.java | 4 ++--
3 files changed, 18 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75f18ad4/lucene/core/src/java/org/apache/lucene/document/Document.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/Document.java b/lucene/core/src/java/org/apache/lucene/document/Document.java
index cdba083..2f44444 100644
--- a/lucene/core/src/java/org/apache/lucene/document/Document.java
+++ b/lucene/core/src/java/org/apache/lucene/document/Document.java
@@ -199,8 +199,7 @@ public final class Document implements Iterable<IndexableField> {
* Returns an array of values of the field specified as the method parameter.
* This method returns an empty array when there are no
* matching fields. It never returns null.
- * For {@link LegacyIntField}, {@link LegacyLongField}, {@link
- * LegacyFloatField} and {@link LegacyDoubleField} it returns the string value of the number. If you want
+ * For a numeric {@link StoredField} it returns the string value of the number. If you want
* the actual numeric field instances back, use {@link #getFields}.
* @param name the name of the field
* @return a <code>String[]</code> of field values
@@ -224,8 +223,7 @@ public final class Document implements Iterable<IndexableField> {
* this document, or null. If multiple fields exist with this name, this
* method returns the first value added. If only binary fields with this name
* exist, returns null.
- * For {@link LegacyIntField}, {@link LegacyLongField}, {@link
- * LegacyFloatField} and {@link LegacyDoubleField} it returns the string value of the number. If you want
+ * For a numeric {@link StoredField} it returns the string value of the number. If you want
* the actual numeric field instance back, use {@link #getField}.
*/
public final String get(String name) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75f18ad4/lucene/core/src/java/org/apache/lucene/document/Field.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/Field.java b/lucene/core/src/java/org/apache/lucene/document/Field.java
index dff2e58..550d1fd 100644
--- a/lucene/core/src/java/org/apache/lucene/document/Field.java
+++ b/lucene/core/src/java/org/apache/lucene/document/Field.java
@@ -33,11 +33,20 @@ import org.apache.lucene.util.BytesRef;
/**
* Expert: directly create a field for a document. Most
- * users should use one of the sugar subclasses: {@link
- * LegacyIntField}, {@link LegacyLongField}, {@link LegacyFloatField}, {@link
- * LegacyDoubleField}, {@link BinaryDocValuesField}, {@link
- * NumericDocValuesField}, {@link SortedDocValuesField}, {@link
- * StringField}, {@link TextField}, {@link StoredField}.
+ * users should use one of the sugar subclasses:
+ * <ul>
+ * <li>{@link TextField}: {@link Reader} or {@link String} indexed for full-text search
+ * <li>{@link StringField}: {@link String} indexed verbatim as a single token
+ * <li>{@link IntPoint}: {@code int} indexed for exact/range queries.
+ * <li>{@link LongPoint}: {@code long} indexed for exact/range queries.
+ * <li>{@link FloatPoint}: {@code float} indexed for exact/range queries.
+ * <li>{@link DoublePoint}: {@code double} indexed for exact/range queries.
+ * <li>{@link SortedDocValuesField}: {@code byte[]} indexed column-wise for sorting/faceting
+ * <li>{@link SortedSetDocValuesField}: {@code SortedSet<byte[]>} indexed column-wise for sorting/faceting
+ * <li>{@link NumericDocValuesField}: {@code long} indexed column-wise for sorting/faceting
+ * <li>{@link SortedNumericDocValuesField}: {@code SortedSet<long>} indexed column-wise for sorting/faceting
+ * <li>{@link StoredField}: Stored-only value for retrieving in summary results
+ * </ul>
*
* <p> A field is a section of a Document. Each field has three
* parts: name, type and value. Values may be text
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/75f18ad4/lucene/core/src/test/org/apache/lucene/document/TestDocument.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestDocument.java b/lucene/core/src/test/org/apache/lucene/document/TestDocument.java
index bd873ec..50c1ed0 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestDocument.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestDocument.java
@@ -340,10 +340,10 @@ public class TestDocument extends LuceneTestCase {
public void testNumericFieldAsString() throws Exception {
Document doc = new Document();
- doc.add(new LegacyIntField("int", 5, Field.Store.YES));
+ doc.add(new StoredField("int", 5));
assertEquals("5", doc.get("int"));
assertNull(doc.get("somethingElse"));
- doc.add(new LegacyIntField("int", 4, Field.Store.YES));
+ doc.add(new StoredField("int", 4));
assertArrayEquals(new String[] { "5", "4" }, doc.getValues("int"));
Directory dir = newDirectory();
[05/50] [abbrv] lucene-solr git commit: Merge remote-tracking branch
'origin/master'
Posted by no...@apache.org.
Merge remote-tracking branch 'origin/master'
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b87e3920
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b87e3920
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b87e3920
Branch: refs/heads/apiv2
Commit: b87e3920976b3c7f7c765bb6d6ad1eeabd539c30
Parents: f2c281a 9617d3d
Author: Noble Paul <no...@apache.org>
Authored: Mon Mar 7 22:48:25 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Mon Mar 7 22:48:25 2016 +0530
----------------------------------------------------------------------
dev-tools/scripts/smokeTestRelease.py | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
[46/50] [abbrv] lucene-solr git commit: fix random float test to do
the +/- 1 ulp in float space
Posted by no...@apache.org.
fix random float test to do the +/- 1 ulp in float space
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/a6c8ccbc
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/a6c8ccbc
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/a6c8ccbc
Branch: refs/heads/apiv2
Commit: a6c8ccbc99a9fc83cc5ddfcfd65f9c3c4d4e920c
Parents: d776f7b
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 8 17:21:12 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 8 17:22:31 2016 -0500
----------------------------------------------------------------------
.../lucene/facet/range/TestRangeFacetCounts.java | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a6c8ccbc/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
index 9fde6e3..9f8b109 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
@@ -532,6 +532,8 @@ public class TestRangeFacetCounts extends FacetTestCase {
int[] expectedCounts = new int[numRange];
float minAcceptedValue = Float.POSITIVE_INFINITY;
float maxAcceptedValue = Float.NEGATIVE_INFINITY;
+ boolean[] rangeMinIncl = new boolean[numRange];
+ boolean[] rangeMaxIncl = new boolean[numRange];
if (VERBOSE) {
System.out.println("TEST: " + numRange + " ranges");
}
@@ -582,6 +584,8 @@ public class TestRangeFacetCounts extends FacetTestCase {
minIncl = random().nextBoolean();
maxIncl = random().nextBoolean();
}
+ rangeMinIncl[rangeID] = minIncl;
+ rangeMaxIncl[rangeID] = maxIncl;
ranges[rangeID] = new DoubleRange("r" + rangeID, min, minIncl, max, maxIncl);
if (VERBOSE) {
@@ -642,7 +646,17 @@ public class TestRangeFacetCounts extends FacetTestCase {
// Test drill-down:
DrillDownQuery ddq = new DrillDownQuery(config);
if (random().nextBoolean()) {
- ddq.add("field", FloatPoint.newRangeQuery("field", (float) range.min, (float) range.max));
+ // We must do the nextUp/down in float space, here, because the nextUp that DoubleRange did in double space, when cast back to float,
+ // in fact does nothing!
+ float minFloat = (float) range.min;
+ if (rangeMinIncl[rangeID] == false) {
+ minFloat = Math.nextUp(minFloat);
+ }
+ float maxFloat = (float) range.max;
+ if (rangeMaxIncl[rangeID] == false) {
+ maxFloat = Math.nextAfter(maxFloat, Float.NEGATIVE_INFINITY);
+ }
+ ddq.add("field", FloatPoint.newRangeQuery("field", minFloat, maxFloat));
} else {
ddq.add("field", range.getQuery(fastMatchQuery, vs));
}
[37/50] [abbrv] lucene-solr git commit: LUCENE-6952: Make most
Filter* classes abstract.
Posted by no...@apache.org.
LUCENE-6952: Make most Filter* classes abstract.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/9393a319
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/9393a319
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/9393a319
Branch: refs/heads/apiv2
Commit: 9393a3190ce6af48ae0aac40d5d4b17c3b5d5423
Parents: f9fbf8b
Author: David Smiley <ds...@apache.org>
Authored: Tue Mar 8 12:36:46 2016 -0500
Committer: David Smiley <ds...@apache.org>
Committed: Tue Mar 8 12:36:46 2016 -0500
----------------------------------------------------------------------
lucene/CHANGES.txt | 4 ++++
.../java/org/apache/lucene/index/FilterCodecReader.java | 2 +-
.../java/org/apache/lucene/index/FilterLeafReader.java | 10 +++++-----
.../java/org/apache/lucene/search/FilterCollector.java | 2 +-
.../org/apache/lucene/search/FilterLeafCollector.java | 2 +-
.../src/java/org/apache/lucene/store/FilterDirectory.java | 2 +-
.../org/apache/lucene/index/TestFilterLeafReader.java | 2 +-
.../test/org/apache/lucene/store/TestFilterDirectory.java | 4 ++--
.../org/apache/lucene/index/MockRandomMergePolicy.java | 2 +-
.../org/apache/lucene/mockfile/FilterFileChannel.java | 2 +-
.../java/org/apache/lucene/mockfile/FilterFileStore.java | 2 +-
.../java/org/apache/lucene/mockfile/FilterFileSystem.java | 2 +-
.../apache/lucene/mockfile/FilterFileSystemProvider.java | 2 +-
.../org/apache/lucene/mockfile/FilterOutputStream2.java | 2 +-
14 files changed, 22 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 65281b5..7e803cf 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -135,6 +135,10 @@ API Changes
* LUCENE-7056: Geo3D classes are in different packages now. (David Smiley)
+* LUCENE-6952: These classes are now abstract: FilterCodecReader, FilterLeafReader,
+ FilterCollector, FilterDirectory. And some Filter* classes in
+ lucene-test-framework too. (David Smiley)
+
Optimizations
* LUCENE-6891: Use prefix coding when writing points in
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java
index 41f0984..c35dc67 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java
@@ -32,7 +32,7 @@ import org.apache.lucene.util.Bits;
* uses as its basic source of data, possibly transforming the data along the
* way or providing additional functionality.
*/
-public class FilterCodecReader extends CodecReader {
+public abstract class FilterCodecReader extends CodecReader {
/**
* The underlying CodecReader instance.
*/
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
index 98365a6..1d593c3 100644
--- a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
@@ -44,7 +44,7 @@ import org.apache.lucene.util.BytesRef;
* overridden as well if the {@link #getLiveDocs() live docs} are not changed
* either.
*/
-public class FilterLeafReader extends LeafReader {
+public abstract class FilterLeafReader extends LeafReader {
/** Get the wrapped instance by <code>reader</code> as long as this reader is
* an instance of {@link FilterLeafReader}. */
@@ -57,7 +57,7 @@ public class FilterLeafReader extends LeafReader {
/** Base class for filtering {@link Fields}
* implementations. */
- public static class FilterFields extends Fields {
+ public abstract static class FilterFields extends Fields {
/** The underlying Fields instance. */
protected final Fields in;
@@ -93,7 +93,7 @@ public class FilterLeafReader extends LeafReader {
* these terms are going to be intersected with automata, you could consider
* overriding {@link #intersect} for better performance.
*/
- public static class FilterTerms extends Terms {
+ public abstract static class FilterTerms extends Terms {
/** The underlying Terms instance. */
protected final Terms in;
@@ -160,7 +160,7 @@ public class FilterLeafReader extends LeafReader {
}
/** Base class for filtering {@link TermsEnum} implementations. */
- public static class FilterTermsEnum extends TermsEnum {
+ public abstract static class FilterTermsEnum extends TermsEnum {
/** The underlying TermsEnum instance. */
protected final TermsEnum in;
@@ -223,7 +223,7 @@ public class FilterLeafReader extends LeafReader {
}
/** Base class for filtering {@link PostingsEnum} implementations. */
- public static class FilterPostingsEnum extends PostingsEnum {
+ public abstract static class FilterPostingsEnum extends PostingsEnum {
/** The underlying PostingsEnum instance. */
protected final PostingsEnum in;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/java/org/apache/lucene/search/FilterCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/FilterCollector.java b/lucene/core/src/java/org/apache/lucene/search/FilterCollector.java
index d290330..d4ec914 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FilterCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FilterCollector.java
@@ -26,7 +26,7 @@ import org.apache.lucene.index.LeafReaderContext;
*
* @lucene.experimental
*/
-public class FilterCollector implements Collector {
+public abstract class FilterCollector implements Collector {
protected final Collector in;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/java/org/apache/lucene/search/FilterLeafCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/FilterLeafCollector.java b/lucene/core/src/java/org/apache/lucene/search/FilterLeafCollector.java
index ab15bab..b55410c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FilterLeafCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FilterLeafCollector.java
@@ -24,7 +24,7 @@ import java.io.IOException;
*
* @lucene.experimental
*/
-public class FilterLeafCollector implements LeafCollector {
+public abstract class FilterLeafCollector implements LeafCollector {
protected final LeafCollector in;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java b/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java
index 5df5713..8148b5a 100644
--- a/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java
+++ b/lucene/core/src/java/org/apache/lucene/store/FilterDirectory.java
@@ -29,7 +29,7 @@ import java.util.Collection;
* {@link Directory} or {@link BaseDirectory} rather than try to reuse
* functionality of existing {@link Directory}s by extending this class.
* @lucene.internal */
-public class FilterDirectory extends Directory {
+public abstract class FilterDirectory extends Directory {
/** Get the wrapped instance by <code>dir</code> as long as this reader is
* an instance of {@link FilterDirectory}. */
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java b/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
index 82fb3bc..cad47a4 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestFilterLeafReader.java
@@ -196,7 +196,7 @@ public class TestFilterLeafReader extends LuceneTestCase {
w.addDocument(new Document());
DirectoryReader dr = w.getReader();
LeafReader r = dr.leaves().get(0).reader();
- FilterLeafReader r2 = new FilterLeafReader(r);
+ FilterLeafReader r2 = new FilterLeafReader(r) {};
assertEquals(r, r2.getDelegate());
assertEquals(r, FilterLeafReader.unwrap(r2));
w.close();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java b/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java
index 7fe9bc2..6224140 100644
--- a/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java
+++ b/lucene/core/src/test/org/apache/lucene/store/TestFilterDirectory.java
@@ -29,7 +29,7 @@ public class TestFilterDirectory extends BaseDirectoryTestCase {
@Override
protected Directory getDirectory(Path path) throws IOException {
- return new FilterDirectory(new RAMDirectory());
+ return new FilterDirectory(new RAMDirectory()) {};
}
@Test
@@ -48,7 +48,7 @@ public class TestFilterDirectory extends BaseDirectoryTestCase {
public void testUnwrap() throws IOException {
Directory dir = FSDirectory.open(createTempDir());
- FilterDirectory dir2 = new FilterDirectory(dir);
+ FilterDirectory dir2 = new FilterDirectory(dir) {};
assertEquals(dir, dir2.getDelegate());
assertEquals(dir, FilterDirectory.unwrap(dir2));
dir2.close();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/test-framework/src/java/org/apache/lucene/index/MockRandomMergePolicy.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/MockRandomMergePolicy.java b/lucene/test-framework/src/java/org/apache/lucene/index/MockRandomMergePolicy.java
index bcee1b6..b40ac26 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/MockRandomMergePolicy.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/MockRandomMergePolicy.java
@@ -159,7 +159,7 @@ public class MockRandomMergePolicy extends MergePolicy {
if (LuceneTestCase.VERBOSE) {
System.out.println("NOTE: MockRandomMergePolicy now swaps in a SlowCodecReaderWrapper for merging reader=" + readers.get(i));
}
- readers.set(i, SlowCodecReaderWrapper.wrap(new FilterLeafReader(readers.get(i))));
+ readers.set(i, SlowCodecReaderWrapper.wrap(new FilterLeafReader(readers.get(i)) {}));
} else if (thingToDo == 1) {
// renumber fields
// NOTE: currently this only "blocks" bulk merges just by
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileChannel.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileChannel.java b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileChannel.java
index 0c95af0..ccc6e7a 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileChannel.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileChannel.java
@@ -31,7 +31,7 @@ import java.util.Objects;
* source of data, possibly transforming the data along the
* way or providing additional functionality.
*/
-public class FilterFileChannel extends FileChannel {
+public abstract class FilterFileChannel extends FileChannel {
/**
* The underlying {@code FileChannel} instance.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileStore.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileStore.java b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileStore.java
index dc90799..423b32d 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileStore.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileStore.java
@@ -28,7 +28,7 @@ import java.util.Objects;
* source of data, possibly transforming the data along the
* way or providing additional functionality.
*/
-public class FilterFileStore extends FileStore {
+public abstract class FilterFileStore extends FileStore {
/**
* The underlying {@code FileStore} instance.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystem.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystem.java b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystem.java
index d79ed35..e24506d 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystem.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystem.java
@@ -131,7 +131,7 @@ public class FilterFileSystem extends FileSystem {
@Override
public FileStore next() {
- return new FilterFileStore(iterator.next(), parent.getScheme());
+ return new FilterFileStore(iterator.next(), parent.getScheme()) {};
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystemProvider.java b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystemProvider.java
index c9c0165..8a7ff75 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystemProvider.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterFileSystemProvider.java
@@ -48,7 +48,7 @@ import java.util.concurrent.ExecutorService;
* source of data, possibly transforming the data along the
* way or providing additional functionality.
*/
-public class FilterFileSystemProvider extends FileSystemProvider {
+public abstract class FilterFileSystemProvider extends FileSystemProvider {
/**
* The underlying {@code FileSystemProvider}.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9393a319/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterOutputStream2.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterOutputStream2.java b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterOutputStream2.java
index dbf7a95..5413c87 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterOutputStream2.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/mockfile/FilterOutputStream2.java
@@ -34,7 +34,7 @@ import java.util.Objects;
* that just overrides {@code close} will not force bytes to be
* written one-at-a-time.
*/
-public class FilterOutputStream2 extends OutputStream {
+public abstract class FilterOutputStream2 extends OutputStream {
/**
* The underlying {@code OutputStream} instance.
[20/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthRectangle.java
deleted file mode 100644
index eb6526b..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoSouthRectangle.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box limited on three sides (top lat, left lon, right lon). The
- * other corner is the south pole.
- * The left-right maximum extent for this shape is PI; for anything larger, use
- * {@link GeoWideSouthRectangle}.
- *
- * @lucene.internal
- */
-public class GeoSouthRectangle extends GeoBaseBBox {
- /** The top latitude of the rect */
- protected final double topLat;
- /** The left longitude of the rect */
- protected final double leftLon;
- /** The right longitude of the rect */
- protected final double rightLon;
- /** The cosine of a middle latitude */
- protected final double cosMiddleLat;
- /** The upper left hand corner of the rectangle */
- protected final GeoPoint ULHC;
- /** The upper right hand corner of the rectangle */
- protected final GeoPoint URHC;
-
- /** The top plane */
- protected final SidedPlane topPlane;
- /** The left plane */
- protected final SidedPlane leftPlane;
- /** The right plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for the top plane */
- protected final GeoPoint[] topPlanePoints;
- /** Notable points for the left plane */
- protected final GeoPoint[] leftPlanePoints;
- /** Notable points for the right plane */
- protected final GeoPoint[] rightPlanePoints;
-
- /** The center point */
- protected final GeoPoint centerPoint;
-
- /** A point on the edge */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *@param planetModel is the planet model.
- *@param topLat is the top latitude.
- *@param leftLon is the left longitude.
- *@param rightLon is the right longitude.
- */
- public GeoSouthRectangle(final PlanetModel planetModel, final double topLat, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Top latitude out of range");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent > Math.PI)
- throw new IllegalArgumentException("Width of rectangle too great");
-
- this.topLat = topLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinTopLat = Math.sin(topLat);
- final double cosTopLat = Math.cos(topLat);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the four points
- this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
- this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
-
- final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.cosMiddleLat = Math.cos(middleLat);
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
-
- this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
- this.leftPlanePoints = new GeoPoint[]{ULHC, planetModel.SOUTH_POLE};
- this.rightPlanePoints = new GeoPoint[]{URHC, planetModel.SOUTH_POLE};
-
- this.edgePoints = new GeoPoint[]{planetModel.SOUTH_POLE};
-
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = -Math.PI * 0.5;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return topPlane.isWithin(x, y, z) &&
- leftPlane.isWithin(x, y, z) &&
- rightPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
- final double topAngle = centerPoint.arcDistance(URHC);
- return Math.max(centerAngle, topAngle);
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, leftPlane, rightPlane) ||
- p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds
- .addHorizontalPlane(planetModel, topLat, topPlane, leftPlane, rightPlane)
- .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane, rightPlane)
- .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane, leftPlane)
- .addPoint(URHC).addPoint(ULHC).addPoint(planetModel.SOUTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, leftPlane, rightPlane) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane, rightPlane) ||
- path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, leftPlane, rightPlane);
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, topPlane);
-
- final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
- final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
-
- return Math.min(
- Math.min(
- topDistance,
- Math.min(leftDistance, rightDistance)),
- Math.min(ULHCDistance, URHCDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoSouthRectangle))
- return false;
- GeoSouthRectangle other = (GeoSouthRectangle) o;
- return super.equals(other) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + ULHC.hashCode();
- result = 31 * result + URHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoSouthRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoStandardCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoStandardCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoStandardCircle.java
deleted file mode 100755
index 0304d53..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoStandardCircle.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Circular area with a center and radius.
- *
- * @lucene.experimental
- */
-public class GeoStandardCircle extends GeoBaseCircle {
- /** Center of circle */
- protected final GeoPoint center;
- /** Cutoff angle of circle (not quite the same thing as radius) */
- protected final double cutoffAngle;
- /** The plane describing the circle (really an ellipse on a non-spherical world) */
- protected final SidedPlane circlePlane;
- /** A point that is on the world and on the circle plane */
- protected final GeoPoint[] edgePoints;
- /** Notable points for a circle -- there aren't any */
- protected static final GeoPoint[] circlePoints = new GeoPoint[0];
-
- /** Constructor.
- *@param planetModel is the planet model.
- *@param lat is the center latitude.
- *@param lon is the center longitude.
- *@param cutoffAngle is the cutoff angle for the circle.
- */
- public GeoStandardCircle(final PlanetModel planetModel, final double lat, final double lon, final double cutoffAngle) {
- 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 || cutoffAngle > Math.PI)
- throw new IllegalArgumentException("Cutoff angle out of bounds");
- if (cutoffAngle < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Cutoff angle cannot be effectively zero");
- this.center = new GeoPoint(planetModel, lat, lon);
- // In an ellipsoidal world, cutoff distances make no sense, unfortunately. Only membership
- // can be used to make in/out determination.
- this.cutoffAngle = cutoffAngle;
- // Compute two points on the circle, with the right angle from the center. We'll use these
- // to obtain the perpendicular plane to the circle.
- double upperLat = lat + cutoffAngle;
- double upperLon = lon;
- if (upperLat > Math.PI * 0.5) {
- upperLon += Math.PI;
- if (upperLon > Math.PI)
- upperLon -= 2.0 * Math.PI;
- upperLat = Math.PI - upperLat;
- }
- double lowerLat = lat - cutoffAngle;
- double lowerLon = lon;
- if (lowerLat < -Math.PI * 0.5) {
- lowerLon += Math.PI;
- if (lowerLon > Math.PI)
- lowerLon -= 2.0 * Math.PI;
- lowerLat = -Math.PI - lowerLat;
- }
- final GeoPoint upperPoint = new GeoPoint(planetModel, upperLat, upperLon);
- final GeoPoint lowerPoint = new GeoPoint(planetModel, lowerLat, lowerLon);
- if (Math.abs(cutoffAngle - Math.PI) < Vector.MINIMUM_RESOLUTION) {
- // Circle is the whole world
- this.circlePlane = null;
- this.edgePoints = new GeoPoint[0];
- } else {
- // Construct normal plane
- final Plane normalPlane = Plane.constructNormalizedZPlane(upperPoint, lowerPoint, center);
- // Construct a sided plane that goes through the two points and whose normal is in the normalPlane.
- this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(center, normalPlane, upperPoint, lowerPoint);
- if (circlePlane == null)
- throw new IllegalArgumentException("Couldn't construct circle plane, probably too small? Cutoff angle = "+cutoffAngle+"; upperPoint = "+upperPoint+"; lowerPoint = "+lowerPoint);
- final GeoPoint recomputedIntersectionPoint = circlePlane.getSampleIntersectionPoint(planetModel, normalPlane);
- if (recomputedIntersectionPoint == null)
- throw new IllegalArgumentException("Couldn't construct intersection point, probably circle too small? Plane = "+circlePlane);
- this.edgePoints = new GeoPoint[]{recomputedIntersectionPoint};
- }
- }
-
- @Override
- public double getRadius() {
- return cutoffAngle;
- }
-
- @Override
- public GeoPoint getCenter() {
- return center;
- }
-
- @Override
- protected double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(this.center, x, y, z);
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(planetModel, circlePlane, x, y, z);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- if (circlePlane == null) {
- return true;
- }
- // Fastest way of determining membership
- return circlePlane.isWithin(x, y, z);
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- if (circlePlane == null) {
- return false;
- }
- return circlePlane.intersects(planetModel, p, notablePoints, circlePoints, bounds);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- if (circlePlane == null) {
- // Entire world; should already be covered
- return;
- }
- bounds.addPoint(center);
- bounds.addPlane(planetModel, circlePlane);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoStandardCircle))
- return false;
- GeoStandardCircle other = (GeoStandardCircle) o;
- return super.equals(other) && other.center.equals(center) && other.cutoffAngle == cutoffAngle;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + center.hashCode();
- long temp = Double.doubleToLongBits(cutoffAngle);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoStandardCircle: {planetmodel=" + planetModel+", center=" + center + ", radius=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + ")}";
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideDegenerateHorizontalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideDegenerateHorizontalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideDegenerateHorizontalLine.java
deleted file mode 100644
index a9af5b2..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideDegenerateHorizontalLine.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Degenerate bounding box wider than PI and limited on two sides (left lon, right lon).
- *
- * @lucene.internal
- */
-public class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
- /** The latitude of the line */
- protected final double latitude;
- /** The left longitude cutoff of the line */
- protected final double leftLon;
- /** The right longitude cutoff of the line */
- protected final double rightLon;
-
- /** The left end of the line */
- protected final GeoPoint LHC;
- /** The right end of the line */
- protected final GeoPoint RHC;
-
- /** The plane the line is in */
- protected final Plane plane;
- /** The left cutoff plane */
- protected final SidedPlane leftPlane;
- /** The right cutoff plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for the line */
- protected final GeoPoint[] planePoints;
-
- /** Center point for the line */
- protected final GeoPoint centerPoint;
-
- /** Left/right combination bound */
- protected final EitherBound eitherBound;
-
- /** A point on the line */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
- * Horizontal angle must be greater than or equal to PI.
- *@param planetModel is the planet model.
- *@param latitude is the line latitude.
- *@param leftLon is the left cutoff longitude.
- *@param rightLon is the right cutoff longitude.
- */
- public GeoWideDegenerateHorizontalLine(final PlanetModel planetModel, final double latitude, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
- throw new IllegalArgumentException("Latitude out of range");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent < Math.PI)
- throw new IllegalArgumentException("Width of rectangle too small");
-
- this.latitude = latitude;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinLatitude = Math.sin(latitude);
- final double cosLatitude = Math.cos(latitude);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the two points
- this.LHC = new GeoPoint(planetModel, sinLatitude, sinLeftLon, cosLatitude, cosLeftLon, latitude, leftLon);
- this.RHC = new GeoPoint(planetModel, sinLatitude, sinRightLon, cosLatitude, cosRightLon, latitude, rightLon);
-
- this.plane = new Plane(planetModel, sinLatitude);
-
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- double middleLon = (leftLon + rightLon) * 0.5;
- double sinMiddleLon = Math.sin(middleLon);
- double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
-
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.planePoints = new GeoPoint[]{LHC, RHC};
-
- this.eitherBound = new EitherBound();
-
- this.edgePoints = new GeoPoint[]{centerPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = latitude + angle;
- final double newBottomLat = latitude - angle;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return plane.evaluateIsZero(x, y, z) &&
- (leftPlane.isWithin(x, y, z) ||
- rightPlane.isWithin(x, y, z));
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double topAngle = centerPoint.arcDistance(RHC);
- final double bottomAngle = centerPoint.arcDistance(LHC);
- return Math.max(topAngle, bottomAngle);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
- // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, eitherBound);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.isWide()
- .addHorizontalPlane(planetModel, latitude, plane, eitherBound)
- .addPoint(LHC)
- .addPoint(RHC);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- if (path.intersects(plane, planePoints, eitherBound)) {
- return OVERLAPS;
- }
-
- if (path.isWithin(centerPoint)) {
- return CONTAINS;
- }
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, eitherBound);
-
- final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
- final double RHCDistance = distanceStyle.computeDistance(RHC, x,y,z);
-
- return Math.min(
- distance,
- Math.min(LHCDistance, RHCDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoWideDegenerateHorizontalLine))
- return false;
- GeoWideDegenerateHorizontalLine other = (GeoWideDegenerateHorizontalLine) o;
- return super.equals(other) && other.LHC.equals(LHC) && other.RHC.equals(RHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + LHC.hashCode();
- result = 31 * result + RHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoWideDegenerateHorizontalLine: {planetmodel="+planetModel+", latitude=" + latitude + "(" + latitude * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightLon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-
- /** Membership implementation representing a wide cutoff (more than 180 degrees).
- */
- protected class EitherBound implements Membership {
- /** Constructor.
- */
- public EitherBound() {
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
- }
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideLongitudeSlice.java
deleted file mode 100755
index 64e4fa8..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideLongitudeSlice.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box wider than PI but limited on left and right sides (
- * left lon, right lon).
- *
- * @lucene.internal
- */
-public class GeoWideLongitudeSlice extends GeoBaseBBox {
- /** The left longitude */
- protected final double leftLon;
- /** The right longitude */
- protected final double rightLon;
-
- /** The left plane */
- protected final SidedPlane leftPlane;
- /** The right plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for the shape */
- protected final GeoPoint[] planePoints;
-
- /** Center point for the shape */
- protected final GeoPoint centerPoint;
-
- /** A point on the edge of the shape */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lon: {@code -PI -> PI}.
- * Horizantal angle must be greater than or equal to PI.
- *@param planetModel is the planet model.
- *@param leftLon is the left longitude.
- *@param rightLon is the right longitude.
- */
- public GeoWideLongitudeSlice(final PlanetModel planetModel, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent < Math.PI)
- throw new IllegalArgumentException("Width of rectangle too small");
-
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- this.centerPoint = new GeoPoint(planetModel, 0.0, middleLon);
-
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
- this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return leftPlane.isWithin(x, y, z) ||
- rightPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // Compute the extent and divide by two
- double extent = rightLon - leftLon;
- if (extent < 0.0)
- extent += Math.PI * 2.0;
- return Math.max(Math.PI * 0.5, extent * 0.5);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
- // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(planetModel, leftPlane, notablePoints, planePoints, bounds) ||
- p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.isWide()
- .addVerticalPlane(planetModel, leftLon, leftPlane)
- .addVerticalPlane(planetModel, rightLon, rightPlane)
- .addPoint(planetModel.NORTH_POLE)
- .addPoint(planetModel.SOUTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- if (path.intersects(leftPlane, planePoints) ||
- path.intersects(rightPlane, planePoints))
- return OVERLAPS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- if (insideShape)
- return CONTAINS;
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
- // unbounded distance to both the left and the right and only take the minimum of the two.
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z);
-
- final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
- final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
-
- return Math.min(
- Math.min(leftDistance, rightDistance),
- Math.min(northDistance, southDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoWideLongitudeSlice))
- return false;
- GeoWideLongitudeSlice other = (GeoWideLongitudeSlice) o;
- return super.equals(other) && other.leftLon == leftLon && other.rightLon == rightLon;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp = Double.doubleToLongBits(leftLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(rightLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoWideLongitudeSlice: {planetmodel="+planetModel+", leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideNorthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideNorthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideNorthRectangle.java
deleted file mode 100644
index 86de584..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideNorthRectangle.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box wider than PI but limited on three sides (
- * bottom lat, left lon, right lon).
- *
- * @lucene.internal
- */
-public class GeoWideNorthRectangle extends GeoBaseBBox {
- /** Bottom latitude */
- protected final double bottomLat;
- /** Left longitude */
- protected final double leftLon;
- /** Right longitude */
- protected final double rightLon;
-
- /** The cosine of the middle latitude */
- protected final double cosMiddleLat;
-
- /** The lower right hand corner point */
- protected final GeoPoint LRHC;
- /** The lower left hand corner point */
- protected final GeoPoint LLHC;
-
- /** The bottom plane */
- protected final SidedPlane bottomPlane;
- /** The left plane */
- protected final SidedPlane leftPlane;
- /** The right plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for the bottom plane */
- protected final GeoPoint[] bottomPlanePoints;
- /** Notable points for the left plane */
- protected final GeoPoint[] leftPlanePoints;
- /** Notable points for the right plane */
- protected final GeoPoint[] rightPlanePoints;
-
- /** Center point */
- protected final GeoPoint centerPoint;
-
- /** Composite left/right bounds */
- protected final EitherBound eitherBound;
-
- /** A point on the edge */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
- * Horizontal angle must be greater than or equal to PI.
- */
- public GeoWideNorthRectangle(final PlanetModel planetModel, final double bottomLat, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Bottom latitude out of range");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent < Math.PI)
- throw new IllegalArgumentException("Width of rectangle too small");
-
- this.bottomLat = bottomLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinBottomLat = Math.sin(bottomLat);
- final double cosBottomLat = Math.cos(bottomLat);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the four points
- this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
- this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
-
- final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.cosMiddleLat = Math.cos(middleLat);
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
-
- this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
- this.leftPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LLHC};
- this.rightPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LRHC};
-
- this.eitherBound = new EitherBound();
- this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = Math.PI * 0.5;
- final double newBottomLat = bottomLat - angle;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return
- bottomPlane.isWithin(x, y, z) &&
- (leftPlane.isWithin(x, y, z) ||
- rightPlane.isWithin(x, y, z));
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
- final double bottomAngle = centerPoint.arcDistance(LLHC);
- return Math.max(centerAngle, bottomAngle);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
- // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return
- p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, eitherBound) ||
- p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, bottomPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, bottomPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.isWide()
- .addHorizontalPlane(planetModel, bottomLat, bottomPlane, eitherBound)
- .addVerticalPlane(planetModel, leftLon, leftPlane, bottomPlane)
- .addVerticalPlane(planetModel, rightLon, rightPlane, bottomPlane)
- .addPoint(LLHC).addPoint(LRHC).addPoint(planetModel.NORTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" comparing to "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (
- path.intersects(bottomPlane, bottomPlanePoints, eitherBound) ||
- path.intersects(leftPlane, leftPlanePoints, bottomPlane) ||
- path.intersects(rightPlane, rightPlanePoints, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, eitherBound);
- // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
- // unbounded distance to both the left and the right and only take the minimum of the two.
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, bottomPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, bottomPlane);
-
- final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
- final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
-
- return Math.min(
- Math.min(
- bottomDistance,
- Math.min(leftDistance, rightDistance)),
- Math.min(LRHCDistance, LLHCDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoWideNorthRectangle))
- return false;
- GeoWideNorthRectangle other = (GeoWideNorthRectangle) o;
- return super.equals(other) && other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + LLHC.hashCode();
- result = 31 * result + LRHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoWideNorthRectangle: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-
- /** Membership implementation representing a wide (more than 180 degree) bound.
- */
- protected class EitherBound implements Membership {
- /** Constructor.
- */
- public EitherBound() {
- }
-
- @Override
- public boolean isWithin(final Vector v) {
- return leftPlane.isWithin(v) || rightPlane.isWithin(v);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
- }
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideRectangle.java
deleted file mode 100755
index 68397bb..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideRectangle.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box wider than PI but limited on four sides (top lat,
- * bottom lat, left lon, right lon).
- *
- * @lucene.internal
- */
-public class GeoWideRectangle extends GeoBaseBBox {
- /** The top latitude */
- protected final double topLat;
- /** The bottom latitude */
- protected final double bottomLat;
- /** The left longitude */
- protected final double leftLon;
- /** The right longitude */
- protected final double rightLon;
-
- /** Cosine of the middle latitude */
- protected final double cosMiddleLat;
-
- /** Upper left hand corner point */
- protected final GeoPoint ULHC;
- /** Lower right hand corner point */
- protected final GeoPoint URHC;
- /** Lower right hand corner point */
- protected final GeoPoint LRHC;
- /** Lower left hand corner point */
- protected final GeoPoint LLHC;
-
- /** Top plane */
- protected final SidedPlane topPlane;
- /** Bottom plane */
- protected final SidedPlane bottomPlane;
- /** Left plane */
- protected final SidedPlane leftPlane;
- /** Right plane */
- protected final SidedPlane rightPlane;
-
- /** Top plane's notable points */
- protected final GeoPoint[] topPlanePoints;
- /** Bottom plane's notable points */
- protected final GeoPoint[] bottomPlanePoints;
- /** Left plane's notable points */
- protected final GeoPoint[] leftPlanePoints;
- /** Right plane's notable points */
- protected final GeoPoint[] rightPlanePoints;
-
- /** Center point */
- protected final GeoPoint centerPoint;
-
- /** Combined left/right bounds */
- protected final EitherBound eitherBound;
-
- /** A point on the edge */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
- * Horizontal angle must be greater than or equal to PI.
- */
- public GeoWideRectangle(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Top latitude out of range");
- if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Bottom latitude out of range");
- if (topLat < bottomLat)
- throw new IllegalArgumentException("Top latitude less than bottom latitude");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent < Math.PI)
- throw new IllegalArgumentException("Width of rectangle too small");
-
- this.topLat = topLat;
- this.bottomLat = bottomLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinTopLat = Math.sin(topLat);
- final double cosTopLat = Math.cos(topLat);
- final double sinBottomLat = Math.sin(bottomLat);
- final double cosBottomLat = Math.cos(bottomLat);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the four points
- this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
- this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
- this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
- this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
-
- final double middleLat = (topLat + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.cosMiddleLat = Math.cos(middleLat);
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
-
- this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
- this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
- this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
- this.leftPlanePoints = new GeoPoint[]{ULHC, LLHC};
- this.rightPlanePoints = new GeoPoint[]{URHC, LRHC};
-
- this.eitherBound = new EitherBound();
-
- this.edgePoints = new GeoPoint[]{ULHC};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = bottomLat - angle;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return topPlane.isWithin(x, y, z) &&
- bottomPlane.isWithin(x, y, z) &&
- (leftPlane.isWithin(x, y, z) ||
- rightPlane.isWithin(x, y, z));
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
- final double topAngle = centerPoint.arcDistance(URHC);
- final double bottomAngle = centerPoint.arcDistance(LLHC);
- return Math.max(centerAngle, Math.max(topAngle, bottomAngle));
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
- // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, eitherBound) ||
- p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, eitherBound) ||
- p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, topPlane, bottomPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane, bottomPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.isWide()
- .addHorizontalPlane(planetModel, topLat, topPlane, bottomPlane, eitherBound)
- .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane, bottomPlane)
- .addHorizontalPlane(planetModel, bottomLat, bottomPlane, topPlane, eitherBound)
- .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane, bottomPlane)
- .addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" comparing to "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(ULHC);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
- path.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
- path.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, eitherBound);
- final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, eitherBound);
- // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
- // unbounded distance to both the left and the right and only take the minimum of the two.
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, topPlane, bottomPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, topPlane, bottomPlane);
-
- final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
- final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
- final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
- final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
-
- return Math.min(
- Math.min(
- Math.min(topDistance, bottomDistance),
- Math.min(leftDistance, rightDistance)),
- Math.min(
- Math.min(ULHCDistance, URHCDistance),
- Math.min(LRHCDistance, LLHCDistance)));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoWideRectangle))
- return false;
- GeoWideRectangle other = (GeoWideRectangle) o;
- return super.equals(other) && other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + ULHC.hashCode();
- result = 31 * result + LRHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoWideRectangle: {planetmodel=" + planetModel + ", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-
- /** A membership implementation representing a wide (more than 180) left/right bound.
- */
- protected class EitherBound implements Membership {
- /** Constructor.
- */
- public EitherBound() {
- }
-
- @Override
- public boolean isWithin(final Vector v) {
- return leftPlane.isWithin(v) || rightPlane.isWithin(v);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideSouthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideSouthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideSouthRectangle.java
deleted file mode 100644
index 8bd7220..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWideSouthRectangle.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box wider than PI but limited on three sides (top lat,
- * left lon, right lon).
- *
- * @lucene.internal
- */
-public class GeoWideSouthRectangle extends GeoBaseBBox {
- /** Top latitude of rect */
- protected final double topLat;
- /** Left longitude of rect */
- protected final double leftLon;
- /** Right longitude of rect */
- protected final double rightLon;
-
- /** Cosine of middle latitude */
- protected final double cosMiddleLat;
-
- /** Upper left hand corner */
- protected final GeoPoint ULHC;
- /** Upper right hand corner */
- protected final GeoPoint URHC;
-
- /** The top plane */
- protected final SidedPlane topPlane;
- /** The left plane */
- protected final SidedPlane leftPlane;
- /** The right plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for top plane */
- protected final GeoPoint[] topPlanePoints;
- /** Notable points for left plane */
- protected final GeoPoint[] leftPlanePoints;
- /** Notable points for right plane */
- protected final GeoPoint[] rightPlanePoints;
-
- /** Center point */
- protected final GeoPoint centerPoint;
-
- /** Left/right bounds */
- protected final EitherBound eitherBound;
-
- /** A point on the edge */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
- * Horizontal angle must be greater than or equal to PI.
- */
- public GeoWideSouthRectangle(final PlanetModel planetModel, final double topLat, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Top latitude out of range");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent < Math.PI)
- throw new IllegalArgumentException("Width of rectangle too small");
-
- this.topLat = topLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinTopLat = Math.sin(topLat);
- final double cosTopLat = Math.cos(topLat);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the four points
- this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
- this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
-
- final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.cosMiddleLat = Math.cos(middleLat);
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
-
- this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
- this.leftPlanePoints = new GeoPoint[]{ULHC, planetModel.SOUTH_POLE};
- this.rightPlanePoints = new GeoPoint[]{URHC, planetModel.SOUTH_POLE};
-
- this.eitherBound = new EitherBound();
-
- this.edgePoints = new GeoPoint[]{planetModel.SOUTH_POLE};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = -Math.PI * 0.5;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return topPlane.isWithin(x, y, z) &&
- (leftPlane.isWithin(x, y, z) ||
- rightPlane.isWithin(x, y, z));
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
- final double topAngle = centerPoint.arcDistance(URHC);
- return Math.max(centerAngle, topAngle);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
- // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
- return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, eitherBound) ||
- p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, topPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.isWide()
- .addHorizontalPlane(planetModel, topLat, topPlane, eitherBound)
- .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane)
- .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane)
- .addPoint(ULHC).addPoint(URHC).addPoint(planetModel.SOUTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" comparing to "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" both inside each other");
- return OVERLAPS;
- }
-
- if (path.intersects(topPlane, topPlanePoints, eitherBound) ||
- path.intersects(leftPlane, leftPlanePoints, topPlane) ||
- path.intersects(rightPlane, rightPlanePoints, topPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" rectangle inside shape");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, eitherBound);
- // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
- // unbounded distance to both the left and the right and only take the minimum of the two.
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, topPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, topPlane);
-
- final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
- final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
-
- return Math.min(
- Math.min(
- topDistance,
- Math.min(leftDistance, rightDistance)),
- Math.min(ULHCDistance, URHCDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoWideSouthRectangle))
- return false;
- GeoWideSouthRectangle other = (GeoWideSouthRectangle) o;
- return super.equals(o) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + ULHC.hashCode();
- result = 31 * result + URHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoWideSouthRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-
- /** Membership implementation representing width more than 180.
- */
- protected class EitherBound implements Membership {
- /** Constructor.
- */
- public EitherBound() {
- }
-
- @Override
- public boolean isWithin(final Vector v) {
- return leftPlane.isWithin(v) || rightPlane.isWithin(v);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
- }
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWorld.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWorld.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWorld.java
deleted file mode 100755
index 35ec4ae..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoWorld.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box including the entire world.
- *
- * @lucene.internal
- */
-public class GeoWorld extends GeoBaseBBox {
- /** No points on the edge of the shape */
- protected final static GeoPoint[] edgePoints = new GeoPoint[0];
- /** Point in the middle of the world */
- protected final GeoPoint originPoint;
-
- /** Constructor.
- *@param planetModel is the planet model.
- */
- public GeoWorld(final PlanetModel planetModel) {
- super(planetModel);
- originPoint = new GeoPoint(planetModel.ab, 1.0, 0.0, 0.0);
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- return this;
- }
-
- @Override
- public double getRadius() {
- return Math.PI;
- }
-
- @Override
- public GeoPoint getCenter() {
- // Totally arbitrary
- return originPoint;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return true;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return false;
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- // Unnecessary
- //bounds.noLongitudeBound().noTopLatitudeBound().noBottomLatitudeBound();
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- if (path.getEdgePoints().length > 0)
- // Path is always within the world
- return WITHIN;
-
- return OVERLAPS;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return 0.0;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoWorld))
- return false;
- return super.equals(o);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
- @Override
- public String toString() {
- return "GeoWorld: {planetmodel="+planetModel+"}";
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LatLonBounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LatLonBounds.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LatLonBounds.java
deleted file mode 100644
index 6478e0c..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LatLonBounds.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * An object for accumulating latitude/longitude bounds information.
- *
- * @lucene.experimental
- */
-public class LatLonBounds implements Bounds {
-
- /** Set to true if no longitude bounds can be stated */
- protected boolean noLongitudeBound = false;
- /** Set to true if no top latitude bound can be stated */
- protected boolean noTopLatitudeBound = false;
- /** Set to true if no bottom latitude bound can be stated */
- protected boolean noBottomLatitudeBound = false;
-
- /** If non-null, the minimum latitude bound */
- protected Double minLatitude = null;
- /** If non-null, the maximum latitude bound */
- protected Double maxLatitude = null;
-
- // For longitude bounds, this class needs to worry about keeping track of the distinction
- // between left-side bounds and right-side bounds. Points are always submitted in pairs
- // which have a maximum longitude separation of Math.PI. It's therefore always possible
- // to determine which point represents a left bound, and which point represents a right
- // bound.
- //
- // The next problem is how to compare two of the same kind of bound, e.g. two left bounds.
- // We need to keep track of the leftmost longitude of the shape, but since this is a circle,
- // this is arbitrary. What we could try to do instead would be to find a pair of (left,right) bounds such
- // that:
- // (1) all other bounds are within, and
- // (2) the left minus right distance is minimized
- // Unfortunately, there are still shapes that cannot be summarized in this way correctly.
- // For example. consider a spiral that entirely circles the globe; we might arbitrarily choose
- // lat/lon bounds that do not in fact circle the globe.
- //
- // One way to handle the longitude issue correctly is therefore to stipulate that we
- // walk the bounds of the shape in some kind of connected order. Each point or circle is therefore
- // added in a sequence. We also need an interior point to make sure we have the right
- // choice of longitude bounds. But even with this, we still can't always choose whether the actual shape
- // goes right or left.
- //
- // We can make the specification truly general by submitting the following in order:
- // addSide(PlaneSide side, Membership... constraints)
- // ...
- // This is unambiguous, but I still can't see yet how this would help compute the bounds. The plane
- // solution would in general seem to boil down to the same logic that relies on points along the path
- // to define the shape boundaries. I guess the one thing that you do know for a bounded edge is that
- // the endpoints are actually connected. But it is not clear whether relationship helps in any way.
- //
- // In any case, if we specify shapes by a sequence of planes, we should stipulate that multiple sequences
- // are allowed, provided they progressively tile an area of the sphere that is connected and sequential.
- // For example, paths do alternating rectangles and circles, in sequence. Each sequence member is
- // described by a sequence of planes. I think it would also be reasonable to insist that the first segment
- // of a shape overlap or adjoin the previous shape.
- //
- // Here's a way to think about it that might help: Traversing every edge should grow the longitude bounds
- // in the direction of the traversal. So if the traversal is always known to be less than PI in total longitude
- // angle, then it is possible to use the endpoints to determine the unambiguous extension of the envelope.
- // For example, say you are currently at longitude -0.5. The next point is at longitude PI-0.1. You could say
- // that the difference in longitude going one way around would be beter than the distance the other way
- // around, and therefore the longitude envelope should be extended accordingly. But in practice, when an
- // edge goes near a pole and may be inclined as well, the longer longitude change might be the right path, even
- // if the arc length is short. So this too doesn't work.
- //
- // Given we have a hard time making an exact match, here's the current proposal. The proposal is a
- // heuristic, based on the idea that most areas are small compared to the circumference of the globe.
- // We keep track of the last point we saw, and take each point as it arrives, and compute its longitude.
- // Then, we have a choice as to which way to expand the envelope: we can expand by going to the left or
- // to the right. We choose the direction with the least longitude difference. (If we aren't sure,
- // and can recognize that, we can set "unconstrained in longitude".)
-
- /** If non-null, the left longitude bound */
- protected Double leftLongitude = null;
- /** If non-null, the right longitude bound */
- protected Double rightLongitude = null;
-
- /** Construct an empty bounds object */
- public LatLonBounds() {
- }
-
- // Accessor methods
-
- /** Get maximum latitude, if any.
- *@return maximum latitude or null.
- */
- public Double getMaxLatitude() {
- return maxLatitude;
- }
-
- /** Get minimum latitude, if any.
- *@return minimum latitude or null.
- */
- public Double getMinLatitude() {
- return minLatitude;
- }
-
- /** Get left longitude, if any.
- *@return left longitude, or null.
- */
- public Double getLeftLongitude() {
- return leftLongitude;
- }
-
- /** Get right longitude, if any.
- *@return right longitude, or null.
- */
- public Double getRightLongitude() {
- return rightLongitude;
- }
-
- // Degenerate case check
-
- /** Check if there's no longitude bound.
- *@return true if no longitude bound.
- */
- public boolean checkNoLongitudeBound() {
- return noLongitudeBound;
- }
-
- /** Check if there's no top latitude bound.
- *@return true if no top latitude bound.
- */
- public boolean checkNoTopLatitudeBound() {
- return noTopLatitudeBound;
- }
-
- /** Check if there's no bottom latitude bound.
- *@return true if no bottom latitude bound.
- */
- public boolean checkNoBottomLatitudeBound() {
- return noBottomLatitudeBound;
- }
-
- // Modification methods
-
- @Override
- public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds) {
- plane.recordBounds(planetModel, this, bounds);
- return this;
- }
-
- @Override
- public Bounds addHorizontalPlane(final PlanetModel planetModel,
- final double latitude,
- final Plane horizontalPlane,
- final Membership... bounds) {
- if (!noTopLatitudeBound || !noBottomLatitudeBound) {
- addLatitudeBound(latitude);
- }
- return this;
- }
-
- @Override
- public Bounds addVerticalPlane(final PlanetModel planetModel,
- final double longitude,
- final Plane verticalPlane,
- final Membership... bounds) {
- if (!noLongitudeBound) {
- addLongitudeBound(longitude);
- }
- return this;
- }
-
- @Override
- public Bounds isWide() {
- return noLongitudeBound();
- }
-
- @Override
- public Bounds addXValue(final GeoPoint point) {
- if (!noLongitudeBound) {
- // Get a longitude value
- addLongitudeBound(point.getLongitude());
- }
- return this;
- }
-
- @Override
- public Bounds addYValue(final GeoPoint point) {
- if (!noLongitudeBound) {
- // Get a longitude value
- addLongitudeBound(point.getLongitude());
- }
- return this;
- }
-
- @Override
- public Bounds addZValue(final GeoPoint point) {
- if (!noTopLatitudeBound || !noBottomLatitudeBound) {
- // Compute a latitude value
- double latitude = point.getLatitude();
- addLatitudeBound(latitude);
- }
- return this;
- }
-
- @Override
- public Bounds addPoint(GeoPoint point) {
- if (!noLongitudeBound) {
- // Get a longitude value
- addLongitudeBound(point.getLongitude());
- }
- if (!noTopLatitudeBound || !noBottomLatitudeBound) {
- // Compute a latitude value
- addLatitudeBound(point.getLatitude());
- }
- return this;
- }
-
- @Override
- public Bounds noLongitudeBound() {
- noLongitudeBound = true;
- leftLongitude = null;
- rightLongitude = null;
- return this;
- }
-
- @Override
- public Bounds noTopLatitudeBound() {
- noTopLatitudeBound = true;
- maxLatitude = null;
- return this;
- }
-
- @Override
- public Bounds noBottomLatitudeBound() {
- noBottomLatitudeBound = true;
- minLatitude = null;
- return this;
- }
-
- // Protected methods
-
- /** Update latitude bound.
- *@param latitude is the latitude.
- */
- protected void addLatitudeBound(double latitude) {
- if (!noTopLatitudeBound && (maxLatitude == null || latitude > maxLatitude))
- maxLatitude = latitude;
- if (!noBottomLatitudeBound && (minLatitude == null || latitude < minLatitude))
- minLatitude = latitude;
- }
-
- /** Update longitude bound.
- *@param longitude is the new longitude value.
- */
- protected void addLongitudeBound(double longitude) {
- // If this point is within the current bounds, we're done; otherwise
- // expand one side or the other.
- if (leftLongitude == null && rightLongitude == null) {
- leftLongitude = longitude;
- rightLongitude = longitude;
- } else {
- // Compute whether we're to the right of the left value. But the left value may be greater than
- // the right value.
- double currentLeftLongitude = leftLongitude;
- double currentRightLongitude = rightLongitude;
- if (currentRightLongitude < currentLeftLongitude)
- currentRightLongitude += 2.0 * Math.PI;
- // We have a range to look at that's going in the right way.
- // Now, do the same trick with the computed longitude.
- if (longitude < currentLeftLongitude)
- longitude += 2.0 * Math.PI;
-
- if (longitude < currentLeftLongitude || longitude > currentRightLongitude) {
- // Outside of current bounds. Consider carefully how we'll expand.
- double leftExtensionAmt;
- double rightExtensionAmt;
- if (longitude < currentLeftLongitude) {
- leftExtensionAmt = currentLeftLongitude - longitude;
- } else {
- leftExtensionAmt = currentLeftLongitude + 2.0 * Math.PI - longitude;
- }
- if (longitude > currentRightLongitude) {
- rightExtensionAmt = longitude - currentRightLongitude;
- } else {
- rightExtensionAmt = longitude + 2.0 * Math.PI - currentRightLongitude;
- }
- if (leftExtensionAmt < rightExtensionAmt) {
- currentLeftLongitude = leftLongitude - leftExtensionAmt;
- while (currentLeftLongitude <= -Math.PI) {
- currentLeftLongitude += 2.0 * Math.PI;
- }
- leftLongitude = currentLeftLongitude;
- } else {
- currentRightLongitude = rightLongitude + rightExtensionAmt;
- while (currentRightLongitude > Math.PI) {
- currentRightLongitude -= 2.0 * Math.PI;
- }
- rightLongitude = currentRightLongitude;
- }
- }
- }
- double testRightLongitude = rightLongitude;
- if (testRightLongitude < leftLongitude)
- testRightLongitude += Math.PI * 2.0;
- if (testRightLongitude - leftLongitude >= Math.PI) {
- noLongitudeBound = true;
- leftLongitude = null;
- rightLongitude = null;
- }
- }
-
-}
[38/50] [abbrv] lucene-solr git commit: LUCENE-7083: default points
merge logic should not ask a reader to merge points on a field that doesn't
exist in that segment
Posted by no...@apache.org.
LUCENE-7083: default points merge logic should not ask a reader to merge points on a field that doesn't exist in that segment
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2cac33a5
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2cac33a5
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2cac33a5
Branch: refs/heads/apiv2
Commit: 2cac33a5ce7b64713eba6e22d5f7c9122ab8eafe
Parents: 9393a31
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 8 13:28:28 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 8 13:28:28 2016 -0500
----------------------------------------------------------------------
.../org/apache/lucene/codecs/PointsWriter.java | 6 ++++++
.../org/apache/lucene/index/IndexWriter.java | 1 +
.../apache/lucene/index/TestPointValues.java | 20 ++++++++++++++++++++
3 files changed, 27 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2cac33a5/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java
index 56689ec..53db281 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java
@@ -54,6 +54,12 @@ public abstract class PointsWriter implements Closeable {
// This segment has no points
continue;
}
+ FieldInfo readerFieldInfo = mergeState.fieldInfos[i].fieldInfo(fieldName);
+ if (readerFieldInfo == null) {
+ // This segment never saw this field
+ continue;
+ }
+
MergeState.DocMap docMap = mergeState.docMaps[i];
int docBase = mergeState.docBase[i];
pointsReader.intersect(fieldInfo.name,
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2cac33a5/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
index 57ce3dd..66a0e73 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
@@ -4116,6 +4116,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable {
(mergeState.mergeFieldInfos.hasDocValues() ? "docValues" : "no docValues") + "; " +
(mergeState.mergeFieldInfos.hasProx() ? "prox" : "no prox") + "; " +
(mergeState.mergeFieldInfos.hasProx() ? "freqs" : "no freqs") + "; " +
+ (mergeState.mergeFieldInfos.hasPointValues() ? "points" : "no points") + "; " +
String.format(Locale.ROOT,
"%.1f sec (%.1f sec stopped, %.1f sec paused) to merge segment [%.2f MB, %.2f MB/sec]",
sec,
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2cac33a5/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
index 7231b1a..9ced11a 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
@@ -39,6 +39,7 @@ import org.apache.lucene.index.PointValues.IntersectVisitor;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.index.PointValues;
import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
@@ -562,4 +563,23 @@ public class TestPointValues extends LuceneTestCase {
r.close();
dir.close();
}
+
+ public void testPointsFieldMissingFromOneSegment() throws Exception {
+ Directory dir = FSDirectory.open(createTempDir());
+ IndexWriterConfig iwc = new IndexWriterConfig(null);
+ IndexWriter w = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ doc.add(new StringField("id", "0", Field.Store.NO));
+ doc.add(new IntPoint("int0", 0));
+ w.addDocument(doc);
+ w.commit();
+
+ doc = new Document();
+ doc.add(new IntPoint("int1", 17));
+ w.addDocument(doc);
+ w.forceMerge(1);
+
+ w.close();
+ dir.close();
+ }
}
[17/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java
deleted file mode 100644
index f6a2fa3..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYZSolid.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Y
- *
- * @lucene.internal
- */
-public class XdYZSolid extends BaseXYZSolid {
-
- /** Min-X plane */
- protected final SidedPlane minXPlane;
- /** Max-X plane */
- protected final SidedPlane maxXPlane;
- /** Y plane */
- protected final Plane yPlane;
- /** Min-Z plane */
- protected final SidedPlane minZPlane;
- /** Max-Z plane */
- protected final SidedPlane maxZPlane;
-
- /** These are the edge points of the shape, which are defined to be at least one point on
- * each surface area boundary. In the case of a solid, this includes points which represent
- * the intersection of XYZ bounding planes and the planet, as well as points representing
- * the intersection of single bounding planes with the planet itself.
- */
- protected final GeoPoint[] edgePoints;
-
- /** Notable points for YPlane */
- protected final GeoPoint[] notableYPoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param minX is the minimum X value.
- *@param maxX is the maximum X value.
- *@param Y is the Y value.
- *@param minZ is the minimum Z value.
- *@param maxZ is the maximum Z value.
- */
- public XdYZSolid(final PlanetModel planetModel,
- final double minX,
- final double maxX,
- final double Y,
- final double minZ,
- final double maxZ) {
- super(planetModel);
- // Argument checking
- if (maxX - minX < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("X values in wrong order or identical");
- if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Z values in wrong order or identical");
-
- final double worldMinY = planetModel.getMinimumYValue();
- final double worldMaxY = planetModel.getMaximumYValue();
-
- // Construct the planes
- minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
- maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
- yPlane = new Plane(yUnitVector,-Y);
- minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
- maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
-
- // We need at least one point on the planet surface for each manifestation of the shape.
- // There can be up to 2 (on opposite sides of the world). But we have to go through
- // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
- // Typically, this requires 4 square root operations.
- final GeoPoint[] minXY = minXPlane.findIntersections(planetModel,yPlane,maxXPlane,minZPlane,maxZPlane);
- final GeoPoint[] maxXY = maxXPlane.findIntersections(planetModel,yPlane,minXPlane,minZPlane,maxZPlane);
- final GeoPoint[] YminZ = yPlane.findIntersections(planetModel,minZPlane,maxZPlane,minXPlane,maxXPlane);
- final GeoPoint[] YmaxZ = yPlane.findIntersections(planetModel,maxZPlane,minZPlane,minXPlane,maxXPlane);
-
- notableYPoints = glueTogether(minXY, maxXY, YminZ, YmaxZ);
-
- // Now, compute the edge points.
- // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
- // we'll start there. We know that at most there will be two disconnected shapes on the planet surface.
- // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
- // intersections do. Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
-
- // We need to look at single-plane/world intersections.
- // We detect these by looking at the world model and noting its x, y, and z bounds.
- // The cases we are looking for are when the four corner points for any given
- // plane are all outside of the world, AND that plane intersects the world.
- // There are four corner points all told; we must evaluate these WRT the planet surface.
- final boolean minXYminZ = planetModel.pointOutside(minX, Y, minZ);
- final boolean minXYmaxZ = planetModel.pointOutside(minX, Y, maxZ);
- final boolean maxXYminZ = planetModel.pointOutside(maxX, Y, minZ);
- final boolean maxXYmaxZ = planetModel.pointOutside(maxX, Y, maxZ);
-
- final GeoPoint[] yEdges;
- if (Y - worldMinY >= -Vector.MINIMUM_RESOLUTION && Y - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
- minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
- minXYminZ && minXYmaxZ && maxXYminZ && maxXYmaxZ) {
- // Find any point on the minY plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = yPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
- if (intPoint != null) {
- yEdges = new GeoPoint[]{intPoint};
- } else {
- yEdges = EMPTY_POINTS;
- }
- } else {
- yEdges = EMPTY_POINTS;
- }
-
- this.edgePoints = glueTogether(minXY, maxXY, YminZ, YmaxZ, yEdges);
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return minXPlane.isWithin(x, y, z) &&
- maxXPlane.isWithin(x, y, z) &&
- yPlane.evaluateIsZero(x, y, z) &&
- minZPlane.isWithin(x, y, z) &&
- maxZPlane.isWithin(x, y, z);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(yPlane, notableYPoints, minXPlane, maxXPlane, minZPlane, maxZPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof XdYZSolid))
- return false;
- XdYZSolid other = (XdYZSolid) o;
- if (!super.equals(other)) {
- return false;
- }
- return other.minXPlane.equals(minXPlane) &&
- other.maxXPlane.equals(maxXPlane) &&
- other.yPlane.equals(yPlane) &&
- other.minZPlane.equals(minZPlane) &&
- other.maxZPlane.equals(maxZPlane);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + minXPlane.hashCode();
- result = 31 * result + maxXPlane.hashCode();
- result = 31 * result + yPlane.hashCode();
- result = 31 * result + minZPlane.hashCode();
- result = 31 * result + maxZPlane.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "XdYZSolid: {planetmodel="+planetModel+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", yplane="+yPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java
deleted file mode 100644
index 562e5a6..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XdYdZSolid.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Y and Z.
- * This figure, in fact, represents either zero, one, or two points, so the
- * actual data stored is minimal.
- *
- * @lucene.internal
- */
-public class XdYdZSolid extends BaseXYZSolid {
-
- /** The points in this figure on the planet surface; also doubles for edge points */
- protected final GeoPoint[] surfacePoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param minX is the minimum X value.
- *@param maxX is the maximum X value.
- *@param Y is the Y value.
- *@param Z is the Z value.
- */
- public XdYdZSolid(final PlanetModel planetModel,
- final double minX,
- final double maxX,
- final double Y,
- final double Z) {
- super(planetModel);
- // Argument checking
- if (maxX - minX < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("X values in wrong order or identical");
-
- // Build the planes and intersect them.
- final Plane yPlane = new Plane(yUnitVector,-Y);
- final Plane zPlane = new Plane(zUnitVector,-Z);
- final SidedPlane minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
- final SidedPlane maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
- surfacePoints = yPlane.findIntersections(planetModel,zPlane,minXPlane,maxXPlane);
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return surfacePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- for (final GeoPoint p : surfacePoints) {
- if (p.isIdentical(x,y,z))
- return true;
- }
- return false;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof XdYdZSolid))
- return false;
- XdYdZSolid other = (XdYdZSolid) o;
- if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
- return false;
- }
- for (int i = 0; i < surfacePoints.length; i++) {
- if (!surfacePoints[i].equals(other.surfacePoints[i]))
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- for (final GeoPoint p : surfacePoints) {
- result = 31 * result + p.hashCode();
- }
- return result;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- for (final GeoPoint p : surfacePoints) {
- sb.append(" ").append(p).append(" ");
- }
- return "XdYdZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java
deleted file mode 100644
index 5a2a006..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYZSolid.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X.
- *
- * @lucene.internal
- */
-public class dXYZSolid extends BaseXYZSolid {
-
- /** X plane */
- protected final Plane xPlane;
- /** Min-Y plane */
- protected final SidedPlane minYPlane;
- /** Max-Y plane */
- protected final SidedPlane maxYPlane;
- /** Min-Z plane */
- protected final SidedPlane minZPlane;
- /** Max-Z plane */
- protected final SidedPlane maxZPlane;
-
- /** These are the edge points of the shape, which are defined to be at least one point on
- * each surface area boundary. In the case of a solid, this includes points which represent
- * the intersection of XYZ bounding planes and the planet, as well as points representing
- * the intersection of single bounding planes with the planet itself.
- */
- protected final GeoPoint[] edgePoints;
-
- /** Notable points for XPlane */
- protected final GeoPoint[] notableXPoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param X is the X value.
- *@param minY is the minimum Y value.
- *@param maxY is the maximum Y value.
- *@param minZ is the minimum Z value.
- *@param maxZ is the maximum Z value.
- */
- public dXYZSolid(final PlanetModel planetModel,
- final double X,
- final double minY,
- final double maxY,
- final double minZ,
- final double maxZ) {
- super(planetModel);
- // Argument checking
- if (maxY - minY < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Y values in wrong order or identical");
- if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Z values in wrong order or identical");
-
- final double worldMinX = planetModel.getMinimumXValue();
- final double worldMaxX = planetModel.getMaximumXValue();
-
- // Construct the planes
- xPlane = new Plane(xUnitVector,-X);
- minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
- maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
- minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
- maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
-
- // We need at least one point on the planet surface for each manifestation of the shape.
- // There can be up to 2 (on opposite sides of the world). But we have to go through
- // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
- // Typically, this requires 4 square root operations.
- final GeoPoint[] XminY = xPlane.findIntersections(planetModel,minYPlane,maxYPlane,minZPlane,maxZPlane);
- final GeoPoint[] XmaxY = xPlane.findIntersections(planetModel,maxYPlane,minYPlane,minZPlane,maxZPlane);
- final GeoPoint[] XminZ = xPlane.findIntersections(planetModel,minZPlane,maxZPlane,minYPlane,maxYPlane);
- final GeoPoint[] XmaxZ = xPlane.findIntersections(planetModel,maxZPlane,minZPlane,minYPlane,maxYPlane);
-
- notableXPoints = glueTogether(XminY, XmaxY, XminZ, XmaxZ);
-
- // Now, compute the edge points.
- // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
- // we'll start there. We know that at most there will be two disconnected shapes on the planet surface.
- // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
- // intersections do. Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
-
- // We need to look at single-plane/world intersections.
- // We detect these by looking at the world model and noting its x, y, and z bounds.
- // For the single-dimension degenerate case, there's really only one plane that can possibly intersect the world.
- // The cases we are looking for are when the four corner points for any given
- // plane are all outside of the world, AND that plane intersects the world.
- // There are four corner points all told; we must evaluate these WRT the planet surface.
- final boolean XminYminZ = planetModel.pointOutside(X, minY, minZ);
- final boolean XminYmaxZ = planetModel.pointOutside(X, minY, maxZ);
- final boolean XmaxYminZ = planetModel.pointOutside(X, maxY, minZ);
- final boolean XmaxYmaxZ = planetModel.pointOutside(X, maxY, maxZ);
-
- final GeoPoint[] xEdges;
- if (X - worldMinX >= -Vector.MINIMUM_RESOLUTION && X - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
- minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
- XminYminZ && XminYmaxZ && XmaxYminZ && XmaxYmaxZ) {
- // Find any point on the X plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = xPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
- if (intPoint != null) {
- xEdges = new GeoPoint[]{intPoint};
- } else {
- xEdges = EMPTY_POINTS;
- }
- } else {
- xEdges = EMPTY_POINTS;
- }
-
- this.edgePoints = glueTogether(XminY,XmaxY,XminZ,XmaxZ,xEdges);
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return xPlane.evaluateIsZero(x, y, z) &&
- minYPlane.isWithin(x, y, z) &&
- maxYPlane.isWithin(x, y, z) &&
- minZPlane.isWithin(x, y, z) &&
- maxZPlane.isWithin(x, y, z);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some shape points inside area");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- //System.err.println(" some area points inside shape");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- // The entire locus of points in this shape is on a single plane, so we only need ot look for an intersection with that plane.
- //System.err.println("xPlane = "+xPlane);
- if (path.intersects(xPlane, notableXPoints, minYPlane, maxYPlane, minZPlane, maxZPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape points inside area");
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains all area");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof dXYZSolid))
- return false;
- dXYZSolid other = (dXYZSolid) o;
- if (!super.equals(other)) {
- return false;
- }
- return other.xPlane.equals(xPlane) &&
- other.minYPlane.equals(minYPlane) &&
- other.maxYPlane.equals(maxYPlane) &&
- other.minZPlane.equals(minZPlane) &&
- other.maxZPlane.equals(maxZPlane);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + xPlane.hashCode();
- result = 31 * result + minYPlane.hashCode();
- result = 31 * result + maxYPlane.hashCode();
- result = 31 * result + minZPlane.hashCode();
- result = 31 * result + maxZPlane.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "dXYZSolid: {planetmodel="+planetModel+", xplane="+xPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java
deleted file mode 100644
index 96b3004..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXYdZSolid.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X and Z.
- * This figure, in fact, represents either zero, one, or two points, so the
- * actual data stored is minimal.
- *
- * @lucene.internal
- */
-public class dXYdZSolid extends BaseXYZSolid {
-
- /** The points in this figure on the planet surface; also doubles for edge points */
- protected final GeoPoint[] surfacePoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param X is the X value.
- *@param minY is the minimum Y value.
- *@param maxY is the maximum Y value.
- *@param Z is the Z value.
- */
- public dXYdZSolid(final PlanetModel planetModel,
- final double X,
- final double minY,
- final double maxY,
- final double Z) {
- super(planetModel);
- // Argument checking
- if (maxY - minY < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Y values in wrong order or identical");
-
- // Build the planes and intersect them.
- final Plane xPlane = new Plane(xUnitVector,-X);
- final Plane zPlane = new Plane(zUnitVector,-Z);
- final SidedPlane minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
- final SidedPlane maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
- surfacePoints = xPlane.findIntersections(planetModel,zPlane,minYPlane,maxYPlane);
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return surfacePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- for (final GeoPoint p : surfacePoints) {
- if (p.isIdentical(x,y,z))
- return true;
- }
- return false;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof dXYdZSolid))
- return false;
- dXYdZSolid other = (dXYdZSolid) o;
- if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
- return false;
- }
- for (int i = 0; i < surfacePoints.length; i++) {
- if (!surfacePoints[i].equals(other.surfacePoints[i]))
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- for (final GeoPoint p : surfacePoints) {
- result = 31 * result + p.hashCode();
- }
- return result;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- for (final GeoPoint p : surfacePoints) {
- sb.append(" ").append(p).append(" ");
- }
- return "dXYdZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java
deleted file mode 100644
index b58cd92..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYZSolid.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X and Y.
- * This figure, in fact, represents either zero, one, or two points, so the
- * actual data stored is minimal.
- *
- * @lucene.internal
- */
-public class dXdYZSolid extends BaseXYZSolid {
-
- /** The points in this figure on the planet surface; also doubles for edge points */
- protected final GeoPoint[] surfacePoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param X is the X value.
- *@param Y is the Y value.
- *@param minZ is the minimum Z value.
- *@param maxZ is the maximum Z value.
- */
- public dXdYZSolid(final PlanetModel planetModel,
- final double X,
- final double Y,
- final double minZ,
- final double maxZ) {
- super(planetModel);
- // Argument checking
- if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Z values in wrong order or identical");
-
- // Build the planes and intersect them.
- final Plane xPlane = new Plane(xUnitVector,-X);
- final Plane yPlane = new Plane(yUnitVector,-Y);
- final SidedPlane minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
- final SidedPlane maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
- surfacePoints = xPlane.findIntersections(planetModel,yPlane,minZPlane,maxZPlane);
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return surfacePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- for (final GeoPoint p : surfacePoints) {
- if (p.isIdentical(x,y,z))
- return true;
- }
- return false;
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof dXdYZSolid))
- return false;
- dXdYZSolid other = (dXdYZSolid) o;
- if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
- return false;
- }
- for (int i = 0; i < surfacePoints.length; i++) {
- if (!surfacePoints[i].equals(other.surfacePoints[i]))
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- for (final GeoPoint p : surfacePoints) {
- result = 31 * result + p.hashCode();
- }
- return result;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- for (final GeoPoint p : surfacePoints) {
- sb.append(" ").append(p).append(" ");
- }
- return "dXdYZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java
deleted file mode 100644
index b26cf63..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/dXdYdZSolid.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in all dimensions
- *
- * @lucene.internal
- */
-public class dXdYdZSolid extends BaseXYZSolid {
-
- /** On surface? */
- protected final boolean isOnSurface;
- /** The point */
- protected final GeoPoint thePoint;
-
- /** These are the edge points of the shape, which are defined to be at least one point on
- * each surface area boundary. In the case of a solid, this includes points which represent
- * the intersection of XYZ bounding planes and the planet, as well as points representing
- * the intersection of single bounding planes with the planet itself.
- */
- protected final GeoPoint[] edgePoints;
-
- /** Empty array of {@link GeoPoint}. */
- protected static final GeoPoint[] nullPoints = new GeoPoint[0];
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param X is the X value.
- *@param Y is the Y value.
- *@param Z is the Z value.
- */
- public dXdYdZSolid(final PlanetModel planetModel,
- final double X,
- final double Y,
- final double Z) {
- super(planetModel);
- isOnSurface = planetModel.pointOnSurface(X,Y,Z);
- if (isOnSurface) {
- thePoint = new GeoPoint(X,Y,Z);
- edgePoints = new GeoPoint[]{thePoint};
- } else {
- thePoint = null;
- edgePoints = nullPoints;
- }
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- if (!isOnSurface) {
- return false;
- }
- return thePoint.isIdentical(x,y,z);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- if (!isOnSurface) {
- return DISJOINT;
- }
-
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some shape points inside area");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- //System.err.println(" some area points inside shape");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside area entirely");
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains area entirely");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof dXdYdZSolid))
- return false;
- dXdYdZSolid other = (dXdYdZSolid) o;
- if (!super.equals(other) ||
- other.isOnSurface != isOnSurface) {
- return false;
- }
- if (isOnSurface) {
- return other.thePoint.equals(thePoint);
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (isOnSurface?1:0);
- if (isOnSurface) {
- result = 31 * result + thePoint.hashCode();
- }
- return result;
- }
-
- @Override
- public String toString() {
- return "dXdYdZSolid: {planetmodel="+planetModel+", isOnSurface="+isOnSurface+", thePoint="+thePoint+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java
deleted file mode 100644
index 2b6af74..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Shapes implemented using 3D planar geometry.
- */
-package org.apache.lucene.geo3d;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
new file mode 100644
index 0000000..cd2c79a
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d;
+
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.NumericUtils;
+
+/**
+ * Add this to a document to index lat/lon or x/y/z point, indexed as a 3D point.
+ * Multiple values are allowed: just add multiple Geo3DPoint to the document with the
+ * same field name.
+ * <p>
+ * This field defines static factory methods for creating a shape query:
+ * <ul>
+ * <li>{@link #newShapeQuery newShapeQuery()} for matching all points inside a specified shape
+ * </ul>
+ *
+ * @lucene.experimental */
+public final class Geo3DPoint extends Field {
+
+ /** Indexing {@link FieldType}. */
+ public static final FieldType TYPE = new FieldType();
+ static {
+ TYPE.setDimensions(3, Integer.BYTES);
+ TYPE.freeze();
+ }
+
+ /**
+ * Creates a new Geo3DPoint field with the specified lat, lon (in radians).
+ *
+ * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
+ */
+ public Geo3DPoint(String name, double lat, double lon) {
+ super(name, TYPE);
+ // Translate lat/lon to x,y,z:
+ final GeoPoint point = new GeoPoint(PlanetModel.WGS84, lat, lon);
+ fillFieldsData(point.x, point.y, point.z);
+ }
+
+ /**
+ * Creates a new Geo3DPoint field with the specified x,y,z.
+ *
+ * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
+ */
+ public Geo3DPoint(String name, double x, double y, double z) {
+ super(name, TYPE);
+ fillFieldsData(x, y, z);
+ }
+
+ private void fillFieldsData(double x, double y, double z) {
+ byte[] bytes = new byte[12];
+ encodeDimension(x, bytes, 0);
+ encodeDimension(y, bytes, Integer.BYTES);
+ encodeDimension(z, bytes, 2*Integer.BYTES);
+ fieldsData = new BytesRef(bytes);
+ }
+
+ // public helper methods (e.g. for queries)
+
+ /** Encode single dimension */
+ public static void encodeDimension(double value, byte bytes[], int offset) {
+ NumericUtils.intToSortableBytes(Geo3DUtil.encodeValue(PlanetModel.WGS84.getMaximumMagnitude(), value), bytes, offset);
+ }
+
+ /** Decode single dimension */
+ public static double decodeDimension(byte value[], int offset) {
+ return Geo3DUtil.decodeValueCenter(PlanetModel.WGS84.getMaximumMagnitude(), NumericUtils.sortableBytesToInt(value, offset));
+ }
+
+ /** Returns a query matching all points inside the provided shape.
+ *
+ * @param field field name. must not be {@code null}.
+ * @param shape Which {@link GeoShape} to match
+ */
+ public static Query newShapeQuery(String field, GeoShape shape) {
+ return new PointInGeo3DShapeQuery(field, shape);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append(getClass().getSimpleName());
+ result.append(" <");
+ result.append(name);
+ result.append(':');
+
+ BytesRef bytes = (BytesRef) fieldsData;
+ result.append(" x=" + decodeDimension(bytes.bytes, bytes.offset));
+ result.append(" y=" + decodeDimension(bytes.bytes, bytes.offset + Integer.BYTES));
+ result.append(" z=" + decodeDimension(bytes.bytes, bytes.offset + 2*Integer.BYTES));
+ result.append('>');
+ return result.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
new file mode 100644
index 0000000..0a0bf30
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d;
+
+class Geo3DUtil {
+
+ /** Clips the incoming value to the allowed min/max range before encoding, instead of throwing an exception. */
+ public static int encodeValueLenient(double planetMax, double x) {
+ if (x > planetMax) {
+ x = planetMax;
+ } else if (x < -planetMax) {
+ x = -planetMax;
+ }
+ return encodeValue(planetMax, x);
+ }
+
+ public static int encodeValue(double planetMax, double x) {
+ if (x > planetMax) {
+ throw new IllegalArgumentException("value=" + x + " is out-of-bounds (greater than planetMax=" + planetMax + ")");
+ }
+ if (x < -planetMax) {
+ throw new IllegalArgumentException("value=" + x + " is out-of-bounds (less than than -planetMax=" + -planetMax + ")");
+ }
+ long y = Math.round (x * (Integer.MAX_VALUE / planetMax));
+ assert y >= Integer.MIN_VALUE;
+ assert y <= Integer.MAX_VALUE;
+
+ return (int) y;
+ }
+
+ /** Center decode */
+ public static double decodeValueCenter(double planetMax, int x) {
+ return x * (planetMax / Integer.MAX_VALUE);
+ }
+
+ /** More negative decode, at bottom of cell */
+ public static double decodeValueMin(double planetMax, int x) {
+ return (((double)x) - 0.5) * (planetMax / Integer.MAX_VALUE);
+ }
+
+ /** More positive decode, at top of cell */
+ public static double decodeValueMax(double planetMax, int x) {
+ return (((double)x) + 0.5) * (planetMax / Integer.MAX_VALUE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
new file mode 100644
index 0000000..9df8752
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d;
+
+import java.io.IOException;
+
+import org.apache.lucene.spatial3d.geom.BasePlanetObject;
+import org.apache.lucene.spatial3d.geom.GeoArea;
+import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
+import org.apache.lucene.index.PointValues.IntersectVisitor;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.index.PointValues.Relation;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.util.DocIdSetBuilder;
+import org.apache.lucene.util.NumericUtils;
+
+/** Finds all previously indexed points that fall within the specified polygon.
+ *
+ * <p>The field must be indexed using {@link Geo3DPoint}.
+ *
+ * @lucene.experimental */
+
+class PointInGeo3DShapeQuery extends Query {
+ final String field;
+ final GeoShape shape;
+
+ /** The lats/lons must be clockwise or counter-clockwise. */
+ public PointInGeo3DShapeQuery(String field, GeoShape shape) {
+ this.field = field;
+ this.shape = shape;
+
+ if (shape instanceof BasePlanetObject) {
+ BasePlanetObject planetObject = (BasePlanetObject) shape;
+ if (planetObject.getPlanetModel().equals(PlanetModel.WGS84) == false) {
+ throw new IllegalArgumentException("this qurey requires PlanetModel.WGS84, but got: " + planetObject.getPlanetModel());
+ }
+ }
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+
+ // I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
+ // used in the first pass:
+
+ return new ConstantScoreWeight(this) {
+
+ @Override
+ public Scorer scorer(LeafReaderContext context) throws IOException {
+ LeafReader reader = context.reader();
+ PointValues values = reader.getPointValues();
+ if (values == null) {
+ return null;
+ }
+
+ /*
+ XYZBounds bounds = new XYZBounds();
+ shape.getBounds(bounds);
+
+ final double planetMax = planetModel.getMaximumMagnitude();
+ if (planetMax != treeDV.planetMax) {
+ throw new IllegalStateException(planetModel + " is not the same one used during indexing: planetMax=" + planetMax + " vs indexing planetMax=" + treeDV.planetMax);
+ }
+ */
+
+ /*
+ GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(planetModel,
+ bounds.getMinimumX(),
+ bounds.getMaximumX(),
+ bounds.getMinimumY(),
+ bounds.getMaximumY(),
+ bounds.getMinimumZ(),
+ bounds.getMaximumZ());
+
+ assert xyzSolid.getRelationship(shape) == GeoArea.WITHIN || xyzSolid.getRelationship(shape) == GeoArea.OVERLAPS: "expected WITHIN (1) or OVERLAPS (2) but got " + xyzSolid.getRelationship(shape) + "; shape="+shape+"; XYZSolid="+xyzSolid;
+ */
+
+ double planetMax = PlanetModel.WGS84.getMaximumMagnitude();
+
+ DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
+
+ values.intersect(field,
+ new IntersectVisitor() {
+
+ @Override
+ public void visit(int docID) {
+ result.add(docID);
+ }
+
+ @Override
+ public void visit(int docID, byte[] packedValue) {
+ assert packedValue.length == 12;
+ double x = Geo3DPoint.decodeDimension(packedValue, 0);
+ double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES);
+ double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES);
+ if (shape.isWithin(x, y, z)) {
+ result.add(docID);
+ }
+ }
+
+ @Override
+ public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
+ // Because the dimensional format operates in quantized (64 bit -> 32 bit) space, and the cell bounds
+ // here are inclusive, we need to extend the bounds to the largest un-quantized values that
+ // could quantize into these bounds. The encoding (Geo3DUtil.encodeValue) does
+ // a Math.round from double to long, so e.g. 1.4 -> 1, and -1.4 -> -1:
+ double xMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 0));
+ double xMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 0));
+ double yMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 1 * Integer.BYTES));
+ double yMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 1 * Integer.BYTES));
+ double zMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 2 * Integer.BYTES));
+ double zMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 2 * Integer.BYTES));
+
+ //System.out.println(" compare: x=" + cellXMin + "-" + cellXMax + " y=" + cellYMin + "-" + cellYMax + " z=" + cellZMin + "-" + cellZMax);
+ assert xMin <= xMax;
+ assert yMin <= yMax;
+ assert zMin <= zMax;
+
+ GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, xMin, xMax, yMin, yMax, zMin, zMax);
+
+ switch(xyzSolid.getRelationship(shape)) {
+ case GeoArea.CONTAINS:
+ // Shape fully contains the cell
+ //System.out.println(" inside");
+ return Relation.CELL_INSIDE_QUERY;
+ case GeoArea.OVERLAPS:
+ // They do overlap but neither contains the other:
+ //System.out.println(" crosses1");
+ return Relation.CELL_CROSSES_QUERY;
+ case GeoArea.WITHIN:
+ // Cell fully contains the shape:
+ //System.out.println(" crosses2");
+ // return Relation.SHAPE_INSIDE_CELL;
+ return Relation.CELL_CROSSES_QUERY;
+ case GeoArea.DISJOINT:
+ // They do not overlap at all
+ //System.out.println(" outside");
+ return Relation.CELL_OUTSIDE_QUERY;
+ default:
+ assert false;
+ return Relation.CELL_CROSSES_QUERY;
+ }
+ }
+ });
+
+ return new ConstantScoreScorer(this, score(), result.build().iterator());
+ }
+ };
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public GeoShape getShape() {
+ return shape;
+ }
+
+ @Override
+ @SuppressWarnings({"unchecked","rawtypes"})
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ if (!super.equals(o)) return false;
+
+ PointInGeo3DShapeQuery that = (PointInGeo3DShapeQuery) o;
+
+ return shape.equals(that.shape);
+ }
+
+ @Override
+ public final int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + shape.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString(String field) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(getClass().getSimpleName());
+ sb.append(':');
+ if (this.field.equals(field) == false) {
+ sb.append(" field=");
+ sb.append(this.field);
+ sb.append(':');
+ }
+ sb.append(" Shape: ");
+ sb.append(shape);
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
new file mode 100644
index 0000000..bb60be0
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Arc distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class ArcDistance implements DistanceStyle {
+
+ /** An instance of the ArcDistance DistanceStyle. */
+ public final static ArcDistance INSTANCE = new ArcDistance();
+
+ /** Constructor.
+ */
+ public ArcDistance() {
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.arcDistance(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.arcDistance(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.arcDistance(planetModel, point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.arcDistance(planetModel, x,y,z, bounds);
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java
new file mode 100644
index 0000000..5cd5acc
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BasePlanetObject.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * All Geo3D shapes can derive from this base class, which furnishes
+ * some common code
+ *
+ * @lucene.internal
+ */
+public abstract class BasePlanetObject {
+
+ /** This is the planet model embedded in all objects derived from this
+ * class. */
+ protected final PlanetModel planetModel;
+
+ /** Constructor creating class instance given a planet model.
+ * @param planetModel is the planet model.
+ */
+ public BasePlanetObject(final PlanetModel planetModel) {
+ this.planetModel = planetModel;
+ }
+
+ /** Returns the {@link PlanetModel} provided when this shape was created. */
+ public PlanetModel getPlanetModel() {
+ return planetModel;
+ }
+
+ @Override
+ public int hashCode() {
+ return planetModel.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof BasePlanetObject))
+ return false;
+ return planetModel.equals(((BasePlanetObject)o).planetModel);
+ }
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java
new file mode 100644
index 0000000..16b52cc
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/BaseXYZSolid.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Base class of a family of 3D rectangles, bounded on six sides by X,Y,Z limits
+ *
+ * @lucene.internal
+ */
+public abstract class BaseXYZSolid extends BasePlanetObject implements XYZSolid {
+
+ /** Unit vector in x */
+ protected static final Vector xUnitVector = new Vector(1.0, 0.0, 0.0);
+ /** Unit vector in y */
+ protected static final Vector yUnitVector = new Vector(0.0, 1.0, 0.0);
+ /** Unit vector in z */
+ protected static final Vector zUnitVector = new Vector(0.0, 0.0, 1.0);
+
+ /** Vertical plane normal to x unit vector passing through origin */
+ protected static final Plane xVerticalPlane = new Plane(0.0, 1.0, 0.0, 0.0);
+ /** Vertical plane normal to y unit vector passing through origin */
+ protected static final Plane yVerticalPlane = new Plane(1.0, 0.0, 0.0, 0.0);
+
+ /** Empty point vector */
+ protected static final GeoPoint[] EMPTY_POINTS = new GeoPoint[0];
+
+ /**
+ * Base solid constructor.
+ *@param planetModel is the planet model.
+ */
+ public BaseXYZSolid(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+ /** Construct a single array from a number of individual arrays.
+ * @param pointArrays is the array of point arrays.
+ * @return the single unified array.
+ */
+ protected static GeoPoint[] glueTogether(final GeoPoint[]... pointArrays) {
+ int count = 0;
+ for (final GeoPoint[] pointArray : pointArrays) {
+ count += pointArray.length;
+ }
+ final GeoPoint[] rval = new GeoPoint[count];
+ count = 0;
+ for (final GeoPoint[] pointArray : pointArrays) {
+ for (final GeoPoint point : pointArray) {
+ rval[count++] = point;
+ }
+ }
+ return rval;
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
+
+ @Override
+ public abstract boolean isWithin(final double x, final double y, final double z);
+
+ // Signals for relationship of edge points to shape
+
+ /** All edgepoints inside shape */
+ protected final static int ALL_INSIDE = 0;
+ /** Some edgepoints inside shape */
+ protected final static int SOME_INSIDE = 1;
+ /** No edgepoints inside shape */
+ protected final static int NONE_INSIDE = 2;
+ /** No edgepoints at all (means a shape that is the whole world) */
+ protected final static int NO_EDGEPOINTS = 3;
+
+ /** Determine the relationship between this area and the provided
+ * shape's edgepoints.
+ *@param path is the shape.
+ *@return the relationship.
+ */
+ protected int isShapeInsideArea(final GeoShape path) {
+ final GeoPoint[] pathPoints = path.getEdgePoints();
+ if (pathPoints.length == 0)
+ return NO_EDGEPOINTS;
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (final GeoPoint p : pathPoints) {
+ if (isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+ /** Determine the relationship between a shape and this area's
+ * edgepoints.
+ *@param path is the shape.
+ *@return the relationship.
+ */
+ protected int isAreaInsideShape(final GeoShape path) {
+ final GeoPoint[] edgePoints = getEdgePoints();
+ if (edgePoints.length == 0) {
+ return NO_EDGEPOINTS;
+ }
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (final GeoPoint p : edgePoints) {
+ if (path.isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+ /** Get the edge points for this shape.
+ *@return the edge points.
+ */
+ protected abstract GeoPoint[] getEdgePoints();
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof BaseXYZSolid))
+ return false;
+ BaseXYZSolid other = (BaseXYZSolid) o;
+ return super.equals(other);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java
new file mode 100755
index 0000000..4f7c663
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Bounds.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * An interface for accumulating bounds information.
+ * The bounds object is initially empty. Bounding points
+ * are then applied by supplying (x,y,z) tuples. It is also
+ * possible to indicate the following edge cases:
+ * (1) No longitude bound possible
+ * (2) No upper latitude bound possible
+ * (3) No lower latitude bound possible
+ * When any of these have been applied, further application of
+ * points cannot override that decision.
+ *
+ * @lucene.experimental
+ */
+public interface Bounds {
+
+ /** Add a general plane to the bounds description.
+ *@param planetModel is the planet model.
+ *@param plane is the plane.
+ *@param bounds are the membership bounds for points along the arc.
+ */
+ public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds);
+
+ /** Add a horizontal plane to the bounds description.
+ * This method should EITHER use the supplied latitude, OR use the supplied
+ * plane, depending on what is most efficient.
+ *@param planetModel is the planet model.
+ *@param latitude is the latitude.
+ *@param horizontalPlane is the plane.
+ *@param bounds are the constraints on the plane.
+ *@return updated Bounds object.
+ */
+ public Bounds addHorizontalPlane(final PlanetModel planetModel,
+ final double latitude,
+ final Plane horizontalPlane,
+ final Membership... bounds);
+
+ /** Add a vertical plane to the bounds description.
+ * This method should EITHER use the supplied longitude, OR use the supplied
+ * plane, depending on what is most efficient.
+ *@param planetModel is the planet model.
+ *@param longitude is the longitude.
+ *@param verticalPlane is the plane.
+ *@param bounds are the constraints on the plane.
+ *@return updated Bounds object.
+ */
+ public Bounds addVerticalPlane(final PlanetModel planetModel,
+ final double longitude,
+ final Plane verticalPlane,
+ final Membership... bounds);
+
+ /** Add a single point.
+ *@param point is the point.
+ *@return the updated Bounds object.
+ */
+ public Bounds addPoint(final GeoPoint point);
+
+ /** Add an X value.
+ *@param point is the point to take the x value from.
+ *@return the updated object.
+ */
+ public Bounds addXValue(final GeoPoint point);
+
+ /** Add a Y value.
+ *@param point is the point to take the y value from.
+ *@return the updated object.
+ */
+ public Bounds addYValue(final GeoPoint point);
+
+ /** Add a Z value.
+ *@param point is the point to take the z value from.
+ *@return the updated object.
+ */
+ public Bounds addZValue(final GeoPoint point);
+
+ /** Signal that the shape exceeds Math.PI in longitude.
+ *@return the updated Bounds object.
+ */
+ public Bounds isWide();
+
+ /** Signal that there is no longitude bound.
+ *@return the updated Bounds object.
+ */
+ public Bounds noLongitudeBound();
+
+ /** Signal that there is no top latitude bound.
+ *@return the updated Bounds object.
+ */
+ public Bounds noTopLatitudeBound();
+
+ /** Signal that there is no bottom latitude bound.
+ *@return the updated Bounds object.
+ */
+ public Bounds noBottomLatitudeBound();
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
new file mode 100644
index 0000000..8c8658d
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Distance computation styles, supporting various ways of computing
+ * distance to shapes.
+ *
+ * @lucene.experimental
+ */
+public interface DistanceStyle {
+
+ // convenient access to built-in styles:
+
+ /** Arc distance calculator */
+ public static final ArcDistance ARC = ArcDistance.INSTANCE;
+ /** Linear distance calculator */
+ public static final LinearDistance LINEAR = LinearDistance.INSTANCE;
+ /** Linear distance squared calculator */
+ public static final LinearSquaredDistance LINEAR_SQUARED = LinearSquaredDistance.INSTANCE;
+ /** Normal distance calculator */
+ public static final NormalDistance NORMAL = NormalDistance.INSTANCE;
+ /** Normal distance squared calculator */
+ public static final NormalSquaredDistance NORMAL_SQUARED = NormalSquaredDistance.INSTANCE;
+
+ /** Compute the distance from a point to another point.
+ * @param point1 Starting point
+ * @param point2 Final point
+ * @return the distance
+ */
+ public default double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return computeDistance(point1, point2.x, point2.y, point2.z);
+ }
+
+ /** Compute the distance from a point to another point.
+ * @param point1 Starting point
+ * @param x2 Final point x
+ * @param y2 Final point y
+ * @param z2 Final point z
+ * @return the distance
+ */
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2);
+
+ /** Compute the distance from a plane to a point.
+ * @param planetModel The planet model
+ * @param plane The plane
+ * @param point The point
+ * @param bounds are the plane bounds
+ * @return the distance
+ */
+ public default double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point,
+ final Membership... bounds) {
+ return computeDistance(planetModel, plane, point.x, point.y, point.z, bounds);
+ }
+
+ /** Compute the distance from a plane to a point.
+ * @param planetModel The planet model
+ * @param plane The plane
+ * @param x The point x
+ * @param y The point y
+ * @param z The point z
+ * @param bounds are the plane bounds
+ * @return the distance
+ */
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds);
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java
new file mode 100755
index 0000000..5a6db0d
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoArea.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * A GeoArea represents a standard 2-D breakdown of a part of sphere. It can
+ * be bounded in latitude, or bounded in both latitude and longitude, or not
+ * bounded at all. The purpose of the interface is to describe bounding shapes used for
+ * computation of geo hashes.
+ *
+ * @lucene.experimental
+ */
+public interface GeoArea extends Membership {
+ // Since we don't know what each GeoArea's constraints are,
+ // we put the onus on the GeoArea implementation to do the right thing.
+ // This will, of course, rely heavily on methods provided by
+ // the underlying GeoShape class.
+
+ // Relationship values for "getRelationship()"
+
+ /** The referenced shape CONTAINS this area */
+ public static final int CONTAINS = 0;
+ /** The referenced shape IS WITHIN this area */
+ public static final int WITHIN = 1;
+ /** The referenced shape OVERLAPS this area */
+ public static final int OVERLAPS = 2;
+ /** The referenced shape has no relation to this area */
+ public static final int DISJOINT = 3;
+
+ /**
+ * Find the spatial relationship between a shape and the current geo area.
+ * Note: return value is how the GeoShape relates to the GeoArea, not the
+ * other way around. For example, if this GeoArea is entirely within the
+ * shape, then CONTAINS should be returned. If the shape is entirely enclosed
+ * by this GeoArea, then WITHIN should be returned.
+ *
+ * It is permissible to return OVERLAPS instead of WITHIN if the shape
+ * intersects with the area at even a single point. So, a circle inscribed in
+ * a rectangle could return either OVERLAPS or WITHIN, depending on
+ * implementation. It is not permissible to return CONTAINS or DISJOINT
+ * in this circumstance, however.
+ *
+ * Similarly, it is permissible to return OVERLAPS instead of CONTAINS
+ * under conditions where the shape consists of multiple independent overlapping
+ * subshapes, and the area overlaps one of the subshapes. It is not permissible
+ * to return WITHIN or DISJOINT in this circumstance, however.
+ *
+ * @param shape is the shape to consider.
+ * @return the relationship, from the perspective of the shape.
+ */
+ public int getRelationship(GeoShape shape);
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java
new file mode 100755
index 0000000..0c3caa9
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoAreaFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Factory for {@link GeoArea}.
+ *
+ * @lucene.experimental
+ */
+public class GeoAreaFactory {
+ private GeoAreaFactory() {
+ }
+
+ /**
+ * Create a GeoArea of the right kind given the specified bounds.
+ * @param planetModel is the planet model
+ * @param topLat is the top latitude
+ * @param bottomLat is the bottom latitude
+ * @param leftLon is the left longitude
+ * @param rightLon is the right longitude
+ * @return a GeoArea corresponding to what was specified.
+ */
+ public static GeoArea makeGeoArea(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, final double rightLon) {
+ return GeoBBoxFactory.makeGeoBBox(planetModel, topLat, bottomLat, leftLon, rightLon);
+ }
+
+ /**
+ * Create a GeoArea of the right kind given (x,y,z) bounds.
+ * @param planetModel is the planet model
+ * @param minX is the min X boundary
+ * @param maxX is the max X boundary
+ * @param minY is the min Y boundary
+ * @param maxY is the max Y boundary
+ * @param minZ is the min Z boundary
+ * @param maxZ is the max Z boundary
+ */
+ public static GeoArea makeGeoArea(final PlanetModel planetModel, final double minX, final double maxX, final double minY, final double maxY, final double minZ, final double maxZ) {
+ return XYZSolidFactory.makeXYZSolid(planetModel, minX, maxX, minY, maxY, minZ, maxZ);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
new file mode 100755
index 0000000..0ae2425
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBox.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * All bounding box shapes have this interface in common.
+ * This describes methods that bounding boxes have above and beyond
+ * GeoMembershipShape's.
+ *
+ * @lucene.experimental
+ */
+public interface GeoBBox extends GeoMembershipShape, GeoSizeable, GeoArea {
+
+ /**
+ * Expand box by specified angle.
+ *
+ * @param angle is the angle amount to expand the GeoBBox by.
+ * @return a new GeoBBox.
+ */
+ public GeoBBox expand(double angle);
+
+}
[30/50] [abbrv] lucene-solr git commit: LUCENE-7075: convert test
class to use points
Posted by no...@apache.org.
LUCENE-7075: convert test class to use points
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/862bf7b5
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/862bf7b5
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/862bf7b5
Branch: refs/heads/apiv2
Commit: 862bf7b5ac340729869d8d0bec4c455142ad4b50
Parents: 5ea6ee7
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 8 07:36:09 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 8 07:36:34 2016 -0500
----------------------------------------------------------------------
.../index/BaseStoredFieldsFormatTestCase.java | 53 ++++++++------------
1 file changed, 22 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/862bf7b5/lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java
index 840fdf5..c58d56a 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/BaseStoredFieldsFormatTestCase.java
@@ -33,20 +33,15 @@ import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.StoredFieldsFormat;
import org.apache.lucene.codecs.simpletext.SimpleTextCodec;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.LegacyDoubleField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType.LegacyNumericType;
+import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.LegacyFloatField;
-import org.apache.lucene.document.LegacyIntField;
-import org.apache.lucene.document.LegacyLongField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
@@ -244,51 +239,44 @@ public abstract class BaseStoredFieldsFormatTestCase extends BaseIndexFileFormat
RandomIndexWriter w = new RandomIndexWriter(random(), dir);
final int numDocs = atLeast(500);
final Number[] answers = new Number[numDocs];
- final LegacyNumericType[] typeAnswers = new LegacyNumericType[numDocs];
+ final Class<?>[] typeAnswers = new Class<?>[numDocs];
for(int id=0;id<numDocs;id++) {
Document doc = new Document();
final Field nf;
- final Field sf;
final Number answer;
- final LegacyNumericType typeAnswer;
+ final Class<?> typeAnswer;
if (random().nextBoolean()) {
// float/double
if (random().nextBoolean()) {
final float f = random().nextFloat();
answer = Float.valueOf(f);
- nf = new LegacyFloatField("nf", f, Field.Store.NO);
- sf = new StoredField("nf", f);
- typeAnswer = LegacyNumericType.FLOAT;
+ nf = new StoredField("nf", f);
+ typeAnswer = Float.class;
} else {
final double d = random().nextDouble();
answer = Double.valueOf(d);
- nf = new LegacyDoubleField("nf", d, Field.Store.NO);
- sf = new StoredField("nf", d);
- typeAnswer = LegacyNumericType.DOUBLE;
+ nf = new StoredField("nf", d);
+ typeAnswer = Double.class;
}
} else {
// int/long
if (random().nextBoolean()) {
final int i = random().nextInt();
answer = Integer.valueOf(i);
- nf = new LegacyIntField("nf", i, Field.Store.NO);
- sf = new StoredField("nf", i);
- typeAnswer = LegacyNumericType.INT;
+ nf = new StoredField("nf", i);
+ typeAnswer = Integer.class;
} else {
final long l = random().nextLong();
answer = Long.valueOf(l);
- nf = new LegacyLongField("nf", l, Field.Store.NO);
- sf = new StoredField("nf", l);
- typeAnswer = LegacyNumericType.LONG;
+ nf = new StoredField("nf", l);
+ typeAnswer = Long.class;
}
}
doc.add(nf);
- doc.add(sf);
answers[id] = answer;
typeAnswers[id] = typeAnswer;
- FieldType ft = new FieldType(LegacyIntField.TYPE_STORED);
- ft.setNumericPrecisionStep(Integer.MAX_VALUE);
- doc.add(new LegacyIntField("id", id, ft));
+ doc.add(new StoredField("id", id));
+ doc.add(new IntPoint("id", id));
doc.add(new NumericDocValuesField("id", id));
w.addDocument(doc);
}
@@ -348,10 +336,10 @@ public abstract class BaseStoredFieldsFormatTestCase extends BaseIndexFileFormat
List<Field> fields = Arrays.asList(
new Field("bytes", bytes, ft),
new Field("string", string, ft),
- new LegacyLongField("long", l, Store.YES),
- new LegacyIntField("int", i, Store.YES),
- new LegacyFloatField("float", f, Store.YES),
- new LegacyDoubleField("double", d, Store.YES)
+ new StoredField("long", l),
+ new StoredField("int", i),
+ new StoredField("float", f),
+ new StoredField("double", d)
);
for (int k = 0; k < 100; ++k) {
@@ -519,11 +507,14 @@ public abstract class BaseStoredFieldsFormatTestCase extends BaseIndexFileFormat
final FieldType type = new FieldType(StringField.TYPE_STORED);
type.setIndexOptions(IndexOptions.NONE);
type.freeze();
- LegacyIntField id = new LegacyIntField("id", 0, Store.YES);
+ IntPoint id = new IntPoint("id", 0);
+ StoredField idStored = new StoredField("id", 0);
for (int i = 0; i < data.length; ++i) {
Document doc = new Document();
doc.add(id);
+ doc.add(idStored);
id.setIntValue(i);
+ idStored.setIntValue(i);
for (int j = 0; j < data[i].length; ++j) {
Field f = new Field("bytes" + j, data[i][j], type);
doc.add(f);
@@ -546,7 +537,7 @@ public abstract class BaseStoredFieldsFormatTestCase extends BaseIndexFileFormat
for (int i = 0; i < 10; ++i) {
final int min = random().nextInt(data.length);
final int max = min + random().nextInt(20);
- iw.deleteDocuments(LegacyNumericRangeQuery.newIntRange("id", min, max, true, false));
+ iw.deleteDocuments(IntPoint.newRangeQuery("id", min, max-1));
}
iw.forceMerge(2); // force merges with deletions
[50/50] [abbrv] lucene-solr git commit: Merge remote-tracking branch
'remotes/origin/master' into apiv2
Posted by no...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into apiv2
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ec4889a2
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ec4889a2
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ec4889a2
Branch: refs/heads/apiv2
Commit: ec4889a2b326df4ceb01ecb1ee096d550141fb8c
Parents: 7815408
Author: Noble Paul <no...@apache.org>
Authored: Wed Mar 9 21:26:24 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Wed Mar 9 21:26:24 2016 +0530
----------------------------------------------------------------------
.../handler/admin/CollectionHandlerApi.java | 4 +--
.../solr/handler/admin/CollectionsHandler.java | 26 +++++++++++++-------
.../solr/handler/admin/TestCollectionAPIs.java | 5 ++--
3 files changed, 22 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ec4889a2/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
index fb93d4f..78e5622 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionHandlerApi.java
@@ -203,12 +203,12 @@ public class CollectionHandlerApi extends BaseHandlerApiSupport {
@Override
public void command(SolrQueryRequest req, SolrQueryResponse rsp, CommandOperation c, CollectionHandlerApi handler) throws Exception {
- handler.handler.invokeAction(req,rsp,target);
+ handler.handler.invokeAction(req, rsp, handler.handler.coreContainer, target.action,target);
}
@Override
public void GET(SolrQueryRequest req, SolrQueryResponse rsp, CollectionHandlerApi handler) throws Exception {
- handler.handler.invokeAction(req, rsp, target);
+ handler.handler.invokeAction(req, rsp, handler.handler.coreContainer, target.action,target);
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ec4889a2/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index b12e1fb..c8d2c27 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@ -56,7 +56,6 @@ import static org.apache.solr.common.util.StrUtils.formatString;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -70,13 +69,13 @@ import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.solr.api.Api;
import org.apache.solr.client.solrj.SolrResponse;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.request.CoreAdminRequest.RequestSyncShard;
import org.apache.solr.client.solrj.response.RequestStatusState;
import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
-import org.apache.solr.cloud.DistributedMap;
import org.apache.solr.cloud.Overseer;
import org.apache.solr.cloud.OverseerCollectionMessageHandler;
import org.apache.solr.cloud.OverseerSolrResponse;
@@ -100,6 +99,7 @@ import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionAdminParams;
+import org.apache.solr.common.params.CollectionParams;
import org.apache.solr.common.params.CollectionParams.CollectionAction;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.CoreAdminParams;
@@ -111,7 +111,6 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.CloudConfig;
import org.apache.solr.core.CoreContainer;
-import org.apache.solr.handler.BlobHandler;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.component.ShardHandler;
import org.apache.solr.request.SolrQueryRequest;
@@ -189,20 +188,21 @@ public class CollectionsHandler extends RequestHandlerBase {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unknown action: " + a);
}
CollectionOperation operation = CollectionOperation.get(action);
- log.info("Invoked Collection Action :{} with params {} ", action.toLower(), req.getParamString());
- invokeAction(req, rsp, operation);
+ log.info("Invoked Collection Action :{} with params {} and sendToOCPQueue={}", action.toLower(), req.getParamString(), operation.sendToOCPQueue);
+
+ invokeAction(req, rsp, cores, action, operation);
} else {
throw new SolrException(ErrorCode.BAD_REQUEST, "action is a required param");
}
rsp.setHttpCaching(false);
}
- void invokeAction(SolrQueryRequest req, SolrQueryResponse rsp, CollectionOperation operation) throws Exception {
+ void invokeAction(SolrQueryRequest req, SolrQueryResponse rsp, CoreContainer cores, CollectionAction action, CollectionOperation operation) throws Exception {
if (!coreContainer.isZooKeeperAware()) {
throw new SolrException(BAD_REQUEST,
"Invalid request. collections can be accessed only in SolrCloud mode");
}
-
+ SolrResponse response = null;
Map<String, Object> props = operation.call(req, rsp, this);
String asyncId = req.getParams().get(ASYNC);
if (props != null) {
@@ -211,8 +211,16 @@ public class CollectionsHandler extends RequestHandlerBase {
}
props.put(QUEUE_OPERATION, operation.action.toLower());
ZkNodeProps zkProps = new ZkNodeProps(props);
- if (operation.sendToOCPQueue) handleResponse(operation.action.toLower(), zkProps, rsp, operation.timeOut);
- else Overseer.getInQueue(coreContainer.getZkController().getZkClient()).offer(Utils.toJSON(props));
+ if (operation.sendToOCPQueue) {
+ response = handleResponse(operation.action.toLower(), zkProps, rsp, operation.timeOut);
+ }
+ else Overseer.getStateUpdateQueue(coreContainer.getZkController().getZkClient()).offer(Utils.toJSON(props));
+ final String collectionName = zkProps.getStr(NAME);
+ if (action.equals(CollectionAction.CREATE) && asyncId == null) {
+ if (rsp.getException() == null) {
+ waitForActiveCollection(collectionName, zkProps, cores, response);
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ec4889a2/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
index 3d0c625..919e5b9 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/TestCollectionAPIs.java
@@ -28,6 +28,7 @@ import java.util.Map;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.params.CollectionParams;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.util.Pair;
import org.apache.solr.common.util.Utils;
@@ -99,7 +100,8 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 {
MockCollectionsHandler() { }
@Override
- protected void invokeAction(SolrQueryRequest req, SolrQueryResponse rsp, CollectionOperation operation) throws Exception {
+ void invokeAction(SolrQueryRequest req, SolrQueryResponse rsp, CoreContainer cores, CollectionParams.CollectionAction action,
+ CollectionOperation operation) throws Exception {
Map<String, Object> result = operation.call(req, rsp, this);
if (result != null) {
result.put(QUEUE_OPERATION, operation.action.toLower());
@@ -108,5 +110,4 @@ public class TestCollectionAPIs extends SolrTestCaseJ4 {
}
}
-
}
[10/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYdZSolid.java
new file mode 100644
index 0000000..d824f26
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYdZSolid.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X and Z.
+ * This figure, in fact, represents either zero, one, or two points, so the
+ * actual data stored is minimal.
+ *
+ * @lucene.internal
+ */
+public class dXYdZSolid extends BaseXYZSolid {
+
+ /** The points in this figure on the planet surface; also doubles for edge points */
+ protected final GeoPoint[] surfacePoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param X is the X value.
+ *@param minY is the minimum Y value.
+ *@param maxY is the maximum Y value.
+ *@param Z is the Z value.
+ */
+ public dXYdZSolid(final PlanetModel planetModel,
+ final double X,
+ final double minY,
+ final double maxY,
+ final double Z) {
+ super(planetModel);
+ // Argument checking
+ if (maxY - minY < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Y values in wrong order or identical");
+
+ // Build the planes and intersect them.
+ final Plane xPlane = new Plane(xUnitVector,-X);
+ final Plane zPlane = new Plane(zUnitVector,-Z);
+ final SidedPlane minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
+ final SidedPlane maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
+ surfacePoints = xPlane.findIntersections(planetModel,zPlane,minYPlane,maxYPlane);
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return surfacePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (final GeoPoint p : surfacePoints) {
+ if (p.isIdentical(x,y,z))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof dXYdZSolid))
+ return false;
+ dXYdZSolid other = (dXYdZSolid) o;
+ if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
+ return false;
+ }
+ for (int i = 0; i < surfacePoints.length; i++) {
+ if (!surfacePoints[i].equals(other.surfacePoints[i]))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ for (final GeoPoint p : surfacePoints) {
+ result = 31 * result + p.hashCode();
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ for (final GeoPoint p : surfacePoints) {
+ sb.append(" ").append(p).append(" ");
+ }
+ return "dXYdZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYZSolid.java
new file mode 100644
index 0000000..b9942b5
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYZSolid.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X and Y.
+ * This figure, in fact, represents either zero, one, or two points, so the
+ * actual data stored is minimal.
+ *
+ * @lucene.internal
+ */
+public class dXdYZSolid extends BaseXYZSolid {
+
+ /** The points in this figure on the planet surface; also doubles for edge points */
+ protected final GeoPoint[] surfacePoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param X is the X value.
+ *@param Y is the Y value.
+ *@param minZ is the minimum Z value.
+ *@param maxZ is the maximum Z value.
+ */
+ public dXdYZSolid(final PlanetModel planetModel,
+ final double X,
+ final double Y,
+ final double minZ,
+ final double maxZ) {
+ super(planetModel);
+ // Argument checking
+ if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Z values in wrong order or identical");
+
+ // Build the planes and intersect them.
+ final Plane xPlane = new Plane(xUnitVector,-X);
+ final Plane yPlane = new Plane(yUnitVector,-Y);
+ final SidedPlane minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
+ final SidedPlane maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
+ surfacePoints = xPlane.findIntersections(planetModel,yPlane,minZPlane,maxZPlane);
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return surfacePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (final GeoPoint p : surfacePoints) {
+ if (p.isIdentical(x,y,z))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof dXdYZSolid))
+ return false;
+ dXdYZSolid other = (dXdYZSolid) o;
+ if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
+ return false;
+ }
+ for (int i = 0; i < surfacePoints.length; i++) {
+ if (!surfacePoints[i].equals(other.surfacePoints[i]))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ for (final GeoPoint p : surfacePoints) {
+ result = 31 * result + p.hashCode();
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ for (final GeoPoint p : surfacePoints) {
+ sb.append(" ").append(p).append(" ");
+ }
+ return "dXdYZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYdZSolid.java
new file mode 100644
index 0000000..66dcab8
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXdYdZSolid.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in all dimensions
+ *
+ * @lucene.internal
+ */
+public class dXdYdZSolid extends BaseXYZSolid {
+
+ /** On surface? */
+ protected final boolean isOnSurface;
+ /** The point */
+ protected final GeoPoint thePoint;
+
+ /** These are the edge points of the shape, which are defined to be at least one point on
+ * each surface area boundary. In the case of a solid, this includes points which represent
+ * the intersection of XYZ bounding planes and the planet, as well as points representing
+ * the intersection of single bounding planes with the planet itself.
+ */
+ protected final GeoPoint[] edgePoints;
+
+ /** Empty array of {@link GeoPoint}. */
+ protected static final GeoPoint[] nullPoints = new GeoPoint[0];
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param X is the X value.
+ *@param Y is the Y value.
+ *@param Z is the Z value.
+ */
+ public dXdYdZSolid(final PlanetModel planetModel,
+ final double X,
+ final double Y,
+ final double Z) {
+ super(planetModel);
+ isOnSurface = planetModel.pointOnSurface(X,Y,Z);
+ if (isOnSurface) {
+ thePoint = new GeoPoint(X,Y,Z);
+ edgePoints = new GeoPoint[]{thePoint};
+ } else {
+ thePoint = null;
+ edgePoints = nullPoints;
+ }
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ if (!isOnSurface) {
+ return false;
+ }
+ return thePoint.isIdentical(x,y,z);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ if (!isOnSurface) {
+ return DISJOINT;
+ }
+
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some shape points inside area");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ //System.err.println(" some area points inside shape");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside area entirely");
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains area entirely");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof dXdYdZSolid))
+ return false;
+ dXdYdZSolid other = (dXdYdZSolid) o;
+ if (!super.equals(other) ||
+ other.isOnSurface != isOnSurface) {
+ return false;
+ }
+ if (isOnSurface) {
+ return other.thePoint.equals(thePoint);
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (isOnSurface?1:0);
+ if (isOnSurface) {
+ result = 31 * result + thePoint.hashCode();
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "dXdYdZSolid: {planetmodel="+planetModel+", isOnSurface="+isOnSurface+", thePoint="+thePoint+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/package-info.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/package-info.java
new file mode 100644
index 0000000..446365c
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Shapes implemented using 3D planar geometry. This package has no dependencies aside from Java.
+ * This code was contributed under the name "Geo3D".
+ */
+package org.apache.lucene.spatial3d.geom;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/package-info.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/package-info.java
new file mode 100644
index 0000000..032d26f
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Lucene field & query support for the spatial geometry implemented in {@link org.apache.lucene.spatial3d.geom}.
+ */
+package org.apache.lucene.spatial3d;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/overview.html
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/overview.html b/lucene/spatial3d/src/java/overview.html
index 152d06e..293cc65a 100644
--- a/lucene/spatial3d/src/java/overview.html
+++ b/lucene/spatial3d/src/java/overview.html
@@ -23,7 +23,8 @@
<h1>The Spatial3D Module for Apache Lucene</h1>
<p>
- APIs for planar spatial3d math.
+ APIs for planar spatial3d math. It is mostly comprised of computational geometry code in the
+ "org.apache.lucene.spatial3d.geom" package (AKA "Geo3D").
</p>
</body>
</html>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoBBoxTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoBBoxTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoBBoxTest.java
deleted file mode 100755
index b76134e..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoBBoxTest.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class GeoBBoxTest {
-
- protected final double DEGREES_TO_RADIANS = Math.PI / 180.0;
-
- @Test
- public void testBBoxDegenerate() {
- GeoBBox box;
- GeoConvexPolygon cp;
- int relationship;
- List<GeoPoint> points = new ArrayList<GeoPoint>();
- points.add(new GeoPoint(PlanetModel.SPHERE, 24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
- points.add(new GeoPoint(PlanetModel.SPHERE, -11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
- points.add(new GeoPoint(PlanetModel.SPHERE, -49 * DEGREES_TO_RADIANS, -176 * DEGREES_TO_RADIANS));
- GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -64 * DEGREES_TO_RADIANS, -64 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, 180 * DEGREES_TO_RADIANS);
- relationship = box.getRelationship(shape);
- assertEquals(GeoArea.CONTAINS, relationship);
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -61.85 * DEGREES_TO_RADIANS, -67.5 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, -168.75 * DEGREES_TO_RADIANS);
- //System.out.println("Shape = " + shape + " Rect = " + box);
- relationship = box.getRelationship(shape);
- assertEquals(GeoArea.CONTAINS, relationship);
- }
-
- @Test
- public void testBBoxPointWithin() {
- GeoBBox box;
- GeoPoint gp;
-
- // Standard normal Rect box, not crossing dateline
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 0.0);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.0);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.1);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.1);
- assertFalse(box.isWithin(gp));
- assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.ARC,gp),1e-2);
- assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
- assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
-
- // Standard normal Rect box, crossing dateline
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 1.0, -Math.PI + 1.0);
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
- assertFalse(box.isWithin(gp));
-
- // Latitude zone rectangle
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI, Math.PI);
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
- assertTrue(box.isWithin(gp));
-
- // World
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, Math.PI);
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
- assertTrue(box.isWithin(gp));
-
- }
-
- @Test
- public void testBBoxExpand() {
- GeoBBox box;
- GeoPoint gp;
- // Standard normal Rect box, not crossing dateline
- box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
- box = box.expand(0.1);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.0);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.15, 0.0);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, 0.0);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.15, 0.0);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.05);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.15);
- assertFalse(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.05);
- assertTrue(box.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.15);
- assertFalse(box.isWithin(gp));
- }
-
- @Test
- public void testBBoxBounds() {
- GeoBBox c;
- LatLonBounds b;
- XYZBounds xyzb;
- GeoArea solid;
- GeoPoint point;
- int relationship;
-
- c= GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.7570958596622309, -0.7458670829264561, -0.9566079379002148, 1.4802570961901191);
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,0.10922258701604912,0.1248184603754517,-0.8172414690802067,0.9959041483215542,-0.6136586624726926,0.6821740363641521);
- point = new GeoPoint(PlanetModel.SPHERE, 0.3719987557178081, 1.4529582778845198);
- assertTrue(c.isWithin(point));
- assertTrue(solid.isWithin(point));
- relationship = solid.getRelationship(c);
- assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.CONTAINS || relationship == GeoArea.WITHIN);
-
- c= GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.006607096847842122, -0.002828135860810422, -0.0012934461873348349, 0.006727418645092394);
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,0.9999995988328008,1.0000000002328306,-0.0012934708508166816,0.006727393021214471,-0.002828157275369464,0.006607074060760007);
- point = new GeoPoint(PlanetModel.SPHERE, -5.236470872437899E-4, 3.992578692654256E-4);
- assertTrue(c.isWithin(point));
- assertTrue(solid.isWithin(point));
- relationship = solid.getRelationship(c);
- assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.CONTAINS || relationship == GeoArea.WITHIN);
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.25, -Math.PI * 0.25, -1.0, 1.0);
- b = new LatLonBounds();
- c.getBounds(b);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
- assertEquals(1.0, b.getRightLongitude(), 0.000001);
- assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
- assertEquals(Math.PI * 0.25, b.getMaxLatitude(), 0.000001);
- assertEquals(0.382051, xyzb.getMinimumX(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
- assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
- assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
- assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
- assertEquals(0.707107, xyzb.getMaximumZ(), 0.000001);
-
- GeoArea area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX() - 2.0 * Vector.MINIMUM_RESOLUTION,
- xyzb.getMaximumX() + 2.0 * Vector.MINIMUM_RESOLUTION,
- xyzb.getMinimumY() - 2.0 * Vector.MINIMUM_RESOLUTION,
- xyzb.getMaximumY() + 2.0 * Vector.MINIMUM_RESOLUTION,
- xyzb.getMinimumZ() - 2.0 * Vector.MINIMUM_RESOLUTION,
- xyzb.getMaximumZ() + 2.0 * Vector.MINIMUM_RESOLUTION);
- assertEquals(GeoArea.WITHIN, area.getRelationship(c));
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
- b = new LatLonBounds();
- c.getBounds(b);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
- assertEquals(1.0, b.getRightLongitude(), 0.000001);
- assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
- assertEquals(0.0, b.getMaxLatitude(), 0.000001);
- assertEquals(0.382051, xyzb.getMinimumX(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
- assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
- assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
- assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
- assertEquals(0.0, xyzb.getMaximumZ(), 0.000001);
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, 1.0, -1.0);
-
- b = new LatLonBounds();
- c.getBounds(b);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- assertTrue(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- //assertEquals(1.0,b.getLeftLongitude(),0.000001);
- //assertEquals(-1.0,b.getRightLongitude(),0.000001);
- assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
- assertEquals(0.0, b.getMaxLatitude(), 0.000001);
- assertEquals(-1.0, xyzb.getMinimumX(), 0.000001);
- assertEquals(0.540303, xyzb.getMaximumX(), 0.000001);
- assertEquals(-1.0, xyzb.getMinimumY(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumY(), 0.000001);
- assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
- assertEquals(0.0, xyzb.getMaximumZ(), 0.000001);
-
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -1.0, 1.0);
-
- b = new LatLonBounds();
- c.getBounds(b);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- //assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
- //assertEquals(1.0, b.getRightLongitude(), 0.000001);
- assertEquals(0.0, xyzb.getMinimumX(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
- assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
- assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
- assertEquals(-1.0, xyzb.getMinimumZ(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumZ(), 0.000001);
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 1.0, -1.0);
-
- b = new LatLonBounds();
- c.getBounds(b);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- //assertEquals(1.0,b.getLeftLongitude(),0.000001);
- //assertEquals(-1.0,b.getRightLongitude(),0.000001);
- assertEquals(-1.0, xyzb.getMinimumX(), 0.000001);
- assertEquals(0.540303, xyzb.getMaximumX(), 0.000001);
- assertEquals(-1.0, xyzb.getMinimumY(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumY(), 0.000001);
- assertEquals(-1.0, xyzb.getMinimumZ(), 0.000001);
- assertEquals(1.0, xyzb.getMaximumZ(), 0.000001);
-
- // Check wide variants of rectangle and longitude slice
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI + 0.1, Math.PI - 0.1);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
- //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
- assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
- assertEquals(0.0, b.getMaxLatitude(), 0.000001);
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 0.1, -Math.PI + 0.1);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
- assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
- assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
- assertEquals(0.0, b.getMaxLatitude(), 0.000001);
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI + 0.1, Math.PI - 0.1);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
- //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
-
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, Math.PI - 0.1, -Math.PI + 0.1);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- //assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
- //assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
-
- // Check latitude zone
- c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 1.0, -1.0, -Math.PI, Math.PI);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-1.0, b.getMinLatitude(), 0.000001);
- assertEquals(1.0, b.getMaxLatitude(), 0.000001);
-
- // Now, combine a few things to test the bounds object
- GeoBBox c1;
- GeoBBox c2;
-
- c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
- c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
-
- b = new LatLonBounds();
- c1.getBounds(b);
- c2.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
-
- c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
- c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI * 0.5);
-
- b = new LatLonBounds();
- c1.getBounds(b);
- c2.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- //assertEquals(-Math.PI,b.getLeftLongitude(),0.000001);
- //assertEquals(Math.PI*0.5,b.getRightLongitude(),0.000001);
-
- c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI * 0.5, 0.0);
- c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
-
- b = new LatLonBounds();
- c1.getBounds(b);
- c2.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- //assertEquals(-Math.PI * 0.5,b.getLeftLongitude(),0.000001);
- //assertEquals(Math.PI,b.getRightLongitude(),0.000001);
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoCircleTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoCircleTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoCircleTest.java
deleted file mode 100755
index aa5c2e3..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoCircleTest.java
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.lucene.util.LuceneTestCase;
-
-public class GeoCircleTest extends LuceneTestCase {
-
- @Test
- public void testCircleDistance() {
- GeoCircle c;
- GeoPoint gp;
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.ARC,gp), 0.0);
- assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
- assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertEquals(0.0, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
- assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
- assertEquals(0.05, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- assertEquals(0.049995, c.computeDistance(DistanceStyle.LINEAR,gp), 0.000001);
- assertEquals(0.049979, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
- }
-
- @Test
- public void testCircleFullWorld() {
- GeoCircle c;
- GeoPoint gp;
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, Math.PI);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertTrue(c.isWithin(gp));
- LatLonBounds b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- }
-
- @Test
- public void testCirclePointWithin() {
- GeoCircle c;
- GeoPoint gp;
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertFalse(c.isWithin(gp));
- assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
- assertEquals(0.12,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),0.01);
- assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),0.01);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertFalse(c.isWithin(gp));
- }
-
- @Test
- public void testCircleBounds() {
- GeoCircle c;
- LatLonBounds b;
- XYZBounds xyzb;
- GeoArea area;
- GeoPoint p1;
- GeoPoint p2;
- int relationship;
-
- // ...
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, -0.005931145568901605, -0.001942031539653079, 1.2991918568260272E-4);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, 1.001098377143621, 1.001100011578687, -0.00207467080358696, -0.0018136665346280983, -0.006067808248760161, -0.005807683665759485);
- p1 = new GeoPoint(PlanetModel.WGS84, -0.00591253844632244, -0.0020069187259065093);
- p2 = new GeoPoint(1.001099185736782, -0.0020091272069679327, -0.005919118245803968);
- assertTrue(c.isWithin(p1));
- assertTrue(area.isWithin(p1));
- relationship = area.getRelationship(c);
- assertTrue(relationship != GeoArea.DISJOINT);
-
- // Twelfth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.00824379317765984,-0.0011677469001838581,0.0011530035396910402);
- p1 = new GeoPoint(PlanetModel.WGS84,-0.006505092992723671,0.007654282718327381);
- p2 = new GeoPoint(1.0010681673665647,0.007662608264336381,-0.006512324005914593);
- assertTrue(!c.isWithin(p1));
- assertTrue(!c.isWithin(p2));
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- relationship = area.getRelationship(c);
- assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.WITHIN);
- // Point is actually outside the bounds, and outside the shape
- assertTrue(!area.isWithin(p1));
- // Approximate point the same
- assertTrue(!area.isWithin(p2));
-
- // Eleventh BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-0.004431288600558495,-0.003687846671278374,1.704543429364245E-8);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println(area);
- relationship = area.getRelationship(c);
- assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
-
- // Tenth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.0018829770647349636,-0.001969499061382591,1.3045439293158305E-5);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println(area);
- relationship = area.getRelationship(c);
- assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
-
- // Ninth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-4.211990380885122E-5,-0.0022958453508173044,1.4318475623498535E-5);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println(area);
- relationship = area.getRelationship(c);
- assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
-
- // Eighth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,0.005321278689117842,-0.00216937368755372,1.5306034422500785E-4);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println(area);
- relationship = area.getRelationship(c);
- assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
-
- // Seventh BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-0.0021627146783861745, -0.0017298167021592304,2.0818312293195752E-4);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println(area);
- relationship = area.getRelationship(c);
- assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
-
- // Sixth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.006450320645814321,0.004660694205115142,0.00489710732634323);
- //xyzb = new XYZBounds();
- //c.getBounds(xyzb);
- //System.err.println("xmin="+xyzb.getMinimumX()+", xmax="+xyzb.getMaximumX()+",ymin="+xyzb.getMinimumY()+", ymax="+xyzb.getMaximumY()+",zmin="+xyzb.getMinimumZ()+", zmax="+xyzb.getMaximumZ());
- //xmin=1.0010356621420726, xmax=1.0011141249179447,ymin=-2.5326643901354566E-4, ymax=0.009584741915757169,zmin=-0.011359874956269283, zmax=-0.0015549504447452225
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,1.0010822580620098,1.0010945779732867,0.007079167343247293,0.007541006774427837,-0.0021855011220022575,-0.001896122718181518);
- assertTrue(GeoArea.CONTAINS != area.getRelationship(c));
- /*
- p1 = new GeoPoint(1.0010893045436076,0.007380935180644008,-0.002140671370616495);
- // This has a different bounding box, so we can't use it.
- //p2 = new GeoPoint(PlanetModel.WGS84,-0.002164069780096702, 0.007505617500830066);
- p2 = new GeoPoint(PlanetModel.WGS84,p1.getLatitude(),p1.getLongitude());
- assertTrue(PlanetModel.WGS84.pointOnSurface(p2));
- assertTrue(!c.isWithin(p2));
- assertTrue(!area.isWithin(p2));
- assertTrue(!c.isWithin(p1));
- assertTrue(PlanetModel.WGS84.pointOnSurface(p1)); // This fails
- assertTrue(!area.isWithin(p1)); // This fails
- */
-
- // Fifth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.004282454525970269, -1.6739831367422277E-4, 1.959639723134033E-6);
- assertTrue(c.isWithin(c.getEdgePoints()[0]));
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- assertTrue(GeoArea.WITHIN == area.getRelationship(c) || GeoArea.OVERLAPS == area.getRelationship(c));
-
- // Fourth BKD discovered failure
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.0048795517261255, 0.004053904306995974, 5.93699764258874E-6);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- assertTrue(GeoArea.WITHIN == area.getRelationship(c) || GeoArea.OVERLAPS == area.getRelationship(c));
-
- // Yet another test case from BKD
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, 0.006229478708446979, 0.005570196723795424, 3.840276763694387E-5);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- p1 = new GeoPoint(PlanetModel.WGS84, 0.006224927111830945, 0.005597367237251763);
- p2 = new GeoPoint(1.0010836083810235, 0.005603490759433942, 0.006231850560862502);
- assertTrue(PlanetModel.WGS84.pointOnSurface(p1));
- //assertTrue(PlanetModel.WGS84.pointOnSurface(p2));
- assertTrue(c.isWithin(p1));
- assertTrue(c.isWithin(p2));
- assertTrue(area.isWithin(p1));
- assertTrue(area.isWithin(p2));
-
- // Another test case from BKD
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.005955031040627789, -0.0029274772647399153, 1.601488279374338E-5);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
-
- relationship = area.getRelationship(c);
- assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
-
- // Test case from BKD
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.765816119338, 0.991848766844, 0.8153163226330487);
- p1 = new GeoPoint(0.7692262265236023, -0.055089298115534646, -0.6365973465711254);
- assertTrue(c.isWithin(p1));
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- assertTrue(p1.x >= xyzb.getMinimumX() && p1.x <= xyzb.getMaximumX());
- assertTrue(p1.y >= xyzb.getMinimumY() && p1.y <= xyzb.getMaximumY());
- assertTrue(p1.z >= xyzb.getMinimumZ() && p1.z <= xyzb.getMaximumZ());
-
- // Vertical circle cases
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
- assertEquals(-0.4, b.getRightLongitude(), 0.000001);
- assertEquals(-0.1, b.getMinLatitude(), 0.000001);
- assertEquals(0.1, b.getMaxLatitude(), 0.000001);
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.5, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.4, b.getLeftLongitude(), 0.000001);
- assertEquals(0.6, b.getRightLongitude(), 0.000001);
- assertEquals(-0.1, b.getMinLatitude(), 0.000001);
- assertEquals(0.1, b.getMaxLatitude(), 0.000001);
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-0.1, b.getLeftLongitude(), 0.000001);
- assertEquals(0.1, b.getRightLongitude(), 0.000001);
- assertEquals(-0.1, b.getMinLatitude(), 0.000001);
- assertEquals(0.1, b.getMaxLatitude(), 0.000001);
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
- assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
- assertEquals(-0.1, b.getMinLatitude(), 0.000001);
- assertEquals(0.1, b.getMaxLatitude(), 0.000001);
- // Horizontal circle cases
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertTrue(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(Math.PI * 0.5 - 0.1, b.getMinLatitude(), 0.000001);
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertTrue(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertTrue(b.checkNoBottomLatitudeBound());
- assertEquals(-Math.PI * 0.5 + 0.1, b.getMaxLatitude(), 0.000001);
-
- // Now do a somewhat tilted plane, facing different directions.
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, 0.0, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(-0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(0.1, b.getRightLongitude(), 0.00001);
-
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.00001);
-
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI * 0.5, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(Math.PI * 0.5 - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(Math.PI * 0.5 + 0.1, b.getRightLongitude(), 0.00001);
-
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -Math.PI * 0.5, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(-Math.PI * 0.5 - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(-Math.PI * 0.5 + 0.1, b.getRightLongitude(), 0.00001);
-
- // Slightly tilted, PI/4 direction.
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI * 0.25, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
-
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -Math.PI * 0.25, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(-Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(-Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
-
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.01, Math.PI * 0.25, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.09, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.11, b.getMinLatitude(), 0.000001);
- assertEquals(Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
-
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.01, -Math.PI * 0.25, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.09, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.11, b.getMinLatitude(), 0.000001);
- assertEquals(-Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
- assertEquals(-Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
-
- // Now do a somewhat tilted plane.
- c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -0.5, 0.1);
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(0.11, b.getMaxLatitude(), 0.000001);
- assertEquals(-0.09, b.getMinLatitude(), 0.000001);
- assertEquals(-0.6, b.getLeftLongitude(), 0.00001);
- assertEquals(-0.4, b.getRightLongitude(), 0.00001);
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoConvexPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoConvexPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoConvexPolygonTest.java
deleted file mode 100755
index d6ca7ba..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoConvexPolygonTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class GeoConvexPolygonTest {
-
-
- @Test
- public void testPolygonPointWithin() {
- GeoConvexPolygon c;
- GeoPoint gp;
- c = new GeoConvexPolygon(PlanetModel.SPHERE, -0.1, -0.5);
- c.addPoint(0.0, -0.6, false);
- c.addPoint(0.1, -0.5, false);
- c.addPoint(0.0, -0.4, false);
- c.done(false);
- // Sample some points within
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
- assertTrue(c.isWithin(gp));
- // Sample some nearby points outside, and compute distance-to-shape for them as well
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
- assertFalse(c.isWithin(gp));
- assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
- assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-3);
- assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),1e-3);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
- assertFalse(c.isWithin(gp));
- // Random points outside
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertFalse(c.isWithin(gp));
- }
-
- @Test
- public void testPolygonBounds() {
- GeoConvexPolygon c;
- LatLonBounds b;
-
- c = new GeoConvexPolygon(PlanetModel.SPHERE, -0.1, -0.5);
- c.addPoint(0.0, -0.6, false);
- c.addPoint(0.1, -0.5, false);
- c.addPoint(0.0, -0.4, false);
- c.done(false);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
- assertEquals(-0.4, b.getRightLongitude(), 0.000001);
- assertEquals(-0.1, b.getMinLatitude(), 0.000001);
- assertEquals(0.1, b.getMaxLatitude(), 0.000001);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoModelTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoModelTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoModelTest.java
deleted file mode 100644
index b3001d4..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoModelTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Test basic plane functionality.
- */
-public class GeoModelTest {
-
- protected final static PlanetModel scaledModel = new PlanetModel(1.2,1.5);
-
- @Test
- public void testBasicCircle() {
- // The point of this test is just to make sure nothing blows up doing normal things with a quite non-spherical model
- // Make sure that the north pole is in the circle, and south pole isn't
- final GeoPoint northPole = new GeoPoint(scaledModel, Math.PI * 0.5, 0.0);
- final GeoPoint southPole = new GeoPoint(scaledModel, -Math.PI * 0.5, 0.0);
- final GeoPoint point1 = new GeoPoint(scaledModel, Math.PI * 0.25, 0.0);
- final GeoPoint point2 = new GeoPoint(scaledModel, Math.PI * 0.125, 0.0);
-
- GeoCircle circle = new GeoStandardCircle(scaledModel, Math.PI * 0.5, 0.0, 0.01);
- assertTrue(circle.isWithin(northPole));
- assertFalse(circle.isWithin(southPole));
- assertFalse(circle.isWithin(point1));
- LatLonBounds bounds;
- bounds = new LatLonBounds();
- circle.getBounds(bounds);
- assertTrue(bounds.checkNoLongitudeBound());
- assertTrue(bounds.checkNoTopLatitudeBound());
- assertFalse(bounds.checkNoBottomLatitudeBound());
- assertEquals(Math.PI * 0.5 - 0.01, bounds.getMinLatitude(), 0.01);
-
- circle = new GeoStandardCircle(scaledModel, Math.PI * 0.25, 0.0, 0.01);
- assertTrue(circle.isWithin(point1));
- assertFalse(circle.isWithin(northPole));
- assertFalse(circle.isWithin(southPole));
- bounds = new LatLonBounds();
- circle.getBounds(bounds);
- assertFalse(bounds.checkNoTopLatitudeBound());
- assertFalse(bounds.checkNoLongitudeBound());
- assertFalse(bounds.checkNoBottomLatitudeBound());
- assertEquals(Math.PI * 0.25 + 0.01, bounds.getMaxLatitude(), 0.00001);
- assertEquals(Math.PI * 0.25 - 0.01, bounds.getMinLatitude(), 0.00001);
- assertEquals(-0.0125, bounds.getLeftLongitude(), 0.0001);
- assertEquals(0.0125, bounds.getRightLongitude(), 0.0001);
-
- circle = new GeoStandardCircle(scaledModel, Math.PI * 0.125, 0.0, 0.01);
- assertTrue(circle.isWithin(point2));
- assertFalse(circle.isWithin(northPole));
- assertFalse(circle.isWithin(southPole));
- bounds = new LatLonBounds();
- circle.getBounds(bounds);
- assertFalse(bounds.checkNoLongitudeBound());
- assertFalse(bounds.checkNoTopLatitudeBound());
- assertFalse(bounds.checkNoBottomLatitudeBound());
- // Symmetric, as expected
- assertEquals(Math.PI * 0.125 - 0.01, bounds.getMinLatitude(), 0.00001);
- assertEquals(Math.PI * 0.125 + 0.01, bounds.getMaxLatitude(), 0.00001);
- assertEquals(-0.0089, bounds.getLeftLongitude(), 0.0001);
- assertEquals(0.0089, bounds.getRightLongitude(), 0.0001);
-
- }
-
- @Test
- public void testBasicRectangle() {
- final GeoBBox bbox = GeoBBoxFactory.makeGeoBBox(scaledModel, 1.0, 0.0, 0.0, 1.0);
- final GeoPoint insidePoint = new GeoPoint(scaledModel, 0.5, 0.5);
- assertTrue(bbox.isWithin(insidePoint));
- final GeoPoint topOutsidePoint = new GeoPoint(scaledModel, 1.01, 0.5);
- assertFalse(bbox.isWithin(topOutsidePoint));
- final GeoPoint bottomOutsidePoint = new GeoPoint(scaledModel, -0.01, 0.5);
- assertFalse(bbox.isWithin(bottomOutsidePoint));
- final GeoPoint leftOutsidePoint = new GeoPoint(scaledModel, 0.5, -0.01);
- assertFalse(bbox.isWithin(leftOutsidePoint));
- final GeoPoint rightOutsidePoint = new GeoPoint(scaledModel, 0.5, 1.01);
- assertFalse(bbox.isWithin(rightOutsidePoint));
- final LatLonBounds bounds = new LatLonBounds();
- bbox.getBounds(bounds);
- assertFalse(bounds.checkNoLongitudeBound());
- assertFalse(bounds.checkNoTopLatitudeBound());
- assertFalse(bounds.checkNoBottomLatitudeBound());
- assertEquals(1.0, bounds.getMaxLatitude(), 0.00001);
- assertEquals(0.0, bounds.getMinLatitude(), 0.00001);
- assertEquals(1.0, bounds.getRightLongitude(), 0.00001);
- assertEquals(0.0, bounds.getLeftLongitude(), 0.00001);
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPathTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPathTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPathTest.java
deleted file mode 100755
index fea7ed4..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPathTest.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.junit.Test;
-
-import static java.lang.Math.toRadians;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class GeoPathTest {
-
- @Test
- public void testPathDistance() {
- // Start with a really simple case
- GeoPath p;
- GeoPoint gp;
- p = new GeoPath(PlanetModel.SPHERE, 0.1);
- p.addPoint(0.0, 0.0);
- p.addPoint(0.0, 0.1);
- p.addPoint(0.0, 0.2);
- p.done();
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.15);
- assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
- assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
- assertEquals(0.12 + 0.0, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, -0.15, 0.05);
- assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.25);
- assertEquals(0.20 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.05);
- assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
-
- // Compute path distances now
- p = new GeoPath(PlanetModel.SPHERE, 0.1);
- p.addPoint(0.0, 0.0);
- p.addPoint(0.0, 0.1);
- p.addPoint(0.0, 0.2);
- p.done();
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
- assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
- assertEquals(0.12, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
-
- // Now try a vertical path, and make sure distances are as expected
- p = new GeoPath(PlanetModel.SPHERE, 0.1);
- p.addPoint(-Math.PI * 0.25, -0.5);
- p.addPoint(Math.PI * 0.25, -0.5);
- p.done();
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
- gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.0);
- assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.25 + 0.05, -0.5);
- assertEquals(Math.PI * 0.5 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, -0.5);
- assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
- }
-
- @Test
- public void testPathPointWithin() {
- // Tests whether we can properly detect whether a point is within a path or not
- GeoPath p;
- GeoPoint gp;
- p = new GeoPath(PlanetModel.SPHERE, 0.1);
- // Build a diagonal path crossing the equator
- p.addPoint(-0.2, -0.2);
- p.addPoint(0.2, 0.2);
- p.done();
- // Test points on the path
- gp = new GeoPoint(PlanetModel.SPHERE, -0.2, -0.2);
- assertTrue(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertTrue(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.1);
- assertTrue(p.isWithin(gp));
- // Test points off the path
- gp = new GeoPoint(PlanetModel.SPHERE, -0.2, 0.2);
- assertFalse(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
- assertFalse(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.2, -0.2);
- assertFalse(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertFalse(p.isWithin(gp));
- // Repeat the test, but across the terminator
- p = new GeoPath(PlanetModel.SPHERE, 0.1);
- // Build a diagonal path crossing the equator
- p.addPoint(-0.2, Math.PI - 0.2);
- p.addPoint(0.2, -Math.PI + 0.2);
- p.done();
- // Test points on the path
- gp = new GeoPoint(PlanetModel.SPHERE, -0.2, Math.PI - 0.2);
- assertTrue(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertTrue(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI + 0.1);
- assertTrue(p.isWithin(gp));
- // Test points off the path
- gp = new GeoPoint(PlanetModel.SPHERE, -0.2, -Math.PI + 0.2);
- assertFalse(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
- assertFalse(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.2, Math.PI - 0.2);
- assertFalse(p.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertFalse(p.isWithin(gp));
-
- }
-
- @Test
- public void testGetRelationship() {
- GeoArea rect;
- GeoPath p;
- GeoPath c;
- GeoPoint point;
- GeoPoint pointApprox;
- int relationship;
- GeoArea area;
- PlanetModel planetModel;
-
- planetModel = new PlanetModel(1.151145876105594, 0.8488541238944061);
- c = new GeoPath(planetModel, 0.008726646259971648);
- c.addPoint(-0.6925658899376476, 0.6316613927914589);
- c.addPoint(0.27828548161836364, 0.6785795524104564);
- c.done();
- point = new GeoPoint(planetModel,-0.49298555067758226, 0.9892440995026406);
- pointApprox = new GeoPoint(0.5110940362119821, 0.7774603209946239, -0.49984312299556544);
- area = GeoAreaFactory.makeGeoArea(planetModel, 0.49937141144985997, 0.5161765426256085, 0.3337218719537796,0.8544419570901649, -0.6347692823688085, 0.3069696588119369);
- assertTrue(!c.isWithin(point));
-
- // Start by testing the basic kinds of relationship, increasing in order of difficulty.
-
- p = new GeoPath(PlanetModel.SPHERE, 0.1);
- p.addPoint(-0.3, -0.3);
- p.addPoint(0.3, 0.3);
- p.done();
- // Easiest: The path is wholly contains the georect
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.05, 0.05);
- assertEquals(GeoArea.CONTAINS, rect.getRelationship(p));
- // Next easiest: Some endpoints of the rectangle are inside, and some are outside.
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.05, 0.5);
- assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
- // Now, all points are outside, but the figures intersect
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.5, 0.5);
- assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
- // Finally, all points are outside, and the figures *do not* intersect
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, 0.5);
- assertEquals(GeoArea.WITHIN, rect.getRelationship(p));
- // Check that segment edge overlap detection works
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.1, 0.0, -0.1, 0.0);
- assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.2, 0.1, -0.2, -0.1);
- assertEquals(GeoArea.DISJOINT, rect.getRelationship(p));
- // Check if overlap at endpoints behaves as expected next
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, -0.35);
- assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
- rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, -0.45);
- assertEquals(GeoArea.DISJOINT, rect.getRelationship(p));
-
- }
-
- @Test
- public void testPathBounds() {
- GeoPath c;
- LatLonBounds b;
- XYZBounds xyzb;
- GeoPoint point;
- int relationship;
- GeoArea area;
- PlanetModel planetModel;
-
- planetModel = new PlanetModel(0.751521665790406,1.248478334209594);
- c = new GeoPath(planetModel, 0.7504915783575618);
- c.addPoint(0.10869761172400265, 0.08895880215465272);
- c.addPoint(0.22467878641991612, 0.10972973084229565);
- c.addPoint(-0.7398772468744732, -0.4465812941383364);
- c.addPoint(-0.18462055300079366, -0.6713857796763727);
- c.done();
- point = new GeoPoint(planetModel,-0.626645355125733,-1.409304625439381);
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(planetModel,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- relationship = area.getRelationship(c);
- assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
- assertTrue(area.isWithin(point));
- // No longer true due to fixed GeoPath waypoints.
- //assertTrue(c.isWithin(point));
-
- c = new GeoPath(PlanetModel.WGS84, 0.6894050545377601);
- c.addPoint(-0.0788176065762948, 0.9431251741731624);
- c.addPoint(0.510387871458147, 0.5327078872484678);
- c.addPoint(-0.5624521609859962, 1.5398841746888388);
- c.addPoint(-0.5025171434638661, -0.5895998642788894);
- c.done();
- point = new GeoPoint(PlanetModel.WGS84, 0.023652082107211682, 0.023131910152748437);
- //System.err.println("Point.x = "+point.x+"; point.y="+point.y+"; point.z="+point.z);
- assertTrue(c.isWithin(point));
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println("minx="+xyzb.getMinimumX()+" maxx="+xyzb.getMaximumX()+" miny="+xyzb.getMinimumY()+" maxy="+xyzb.getMaximumY()+" minz="+xyzb.getMinimumZ()+" maxz="+xyzb.getMaximumZ());
- //System.err.println("point.x="+point.x+" point.y="+point.y+" point.z="+point.z);
- relationship = area.getRelationship(c);
- assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
- assertTrue(area.isWithin(point));
-
- c = new GeoPath(PlanetModel.WGS84, 0.7766715171374766);
- c.addPoint(-0.2751718361148076, -0.7786721269011477);
- c.addPoint(0.5728375851539309, -1.2700115736820465);
- c.done();
- point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
- assertTrue(c.isWithin(point));
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- //System.err.println("minx="+xyzb.getMinimumX()+" maxx="+xyzb.getMaximumX()+" miny="+xyzb.getMinimumY()+" maxy="+xyzb.getMaximumY()+" minz="+xyzb.getMinimumZ()+" maxz="+xyzb.getMaximumZ());
- //System.err.println("point.x="+point.x+" point.y="+point.y+" point.z="+point.z);
- relationship = area.getRelationship(c);
- assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
- assertTrue(area.isWithin(point));
-
- c = new GeoPath(PlanetModel.SPHERE, 0.1);
- c.addPoint(-0.3, -0.3);
- c.addPoint(0.3, 0.3);
- c.done();
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-0.4046919, b.getLeftLongitude(), 0.000001);
- assertEquals(0.4046919, b.getRightLongitude(), 0.000001);
- assertEquals(-0.3999999, b.getMinLatitude(), 0.000001);
- assertEquals(0.3999999, b.getMaxLatitude(), 0.000001);
-
- }
-
- @Test
- public void testCoLinear() {
- // p1: (12,-90), p2: (11, -55), (129, -90)
- GeoPath p = new GeoPath(PlanetModel.SPHERE, 0.1);
- p.addPoint(toRadians(-90), toRadians(12));//south pole
- p.addPoint(toRadians(-55), toRadians(11));
- p.addPoint(toRadians(-90), toRadians(129));//south pole again
- p.done();//at least test this doesn't bomb like it used too -- LUCENE-6520
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPolygonTest.java
deleted file mode 100755
index f1511b9..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/GeoPolygonTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class GeoPolygonTest {
-
-
- @Test
- public void testPolygonPointWithin() {
- GeoMembershipShape c;
- GeoPoint gp;
- List<GeoPoint> points;
-
- points = new ArrayList<GeoPoint>();
- points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
-
- c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
- // Sample some points within
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
- assertTrue(c.isWithin(gp));
- // Sample some nearby points outside
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
- assertFalse(c.isWithin(gp));
- // Random points outside
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertFalse(c.isWithin(gp));
-
- points = new ArrayList<GeoPoint>();
- points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
- points.add(new GeoPoint(PlanetModel.SPHERE, -0.01, -0.6));
- points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.7));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.8));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.7));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.01, -0.6));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
-
- /*
- System.out.println("Points: ");
- for (GeoPoint p : points) {
- System.out.println(" "+p);
- }
- */
-
- c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
- // Sample some points within
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
- assertTrue(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.7);
- assertTrue(c.isWithin(gp));
- // Sample some nearby points outside
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
- assertFalse(c.isWithin(gp));
- // Random points outside
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
- assertFalse(c.isWithin(gp));
- gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
- assertFalse(c.isWithin(gp));
-
- }
-
- @Test
- public void testPolygonBounds() {
- GeoMembershipShape c;
- LatLonBounds b;
- List<GeoPoint> points;
- XYZBounds xyzb;
- GeoPoint point;
- GeoArea area;
-
- // BKD failure
- points = new ArrayList<GeoPoint>();
- points.add(new GeoPoint(PlanetModel.WGS84, -0.36716183577912814, 1.4836349969188696));
- points.add(new GeoPoint(PlanetModel.WGS84, 0.7846038240742979, -0.02743348424931823));
- points.add(new GeoPoint(PlanetModel.WGS84, -0.7376479402362607, -0.5072961758807019));
- points.add(new GeoPoint(PlanetModel.WGS84, -0.3760415907667887, 1.4970455334565513));
-
- c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, 1);
-
- point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
- assertTrue(c.isWithin(point));
- xyzb = new XYZBounds();
- c.getBounds(xyzb);
- area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
- xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
- assertTrue(area.isWithin(point));
-
- points = new ArrayList<GeoPoint>();
- points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
- points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
-
- c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
-
- b = new LatLonBounds();
- c.getBounds(b);
- assertFalse(b.checkNoLongitudeBound());
- assertFalse(b.checkNoTopLatitudeBound());
- assertFalse(b.checkNoBottomLatitudeBound());
- assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
- assertEquals(-0.4, b.getRightLongitude(), 0.000001);
- assertEquals(-0.1, b.getMinLatitude(), 0.000001);
- assertEquals(0.1, b.getMaxLatitude(), 0.000001);
- }
-
-}
[07/50] [abbrv] lucene-solr git commit: LUCENE-7071: reduce byte
copying costs of OfflineSorter
Posted by no...@apache.org.
LUCENE-7071: reduce byte copying costs of OfflineSorter
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/3d633c6e
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/3d633c6e
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/3d633c6e
Branch: refs/heads/apiv2
Commit: 3d633c6e68ec7a2e47d398daae203582537593a4
Parents: 4df4cb0
Author: Mike McCandless <mi...@apache.org>
Authored: Mon Mar 7 18:12:10 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Mon Mar 7 18:12:10 2016 -0500
----------------------------------------------------------------------
lucene/CHANGES.txt | 5 +++
.../org/apache/lucene/util/ByteBlockPool.java | 22 +++++++++++
.../org/apache/lucene/util/BytesRefArray.java | 41 +++++++++++++++-----
.../org/apache/lucene/util/OfflineSorter.java | 3 +-
.../search/suggest/SortedInputIterator.java | 16 ++++----
5 files changed, 69 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d633c6e/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 16550c6..5e717d4 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -9,6 +9,11 @@ http://s.apache.org/luceneversions
======================= Lucene 6.1.0 =======================
(No Changes)
+Optimizations
+
+* LUCENE-7071: Reduce bytes copying in OfflineSorter, giving ~10%
+ speedup on merging 2D LatLonPoint values (Mike McCandless)
+
======================= Lucene 6.0.0 =======================
System Requirements
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d633c6e/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java b/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
index 5f8fd41..6bb12bd 100644
--- a/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
+++ b/lucene/core/src/java/org/apache/lucene/util/ByteBlockPool.java
@@ -280,6 +280,28 @@ public final class ByteBlockPool {
return newUpto+3;
}
+ /** Fill the provided {@link BytesRef} with the bytes at the specified offset/length slice.
+ * This will avoid copying the bytes, if the slice fits into a single block; otherwise, it uses
+ * the provided {@linkl BytesRefBuilder} to copy bytes over. */
+ void setBytesRef(BytesRefBuilder builder, BytesRef result, long offset, int length) {
+ result.length = length;
+
+ int bufferIndex = (int) (offset >> BYTE_BLOCK_SHIFT);
+ byte[] buffer = buffers[bufferIndex];
+ int pos = (int) (offset & BYTE_BLOCK_MASK);
+ if (pos + length <= BYTE_BLOCK_SIZE) {
+ // common case where the slice lives in a single block: just reference the buffer directly without copying
+ result.bytes = buffer;
+ result.offset = pos;
+ } else {
+ // uncommon case: the slice spans at least 2 blocks, so we must copy the bytes:
+ builder.grow(length);
+ result.bytes = builder.get().bytes;
+ result.offset = 0;
+ readBytes(offset, result.bytes, 0, length);
+ }
+ }
+
// Fill in a BytesRef from term's length & bytes encoded in
// byte block
public void setBytesRef(BytesRef term, int textStart) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d633c6e/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java b/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
index 47ca52b..a19b7da 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
@@ -108,7 +108,23 @@ public final class BytesRefArray {
}
throw new IndexOutOfBoundsException("index " + index
+ " must be less than the size: " + lastElement);
-
+ }
+
+ /** Used only by sort below, to set a {@link BytesRef} with the specified slice, avoiding copying bytes in the common case when the slice
+ * is contained in a single block in the byte block pool. */
+ private void setBytesRef(BytesRefBuilder spare, BytesRef result, int index) {
+ if (index < lastElement) {
+ int offset = offsets[index];
+ int length;
+ if (index == lastElement - 1) {
+ length = currentOffset - offset;
+ } else {
+ length = offsets[index + 1] - offset;
+ }
+ pool.setBytesRef(spare, result, offset, length);
+ } else {
+ throw new IndexOutOfBoundsException("index " + index + " must be less than the size: " + lastElement);
+ }
}
private int[] sort(final Comparator<BytesRef> comp) {
@@ -127,25 +143,30 @@ public final class BytesRefArray {
@Override
protected int compare(int i, int j) {
final int idx1 = orderedEntries[i], idx2 = orderedEntries[j];
- return comp.compare(get(scratch1, idx1), get(scratch2, idx2));
+ setBytesRef(scratch1, scratchBytes1, idx1);
+ setBytesRef(scratch2, scratchBytes2, idx2);
+ return comp.compare(scratchBytes1, scratchBytes2);
}
@Override
protected void setPivot(int i) {
final int index = orderedEntries[i];
- pivot = get(pivotBuilder, index);
+ setBytesRef(pivotBuilder, pivot, index);
}
@Override
protected int comparePivot(int j) {
final int index = orderedEntries[j];
- return comp.compare(pivot, get(scratch2, index));
+ setBytesRef(scratch2, scratchBytes2, index);
+ return comp.compare(pivot, scratchBytes2);
}
- private BytesRef pivot;
- private final BytesRefBuilder pivotBuilder = new BytesRefBuilder(),
- scratch1 = new BytesRefBuilder(),
- scratch2 = new BytesRefBuilder();
+ private final BytesRef pivot = new BytesRef();
+ private final BytesRef scratchBytes1 = new BytesRef();
+ private final BytesRef scratchBytes2 = new BytesRef();
+ private final BytesRefBuilder pivotBuilder = new BytesRefBuilder();
+ private final BytesRefBuilder scratch1 = new BytesRefBuilder();
+ private final BytesRefBuilder scratch2 = new BytesRefBuilder();
}.sort(0, size());
return orderedEntries;
}
@@ -173,6 +194,7 @@ public final class BytesRefArray {
*/
public BytesRefIterator iterator(final Comparator<BytesRef> comp) {
final BytesRefBuilder spare = new BytesRefBuilder();
+ final BytesRef result = new BytesRef();
final int size = size();
final int[] indices = comp == null ? null : sort(comp);
return new BytesRefIterator() {
@@ -181,7 +203,8 @@ public final class BytesRefArray {
@Override
public BytesRef next() {
if (pos < size) {
- return get(spare, indices == null ? pos++ : indices[pos++]);
+ setBytesRef(spare, result, indices == null ? pos++ : indices[pos++]);
+ return result;
}
return null;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d633c6e/lucene/core/src/java/org/apache/lucene/util/OfflineSorter.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/OfflineSorter.java b/lucene/core/src/java/org/apache/lucene/util/OfflineSorter.java
index 283dc1f..18e421b 100644
--- a/lucene/core/src/java/org/apache/lucene/util/OfflineSorter.java
+++ b/lucene/core/src/java/org/apache/lucene/util/OfflineSorter.java
@@ -282,7 +282,6 @@ public class OfflineSorter {
/** Sort a single partition in-memory. */
protected String sortPartition(TrackingDirectoryWrapper trackingDir) throws IOException {
- BytesRefArray data = this.buffer;
try (IndexOutput tempFile = trackingDir.createTempOutput(tempFileNamePrefix, "sort", IOContext.DEFAULT);
ByteSequencesWriter out = getWriter(tempFile);) {
@@ -299,7 +298,7 @@ public class OfflineSorter {
}
// Clean up the buffer for the next partition.
- data.clear();
+ buffer.clear();
return tempFile.getName();
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d633c6e/lucene/suggest/src/java/org/apache/lucene/search/suggest/SortedInputIterator.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/SortedInputIterator.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/SortedInputIterator.java
index 2be1759..bc71e45 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/SortedInputIterator.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/SortedInputIterator.java
@@ -146,6 +146,7 @@ public class SortedInputIterator implements InputIterator {
@Override
public int compare(BytesRef left, BytesRef right) {
// Make shallow copy in case decode changes the BytesRef:
+ assert left != right;
leftScratch.bytes = left.bytes;
leftScratch.offset = left.offset;
leftScratch.length = left.length;
@@ -245,24 +246,24 @@ public class SortedInputIterator implements InputIterator {
/** decodes the weight at the current position */
protected long decode(BytesRef scratch, ByteArrayDataInput tmpInput) {
- tmpInput.reset(scratch.bytes);
+ tmpInput.reset(scratch.bytes, scratch.offset, scratch.length);
tmpInput.skipBytes(scratch.length - 8); // suggestion
- scratch.length -= 8; // long
+ scratch.length -= Long.BYTES; // long
return tmpInput.readLong();
}
/** decodes the contexts at the current position */
protected Set<BytesRef> decodeContexts(BytesRef scratch, ByteArrayDataInput tmpInput) {
- tmpInput.reset(scratch.bytes);
+ tmpInput.reset(scratch.bytes, scratch.offset, scratch.length);
tmpInput.skipBytes(scratch.length - 2); //skip to context set size
short ctxSetSize = tmpInput.readShort();
scratch.length -= 2;
final Set<BytesRef> contextSet = new HashSet<>();
for (short i = 0; i < ctxSetSize; i++) {
- tmpInput.setPosition(scratch.length - 2);
+ tmpInput.setPosition(scratch.offset + scratch.length - 2);
short curContextLength = tmpInput.readShort();
scratch.length -= 2;
- tmpInput.setPosition(scratch.length - curContextLength);
+ tmpInput.setPosition(scratch.offset + scratch.length - curContextLength);
BytesRef contextSpare = new BytesRef(curContextLength);
tmpInput.readBytes(contextSpare.bytes, 0, curContextLength);
contextSpare.length = curContextLength;
@@ -274,10 +275,11 @@ public class SortedInputIterator implements InputIterator {
/** decodes the payload at the current position */
protected BytesRef decodePayload(BytesRef scratch, ByteArrayDataInput tmpInput) {
- tmpInput.reset(scratch.bytes);
+ tmpInput.reset(scratch.bytes, scratch.offset, scratch.length);
tmpInput.skipBytes(scratch.length - 2); // skip to payload size
short payloadLength = tmpInput.readShort(); // read payload size
- tmpInput.setPosition(scratch.length - 2 - payloadLength); // setPosition to start of payload
+ assert payloadLength >= 0: payloadLength;
+ tmpInput.setPosition(scratch.offset + scratch.length - 2 - payloadLength); // setPosition to start of payload
BytesRef payloadScratch = new BytesRef(payloadLength);
tmpInput.readBytes(payloadScratch.bytes, 0, payloadLength); // read payload
payloadScratch.length = payloadLength;
[43/50] [abbrv] lucene-solr git commit: Merge branch 'master' of
https://git-wip-us.apache.org/repos/asf/lucene-solr
Posted by no...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/lucene-solr
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/d776f7b6
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/d776f7b6
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/d776f7b6
Branch: refs/heads/apiv2
Commit: d776f7b6bd7704283ec4db885b89cfb90f28ca75
Parents: 62b3aaa 02523d5
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 8 15:22:13 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 8 15:22:13 2016 -0500
----------------------------------------------------------------------
solr/CHANGES.txt | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
[15/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
new file mode 100755
index 0000000..458cf8b
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLongitudeSlice.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box limited on left and right.
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * {@link GeoWideLongitudeSlice}.
+ *
+ * @lucene.internal
+ */
+public class GeoLongitudeSlice extends GeoBaseBBox {
+ /** The left longitude of the slice */
+ protected final double leftLon;
+ /** The right longitude of the slice */
+ protected final double rightLon;
+ /** The left plane of the slice */
+ protected final SidedPlane leftPlane;
+ /** The right plane of the slice */
+ protected final SidedPlane rightPlane;
+ /** The notable points for the slice (north and south poles) */
+ protected final GeoPoint[] planePoints;
+ /** The center point of the slice */
+ protected final GeoPoint centerPoint;
+ /** A point on the edge of the slice */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lon: {@code -PI -> PI}
+ *@param planetModel is the planet model.
+ *@param leftLon is the left longitude of the slice.
+ *@param rightLon is the right longitude of the slice.
+ */
+ public GeoLongitudeSlice(final PlanetModel planetModel, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent > Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too great");
+
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ this.centerPoint = new GeoPoint(planetModel, 0.0, middleLon);
+
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
+ this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) &&
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Compute the extent and divide by two
+ double extent = rightLon - leftLon;
+ if (extent < 0.0)
+ extent += Math.PI * 2.0;
+ return Math.max(Math.PI * 0.5, extent * 0.5);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, leftPlane, notablePoints, planePoints, bounds, rightPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds, leftPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds
+ .addVerticalPlane(planetModel, leftLon, leftPlane, rightPlane)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, leftPlane)
+ .addPoint(planetModel.NORTH_POLE)
+ .addPoint(planetModel.SOUTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ if (path.intersects(leftPlane, planePoints, rightPlane) ||
+ path.intersects(rightPlane, planePoints, leftPlane)) {
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ return CONTAINS;
+ }
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane);
+
+ final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
+ final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
+
+ return
+ Math.min(
+ Math.min(northDistance, southDistance),
+ Math.min(leftDistance, rightDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoLongitudeSlice))
+ return false;
+ GeoLongitudeSlice other = (GeoLongitudeSlice) o;
+ return super.equals(other) && other.leftLon == leftLon && other.rightLon == rightLon;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp = Double.doubleToLongBits(leftLon);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(rightLon);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoLongitudeSlice: {planetmodel="+planetModel+", leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoMembershipShape.java
new file mode 100755
index 0000000..2c47971
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoMembershipShape.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Membership shapes have capabilities of both geohashing and membership
+ * determination.
+ *
+ * @lucene.experimental
+ */
+public interface GeoMembershipShape extends GeoShape, GeoOutsideDistance, Membership {
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
new file mode 100644
index 0000000..2c94061
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthLatitudeZone.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * This GeoBBox represents an area rectangle limited only in south latitude.
+ *
+ * @lucene.internal
+ */
+public class GeoNorthLatitudeZone extends GeoBaseBBox {
+ /** The bottom latitude of the zone */
+ protected final double bottomLat;
+ /** Cosine of the bottom latitude of the zone */
+ protected final double cosBottomLat;
+ /** The bottom plane of the zone */
+ protected final SidedPlane bottomPlane;
+ /** An interior point of the zone */
+ protected final GeoPoint interiorPoint;
+ /** Notable points: none */
+ protected final static GeoPoint[] planePoints = new GeoPoint[0];
+ /** A point on the bottom boundary */
+ protected final GeoPoint bottomBoundaryPoint;
+ /** A reference to the point on the boundary */
+ protected final GeoPoint[] edgePoints;
+
+ /** Constructor.
+ *@param planetModel is the planet model.
+ *@param bottomLat is the bottom latitude.
+ */
+ public GeoNorthLatitudeZone(final PlanetModel planetModel, final double bottomLat) {
+ super(planetModel);
+ this.bottomLat = bottomLat;
+
+ final double sinBottomLat = Math.sin(bottomLat);
+ this.cosBottomLat = Math.cos(bottomLat);
+
+ // Compute an interior point. Pick one whose lat is between top and bottom.
+ final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
+ this.bottomBoundaryPoint = new GeoPoint(planetModel, sinBottomLat, 0.0, Math.sqrt(1.0 - sinBottomLat * sinBottomLat), 1.0);
+
+ this.bottomPlane = new SidedPlane(interiorPoint, planetModel, sinBottomLat);
+
+ this.edgePoints = new GeoPoint[]{bottomBoundaryPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = Math.PI * 0.5;
+ final double newBottomLat = bottomLat - angle;
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return
+ bottomPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
+ // would contain all the bounding box points, when starting in the "center".
+ if (bottomLat < 0.0)
+ return Math.PI;
+ double maxCosLat = cosBottomLat;
+ return maxCosLat * Math.PI;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return
+ p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds
+ .addHorizontalPlane(planetModel, bottomLat, bottomPlane);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean insideShape = path.isWithin(bottomBoundaryPoint);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ // Second, the shortcut of seeing whether endpoints are in/out is not going to
+ // work with no area endpoints. So we rely entirely on intersections.
+
+ if (path.intersects(bottomPlane, planePoints))
+ return OVERLAPS;
+
+ // There is another case for latitude zones only. This is when the boundaries of the shape all fit
+ // within the zone, but the shape includes areas outside the zone crossing a pole.
+ // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
+ // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
+ // one such point is within, then OVERLAPS is the right answer.
+
+ if (insideShape)
+ return CONTAINS;
+
+ if (insideRectangle == ALL_INSIDE)
+ return WITHIN;
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoNorthLatitudeZone))
+ return false;
+ GeoNorthLatitudeZone other = (GeoNorthLatitudeZone) o;
+ return super.equals(other) && other.bottomBoundaryPoint.equals(bottomBoundaryPoint);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + bottomBoundaryPoint.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoNorthLatitudeZone: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
new file mode 100644
index 0000000..a2b6f1b
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoNorthRectangle.java
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box limited on three sides (bottom lat, left lon, right lon), including
+ * the north pole.
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * {@link GeoWideNorthRectangle}.
+ *
+ * @lucene.internal
+ */
+public class GeoNorthRectangle extends GeoBaseBBox {
+ /** The bottom latitude of the rectangle */
+ protected final double bottomLat;
+ /** The left longitude */
+ protected final double leftLon;
+ /** The right longitude */
+ protected final double rightLon;
+ /** Cosine of the middle latitude */
+ protected final double cosMiddleLat;
+ /** Lower right hand corner point */
+ protected final GeoPoint LRHC;
+ /** Lower left hand corner point */
+ protected final GeoPoint LLHC;
+ /** Bottom edge plane */
+ protected final SidedPlane bottomPlane;
+ /** Left-side plane */
+ protected final SidedPlane leftPlane;
+ /** Right-side plane */
+ protected final SidedPlane rightPlane;
+ /** Bottom plane notable points */
+ protected final GeoPoint[] bottomPlanePoints;
+ /** Left plane notable points */
+ protected final GeoPoint[] leftPlanePoints;
+ /** Right plane notable points */
+ protected final GeoPoint[] rightPlanePoints;
+ /** Center point */
+ protected final GeoPoint centerPoint;
+ /** A point on the edge */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *@param planetModel is the planet model.
+ *@param bottomLat is the bottom latitude.
+ *@param leftLon is the left longitude.
+ *@param rightLon is the right longitude.
+ */
+ public GeoNorthRectangle(final PlanetModel planetModel, final double bottomLat, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent > Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too great");
+
+ this.bottomLat = bottomLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinBottomLat = Math.sin(bottomLat);
+ final double cosBottomLat = Math.cos(bottomLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the points
+ this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
+ this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
+
+ final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+
+ this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
+ this.leftPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LLHC};
+ this.rightPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LRHC};
+
+ this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = Math.PI * 0.5;
+ final double newBottomLat = bottomLat - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return
+ bottomPlane.isWithin(x, y, z) &&
+ leftPlane.isWithin(x, y, z) &&
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double bottomAngle = centerPoint.arcDistance(LLHC);
+ return Math.max(centerAngle, bottomAngle);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return
+ p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, leftPlane, rightPlane) ||
+ p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, bottomPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, bottomPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds
+ .addHorizontalPlane(planetModel, bottomLat, bottomPlane, leftPlane, rightPlane)
+ .addVerticalPlane(planetModel, leftLon, leftPlane, bottomPlane, rightPlane)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, bottomPlane, leftPlane)
+ .addPoint(LLHC).addPoint(LRHC).addPoint(planetModel.NORTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (
+ path.intersects(bottomPlane, bottomPlanePoints, leftPlane, rightPlane) ||
+ path.intersects(leftPlane, leftPlanePoints, bottomPlane, rightPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, leftPlane, bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, leftPlane, rightPlane);
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, bottomPlane);
+
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return
+ Math.min(
+ bottomDistance,
+ Math.min(
+ Math.min(leftDistance, rightDistance),
+ Math.min(LRHCDistance, LLHCDistance)));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoNorthRectangle))
+ return false;
+ GeoNorthRectangle other = (GeoNorthRectangle) o;
+ return super.equals(other) && other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + LLHC.hashCode();
+ result = 31 * result + LRHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoNorthRectangle: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoOutsideDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoOutsideDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoOutsideDistance.java
new file mode 100644
index 0000000..717854c
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoOutsideDistance.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Implemented by Geo3D shapes that can compute the distance from a point to the closest outside edge.
+ *
+ * @lucene.experimental
+ */
+public interface GeoOutsideDistance extends Membership {
+
+ // The following methods compute distances from the shape to a point
+ // expected to be OUTSIDE the shape. Typically a value of 0.0
+ // is returned for points that happen to be within the shape.
+
+ /**
+ * Compute this shape's distance to the GeoPoint.
+ * A return value of 0.0 should be returned for
+ * points inside of the shape.
+ * @param distanceStyle is the distance style.
+ * @param point is the point to compute the distance to.
+ * @return the distance.
+ */
+ public default double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+ return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
+ }
+
+ /**
+ * Compute this shape's distance to the GeoPoint.
+ * A return value of 0.0 should be returned for
+ * points inside of the shape.
+ * @param distanceStyle is the distance style.
+ * @param x is the point's unit x coordinate (using U.S. convention).
+ * @param y is the point's unit y coordinate (using U.S. convention).
+ * @param z is the point's unit z coordinate (using U.S. convention).
+ * @return the distance.
+ */
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPath.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPath.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPath.java
new file mode 100755
index 0000000..a5b8b9b
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPath.java
@@ -0,0 +1,797 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * GeoShape representing a path across the surface of the globe,
+ * with a specified half-width. Path is described by a series of points.
+ * Distances are measured from the starting point along the path, and then at right
+ * angles to the path.
+ *
+ * @lucene.experimental
+ */
+public class GeoPath extends GeoBaseDistanceShape {
+ /** The cutoff angle (width) */
+ protected final double cutoffAngle;
+
+ /** Sine of cutoff angle */
+ protected final double sinAngle;
+ /** Cosine of cutoff angle */
+ protected final double cosAngle;
+
+ /** The original list of path points */
+ protected final List<GeoPoint> points = new ArrayList<GeoPoint>();
+
+ /** A list of SegmentEndpoints */
+ protected List<SegmentEndpoint> endPoints;
+ /** A list of PathSegments */
+ protected List<PathSegment> segments;
+
+ /** A point on the edge */
+ protected GeoPoint[] edgePoints;
+
+ /** Set to true if path has been completely constructed */
+ protected boolean isDone = false;
+
+ /** Constructor.
+ *@param planetModel is the planet model.
+ *@param maxCutoffAngle is the width of the path, measured as an angle.
+ *@param pathPoints are the points in the path.
+ */
+ public GeoPath(final PlanetModel planetModel, final double maxCutoffAngle, final GeoPoint[] pathPoints) {
+ this(planetModel, maxCutoffAngle);
+ Collections.addAll(points, pathPoints);
+ done();
+ }
+
+ /** Piece-wise constructor. Use in conjunction with addPoint() and done().
+ *@param planetModel is the planet model.
+ *@param maxCutoffAngle is the width of the path, measured as an angle.
+ */
+ public GeoPath(final PlanetModel planetModel, final double maxCutoffAngle) {
+ super(planetModel);
+ if (maxCutoffAngle <= 0.0 || maxCutoffAngle > Math.PI * 0.5)
+ throw new IllegalArgumentException("Cutoff angle out of bounds");
+ this.cutoffAngle = maxCutoffAngle;
+ this.cosAngle = Math.cos(maxCutoffAngle);
+ this.sinAngle = Math.sin(maxCutoffAngle);
+ }
+
+ /** Add a point to the path.
+ *@param lat is the latitude of the point.
+ *@param lon is the longitude of the point.
+ */
+ public void addPoint(final double lat, final double lon) {
+ if (isDone)
+ throw new IllegalStateException("Can't call addPoint() if done() already called");
+ points.add(new GeoPoint(planetModel, lat, lon));
+ }
+
+ /** Complete the path.
+ */
+ public void done() {
+ if (isDone)
+ throw new IllegalStateException("Can't call done() twice");
+ if (points.size() == 0)
+ throw new IllegalArgumentException("Path must have at least one point");
+ isDone = true;
+
+ endPoints = new ArrayList<>(points.size());
+ segments = new ArrayList<>(points.size());
+ // Compute an offset to use for all segments. This will be based on the minimum magnitude of
+ // the entire ellipsoid.
+ final double cutoffOffset = this.sinAngle * planetModel.getMinimumMagnitude();
+
+ // First, build all segments. We'll then go back and build corresponding segment endpoints.
+ GeoPoint lastPoint = null;
+ for (final GeoPoint end : points) {
+ if (lastPoint != null) {
+ final Plane normalizedConnectingPlane = new Plane(lastPoint, end);
+ if (normalizedConnectingPlane == null) {
+ continue;
+ }
+ segments.add(new PathSegment(planetModel, lastPoint, end, normalizedConnectingPlane, cutoffOffset));
+ }
+ lastPoint = end;
+ }
+
+ if (segments.size() == 0) {
+ // Simple circle
+ double lat = points.get(0).getLatitude();
+ double lon = points.get(0).getLongitude();
+ // Compute two points on the circle, with the right angle from the center. We'll use these
+ // to obtain the perpendicular plane to the circle.
+ double upperLat = lat + cutoffAngle;
+ double upperLon = lon;
+ if (upperLat > Math.PI * 0.5) {
+ upperLon += Math.PI;
+ if (upperLon > Math.PI)
+ upperLon -= 2.0 * Math.PI;
+ upperLat = Math.PI - upperLat;
+ }
+ double lowerLat = lat - cutoffAngle;
+ double lowerLon = lon;
+ if (lowerLat < -Math.PI * 0.5) {
+ lowerLon += Math.PI;
+ if (lowerLon > Math.PI)
+ lowerLon -= 2.0 * Math.PI;
+ lowerLat = -Math.PI - lowerLat;
+ }
+ final GeoPoint upperPoint = new GeoPoint(planetModel, upperLat, upperLon);
+ final GeoPoint lowerPoint = new GeoPoint(planetModel, lowerLat, lowerLon);
+ final GeoPoint point = points.get(0);
+
+ // Construct normal plane
+ final Plane normalPlane = Plane.constructNormalizedZPlane(upperPoint, lowerPoint, point);
+
+ final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(point, normalPlane, upperPoint, lowerPoint);
+ endPoints.add(onlyEndpoint);
+ this.edgePoints = new GeoPoint[]{onlyEndpoint.circlePlane.getSampleIntersectionPoint(planetModel, normalPlane)};
+ return;
+ }
+
+ // Create segment endpoints. Use an appropriate constructor for the start and end of the path.
+ for (int i = 0; i < segments.size(); i++) {
+ final PathSegment currentSegment = segments.get(i);
+
+ if (i == 0) {
+ // Starting endpoint
+ final SegmentEndpoint startEndpoint = new SegmentEndpoint(currentSegment.start,
+ currentSegment.startCutoffPlane, currentSegment.ULHC, currentSegment.LLHC);
+ endPoints.add(startEndpoint);
+ this.edgePoints = new GeoPoint[]{currentSegment.ULHC};
+ continue;
+ }
+
+ // General intersection case
+ final PathSegment prevSegment = segments.get(i-1);
+ // We construct four separate planes, and evaluate which one includes all interior points with least overlap
+ final SidedPlane candidate1 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, prevSegment.URHC, currentSegment.ULHC, currentSegment.LLHC);
+ final SidedPlane candidate2 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, currentSegment.ULHC, currentSegment.LLHC, prevSegment.LRHC);
+ final SidedPlane candidate3 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, currentSegment.LLHC, prevSegment.LRHC, prevSegment.URHC);
+ final SidedPlane candidate4 = SidedPlane.constructNormalizedThreePointSidedPlane(currentSegment.start, prevSegment.LRHC, prevSegment.URHC, currentSegment.ULHC);
+
+ if (candidate1 == null && candidate2 == null && candidate3 == null && candidate4 == null) {
+ // The planes are identical. We wouldn't need a circle at all except for the possibility of
+ // backing up, which is hard to detect here.
+ final SegmentEndpoint midEndpoint = new SegmentEndpoint(currentSegment.start,
+ prevSegment.endCutoffPlane, currentSegment.startCutoffPlane, currentSegment.ULHC, currentSegment.LLHC);
+ //don't need a circle at all. Special constructor...
+ endPoints.add(midEndpoint);
+ } else {
+ endPoints.add(new SegmentEndpoint(currentSegment.start,
+ prevSegment.endCutoffPlane, currentSegment.startCutoffPlane,
+ prevSegment.URHC, prevSegment.LRHC,
+ currentSegment.ULHC, currentSegment.LLHC,
+ candidate1, candidate2, candidate3, candidate4));
+ }
+ }
+ // Do final endpoint
+ final PathSegment lastSegment = segments.get(segments.size()-1);
+ endPoints.add(new SegmentEndpoint(lastSegment.end,
+ lastSegment.endCutoffPlane, lastSegment.URHC, lastSegment.LRHC));
+
+ }
+
+ @Override
+ protected double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ // Algorithm:
+ // (1) If the point is within any of the segments along the path, return that value.
+ // (2) If the point is within any of the segment end circles along the path, return that value.
+ double currentDistance = 0.0;
+ for (PathSegment segment : segments) {
+ double distance = segment.pathDistance(planetModel, distanceStyle, x,y,z);
+ if (distance != Double.MAX_VALUE)
+ return currentDistance + distance;
+ currentDistance += segment.fullPathDistance(distanceStyle);
+ }
+
+ int segmentIndex = 0;
+ currentDistance = 0.0;
+ for (SegmentEndpoint endpoint : endPoints) {
+ double distance = endpoint.pathDistance(distanceStyle, x, y, z);
+ if (distance != Double.MAX_VALUE)
+ return currentDistance + distance;
+ if (segmentIndex < segments.size())
+ currentDistance += segments.get(segmentIndex++).fullPathDistance(distanceStyle);
+ }
+
+ return Double.MAX_VALUE;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ double minDistance = Double.MAX_VALUE;
+ for (final SegmentEndpoint endpoint : endPoints) {
+ final double newDistance = endpoint.outsideDistance(distanceStyle, x,y,z);
+ if (newDistance < minDistance)
+ minDistance = newDistance;
+ }
+ for (final PathSegment segment : segments) {
+ final double newDistance = segment.outsideDistance(planetModel, distanceStyle, x, y, z);
+ if (newDistance < minDistance)
+ minDistance = newDistance;
+ }
+ return minDistance;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (SegmentEndpoint pathPoint : endPoints) {
+ if (pathPoint.isWithin(x, y, z))
+ return true;
+ }
+ for (PathSegment pathSegment : segments) {
+ if (pathSegment.isWithin(x, y, z))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // We look for an intersection with any of the exterior edges of the path.
+ // We also have to look for intersections with the cones described by the endpoints.
+ // Return "true" if any such intersections are found.
+
+ // For plane intersections, the basic idea is to come up with an equation of the line that is
+ // the intersection (if any). Then, find the intersections with the unit sphere (if any). If
+ // any of the intersection points are within the bounds, then we've detected an intersection.
+ // Well, sort of. We can detect intersections also due to overlap of segments with each other.
+ // But that's an edge case and we won't be optimizing for it.
+ //System.err.println(" Looking for intersection of plane "+plane+" with path "+this);
+ for (final SegmentEndpoint pathPoint : endPoints) {
+ if (pathPoint.intersects(planetModel, plane, notablePoints, bounds)) {
+ return true;
+ }
+ }
+
+ for (final PathSegment pathSegment : segments) {
+ if (pathSegment.intersects(planetModel, plane, notablePoints, bounds)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ // For building bounds, order matters. We want to traverse
+ // never more than 180 degrees longitude at a pop or we risk having the
+ // bounds object get itself inverted. So do the edges first.
+ for (PathSegment pathSegment : segments) {
+ pathSegment.getBounds(planetModel, bounds);
+ }
+ for (SegmentEndpoint pathPoint : endPoints) {
+ pathPoint.getBounds(planetModel, bounds);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoPath))
+ return false;
+ GeoPath p = (GeoPath) o;
+ if (!super.equals(p))
+ return false;
+ if (cutoffAngle != p.cutoffAngle)
+ return false;
+ return points.equals(p.points);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp = Double.doubleToLongBits(cutoffAngle);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ result = 31 * result + points.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoPath: {planetmodel=" + planetModel+", width=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + "), points={" + points + "}}";
+ }
+
+ /**
+ * This is precalculated data for segment endpoint.
+ * Note well: This is not necessarily a circle. There are four cases:
+ * (1) The path consists of a single endpoint. In this case, we build a simple circle with the proper cutoff offset.
+ * (2) This is the end of a path. The circle plane must be constructed to go through two supplied points and be perpendicular to a connecting plane.
+ * (2.5) Intersection, but the path on both sides is linear. We generate a circle, but we use the cutoff planes to limit its influence in the straight line case.
+ * (3) This is an intersection in a path. We are supplied FOUR planes. If there are intersections within bounds for both upper and lower, then
+ * we generate no circle at all. If there is one intersection only, then we generate a plane that includes that intersection, as well as the remaining
+ * cutoff plane/edge plane points.
+ */
+ public static class SegmentEndpoint {
+ /** The center point of the endpoint */
+ public final GeoPoint point;
+ /** A plane describing the circle */
+ public final SidedPlane circlePlane;
+ /** Pertinent cutoff planes from adjoining segments */
+ public final Membership[] cutoffPlanes;
+ /** Notable points for this segment endpoint */
+ public final GeoPoint[] notablePoints;
+ /** No notable points from the circle itself */
+ public final static GeoPoint[] circlePoints = new GeoPoint[0];
+ /** Null membership */
+ public final static Membership[] NO_MEMBERSHIP = new Membership[0];
+
+ /** Base case. Does nothing at all.
+ */
+ public SegmentEndpoint(final GeoPoint point) {
+ this.point = point;
+ this.circlePlane = null;
+ this.cutoffPlanes = null;
+ this.notablePoints = null;
+ }
+
+ /** Constructor for case (1).
+ * Generate a simple circle cutoff plane.
+ *@param point is the center point.
+ *@param upperPoint is a point that must be on the circle plane.
+ *@param lowerPoint is another point that must be on the circle plane.
+ */
+ public SegmentEndpoint(final GeoPoint point, final Plane normalPlane, final GeoPoint upperPoint, final GeoPoint lowerPoint) {
+ this.point = point;
+ // Construct a sided plane that goes through the two points and whose normal is in the normalPlane.
+ this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, normalPlane, upperPoint, lowerPoint);
+ this.cutoffPlanes = NO_MEMBERSHIP;
+ this.notablePoints = circlePoints;
+ }
+
+ /** Constructor for case (2).
+ * Generate an endpoint, given a single cutoff plane plus upper and lower edge points.
+ *@param point is the center point.
+ *@param cutoffPlane is the plane from the adjoining path segment marking the boundary between this endpoint and that segment.
+ *@param topEdgePoint is a point on the cutoffPlane that should be also on the circle plane.
+ *@param bottomEdgePoint is another point on the cutoffPlane that should be also on the circle plane.
+ */
+ public SegmentEndpoint(final GeoPoint point,
+ final SidedPlane cutoffPlane, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) {
+ this.point = point;
+ this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane)};
+ this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint};
+ // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
+ this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane, topEdgePoint, bottomEdgePoint);
+ }
+
+ /** Constructor for case (2.5).
+ * Generate an endpoint, given two cutoff planes plus upper and lower edge points.
+ *@param point is the center.
+ *@param cutoffPlane1 is one adjoining path segment cutoff plane.
+ *@param cutoffPlane2 is another adjoining path segment cutoff plane.
+ *@param topEdgePoint is a point on the cutoffPlane that should be also on the circle plane.
+ *@param bottomEdgePoint is another point on the cutoffPlane that should be also on the circle plane.
+ */
+ public SegmentEndpoint(final GeoPoint point,
+ final SidedPlane cutoffPlane1, final SidedPlane cutoffPlane2, final GeoPoint topEdgePoint, final GeoPoint bottomEdgePoint) {
+ this.point = point;
+ this.cutoffPlanes = new Membership[]{new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)};
+ this.notablePoints = new GeoPoint[]{topEdgePoint, bottomEdgePoint};
+ // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
+ this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(point, cutoffPlane1, topEdgePoint, bottomEdgePoint);
+ }
+
+ /** Constructor for case (3).
+ * Generate an endpoint for an intersection, given four points.
+ *@param point is the center.
+ *@param prevCutoffPlane is the previous adjoining segment cutoff plane.
+ *@param nextCutoffPlane is the next path segment cutoff plane.
+ *@param notCand2Point is a point NOT on candidate2.
+ *@param notCand1Point is a point NOT on candidate1.
+ *@param notCand3Point is a point NOT on candidate3.
+ *@param notCand4Point is a point NOT on candidate4.
+ *@param candidate1 one of four candidate circle planes.
+ *@param candidate2 one of four candidate circle planes.
+ *@param candidate3 one of four candidate circle planes.
+ *@param candidate4 one of four candidate circle planes.
+ */
+ public SegmentEndpoint(final GeoPoint point,
+ final SidedPlane prevCutoffPlane, final SidedPlane nextCutoffPlane,
+ final GeoPoint notCand2Point, final GeoPoint notCand1Point,
+ final GeoPoint notCand3Point, final GeoPoint notCand4Point,
+ final SidedPlane candidate1, final SidedPlane candidate2, final SidedPlane candidate3, final SidedPlane candidate4) {
+ // Note: What we really need is a single plane that goes through all four points.
+ // Since that's not possible in the ellipsoid case (because three points determine a plane, not four), we
+ // need an approximation that at least creates a boundary that has no interruptions.
+ // There are three obvious choices for the third point: either (a) one of the two remaining points, or (b) the top or bottom edge
+ // intersection point. (a) has no guarantee of continuity, while (b) is capable of producing something very far from a circle if
+ // the angle between segments is acute.
+ // The solution is to look for the side (top or bottom) that has an intersection within the shape. We use the two points from
+ // the opposite side to determine the plane, AND we pick the third to be either of the two points on the intersecting side
+ // PROVIDED that the other point is within the final circle we come up with.
+ this.point = point;
+
+ // We construct four separate planes, and evaluate which one includes all interior points with least overlap
+ // (Constructed beforehand because we need them for degeneracy check)
+
+ final boolean cand1IsOtherWithin = candidate1!=null?candidate1.isWithin(notCand1Point):false;
+ final boolean cand2IsOtherWithin = candidate2!=null?candidate2.isWithin(notCand2Point):false;
+ final boolean cand3IsOtherWithin = candidate3!=null?candidate3.isWithin(notCand3Point):false;
+ final boolean cand4IsOtherWithin = candidate4!=null?candidate4.isWithin(notCand4Point):false;
+
+ if (cand1IsOtherWithin && cand2IsOtherWithin && cand3IsOtherWithin && cand4IsOtherWithin) {
+ // The only way we should see both within is if all four points are coplanar. In that case, we default to the simplest treatment.
+ this.circlePlane = candidate1; // doesn't matter which
+ this.notablePoints = new GeoPoint[]{notCand2Point, notCand3Point, notCand1Point, notCand4Point};
+ this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane), new SidedPlane(nextCutoffPlane)};
+ } else if (cand1IsOtherWithin) {
+ // Use candidate1, and DON'T include prevCutoffPlane in the cutoff planes list
+ this.circlePlane = candidate1;
+ this.notablePoints = new GeoPoint[]{notCand2Point, notCand3Point, notCand4Point};
+ this.cutoffPlanes = new Membership[]{new SidedPlane(nextCutoffPlane)};
+ } else if (cand2IsOtherWithin) {
+ // Use candidate2
+ this.circlePlane = candidate2;
+ this.notablePoints = new GeoPoint[]{notCand3Point, notCand4Point, notCand1Point};
+ this.cutoffPlanes = new Membership[]{new SidedPlane(nextCutoffPlane)};
+ } else if (cand3IsOtherWithin) {
+ this.circlePlane = candidate3;
+ this.notablePoints = new GeoPoint[]{notCand4Point, notCand1Point, notCand2Point};
+ this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane)};
+ } else if (cand4IsOtherWithin) {
+ this.circlePlane = candidate4;
+ this.notablePoints = new GeoPoint[]{notCand1Point, notCand2Point, notCand3Point};
+ this.cutoffPlanes = new Membership[]{new SidedPlane(prevCutoffPlane)};
+ } else {
+ // dunno what happened
+ throw new RuntimeException("Couldn't come up with a plane through three points that included the fourth");
+ }
+ }
+
+ /** Check if point is within this endpoint.
+ *@param point is the point.
+ *@return true of within.
+ */
+ public boolean isWithin(final Vector point) {
+ if (circlePlane == null)
+ return false;
+ if (!circlePlane.isWithin(point))
+ return false;
+ for (final Membership m : cutoffPlanes) {
+ if (!m.isWithin(point)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Check if point is within this endpoint.
+ *@param x is the point x.
+ *@param y is the point y.
+ *@param z is the point z.
+ *@return true of within.
+ */
+ public boolean isWithin(final double x, final double y, final double z) {
+ if (circlePlane == null)
+ return false;
+ if (!circlePlane.isWithin(x, y, z))
+ return false;
+ for (final Membership m : cutoffPlanes) {
+ if (!m.isWithin(x,y,z)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Compute interior path distance.
+ *@param distanceStyle is the distance style.
+ *@param x is the point x.
+ *@param y is the point y.
+ *@param z is the point z.
+ *@return the distance metric.
+ */
+ public double pathDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (!isWithin(x,y,z))
+ return Double.MAX_VALUE;
+ return distanceStyle.computeDistance(this.point, x, y, z);
+ }
+
+ /** Compute external distance.
+ *@param distanceStyle is the distance style.
+ *@param x is the point x.
+ *@param y is the point y.
+ *@param z is the point z.
+ *@return the distance metric.
+ */
+ public double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(this.point, x, y, z);
+ }
+
+ /** Determine if this endpoint intersects a specified plane.
+ *@param planetModel is the planet model.
+ *@param p is the plane.
+ *@param notablePoints are the points associated with the plane.
+ *@param bounds are any bounds which the intersection must lie within.
+ *@return true if there is a matching intersection.
+ */
+ public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
+ //System.err.println(" looking for intersection between plane "+p+" and circle "+circlePlane+" on proper side of "+cutoffPlanes+" within "+bounds);
+ if (circlePlane == null)
+ return false;
+ return circlePlane.intersects(planetModel, p, notablePoints, this.notablePoints, bounds, this.cutoffPlanes);
+ }
+
+ /** Get the bounds for a segment endpoint.
+ *@param planetModel is the planet model.
+ *@param bounds are the bounds to be modified.
+ */
+ public void getBounds(final PlanetModel planetModel, Bounds bounds) {
+ bounds.addPoint(point);
+ if (circlePlane == null)
+ return;
+ bounds.addPlane(planetModel, circlePlane);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof SegmentEndpoint))
+ return false;
+ SegmentEndpoint other = (SegmentEndpoint) o;
+ return point.equals(other.point);
+ }
+
+ @Override
+ public int hashCode() {
+ return point.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return point.toString();
+ }
+ }
+
+ /**
+ * This is the pre-calculated data for a path segment.
+ */
+ public static class PathSegment {
+ /** Starting point of the segment */
+ public final GeoPoint start;
+ /** End point of the segment */
+ public final GeoPoint end;
+ /** Place to keep any complete segment distances we've calculated so far */
+ public final Map<DistanceStyle,Double> fullDistanceCache = new HashMap<DistanceStyle,Double>();
+ /** Normalized plane connecting the two points and going through world center */
+ public final Plane normalizedConnectingPlane;
+ /** Cutoff plane parallel to connecting plane representing one side of the path segment */
+ public final SidedPlane upperConnectingPlane;
+ /** Cutoff plane parallel to connecting plane representing the other side of the path segment */
+ public final SidedPlane lowerConnectingPlane;
+ /** Plane going through the center and start point, marking the start edge of the segment */
+ public final SidedPlane startCutoffPlane;
+ /** Plane going through the center and end point, marking the end edge of the segment */
+ public final SidedPlane endCutoffPlane;
+ /** Upper right hand corner of segment */
+ public final GeoPoint URHC;
+ /** Lower right hand corner of segment */
+ public final GeoPoint LRHC;
+ /** Upper left hand corner of segment */
+ public final GeoPoint ULHC;
+ /** Lower left hand corner of segment */
+ public final GeoPoint LLHC;
+ /** Notable points for the upper connecting plane */
+ public final GeoPoint[] upperConnectingPlanePoints;
+ /** Notable points for the lower connecting plane */
+ public final GeoPoint[] lowerConnectingPlanePoints;
+ /** Notable points for the start cutoff plane */
+ public final GeoPoint[] startCutoffPlanePoints;
+ /** Notable points for the end cutoff plane */
+ public final GeoPoint[] endCutoffPlanePoints;
+
+ /** Construct a path segment.
+ *@param planetModel is the planet model.
+ *@param start is the starting point.
+ *@param end is the ending point.
+ *@param normalizedConnectingPlane is the connecting plane.
+ *@param planeBoundingOffset is the linear offset from the connecting plane to either side.
+ */
+ public PathSegment(final PlanetModel planetModel, final GeoPoint start, final GeoPoint end,
+ final Plane normalizedConnectingPlane, final double planeBoundingOffset) {
+ this.start = start;
+ this.end = end;
+ this.normalizedConnectingPlane = normalizedConnectingPlane;
+
+ // Either start or end should be on the correct side
+ upperConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, -planeBoundingOffset);
+ lowerConnectingPlane = new SidedPlane(start, normalizedConnectingPlane, planeBoundingOffset);
+ // Cutoff planes use opposite endpoints as correct side examples
+ startCutoffPlane = new SidedPlane(end, normalizedConnectingPlane, start);
+ endCutoffPlane = new SidedPlane(start, normalizedConnectingPlane, end);
+ final Membership[] upperSide = new Membership[]{upperConnectingPlane};
+ final Membership[] lowerSide = new Membership[]{lowerConnectingPlane};
+ final Membership[] startSide = new Membership[]{startCutoffPlane};
+ final Membership[] endSide = new Membership[]{endCutoffPlane};
+ GeoPoint[] points;
+ points = upperConnectingPlane.findIntersections(planetModel, startCutoffPlane, lowerSide, endSide);
+ if (points.length == 0) {
+ throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+ }
+ this.ULHC = points[0];
+ points = upperConnectingPlane.findIntersections(planetModel, endCutoffPlane, lowerSide, startSide);
+ if (points.length == 0) {
+ throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+ }
+ this.URHC = points[0];
+ points = lowerConnectingPlane.findIntersections(planetModel, startCutoffPlane, upperSide, endSide);
+ if (points.length == 0) {
+ throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+ }
+ this.LLHC = points[0];
+ points = lowerConnectingPlane.findIntersections(planetModel, endCutoffPlane, upperSide, startSide);
+ if (points.length == 0) {
+ throw new IllegalArgumentException("Some segment boundary points are off the ellipsoid; path too wide");
+ }
+ this.LRHC = points[0];
+ upperConnectingPlanePoints = new GeoPoint[]{ULHC, URHC};
+ lowerConnectingPlanePoints = new GeoPoint[]{LLHC, LRHC};
+ startCutoffPlanePoints = new GeoPoint[]{ULHC, LLHC};
+ endCutoffPlanePoints = new GeoPoint[]{URHC, LRHC};
+ }
+
+ /** Compute the full distance along this path segment.
+ *@param distanceStyle is the distance style.
+ *@return the distance metric.
+ */
+ public double fullPathDistance(final DistanceStyle distanceStyle) {
+ synchronized (fullDistanceCache) {
+ Double dist = fullDistanceCache.get(distanceStyle);
+ if (dist == null) {
+ dist = new Double(distanceStyle.computeDistance(start, end.x, end.y, end.z));
+ fullDistanceCache.put(distanceStyle, dist);
+ }
+ return dist.doubleValue();
+ }
+ }
+
+ /** Check if point is within this segment.
+ *@param point is the point.
+ *@return true of within.
+ */
+ public boolean isWithin(final Vector point) {
+ return startCutoffPlane.isWithin(point) &&
+ endCutoffPlane.isWithin(point) &&
+ upperConnectingPlane.isWithin(point) &&
+ lowerConnectingPlane.isWithin(point);
+ }
+
+ /** Check if point is within this segment.
+ *@param x is the point x.
+ *@param y is the point y.
+ *@param z is the point z.
+ *@return true of within.
+ */
+ public boolean isWithin(final double x, final double y, final double z) {
+ return startCutoffPlane.isWithin(x, y, z) &&
+ endCutoffPlane.isWithin(x, y, z) &&
+ upperConnectingPlane.isWithin(x, y, z) &&
+ lowerConnectingPlane.isWithin(x, y, z);
+ }
+
+ /** Compute interior path distance.
+ *@param planetModel is the planet model.
+ *@param distanceStyle is the distance style.
+ *@param x is the point x.
+ *@param y is the point y.
+ *@param z is the point z.
+ *@return the distance metric.
+ */
+ public double pathDistance(final PlanetModel planetModel, final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (!isWithin(x,y,z))
+ return Double.MAX_VALUE;
+
+ // (1) Compute normalizedPerpPlane. If degenerate, then return point distance from start to point.
+ // Want no allocations or expensive operations! so we do this the hard way
+ final double perpX = normalizedConnectingPlane.y * z - normalizedConnectingPlane.z * y;
+ final double perpY = normalizedConnectingPlane.z * x - normalizedConnectingPlane.x * z;
+ final double perpZ = normalizedConnectingPlane.x * y - normalizedConnectingPlane.y * x;
+ final double magnitude = Math.sqrt(perpX * perpX + perpY * perpY + perpZ * perpZ);
+ if (Math.abs(magnitude) < Vector.MINIMUM_RESOLUTION)
+ return distanceStyle.computeDistance(start, x,y,z);
+ final double normFactor = 1.0/magnitude;
+ final Plane normalizedPerpPlane = new Plane(perpX * normFactor, perpY * normFactor, perpZ * normFactor, 0.0);
+
+ // Old computation: too expensive, because it calculates the intersection point twice.
+ //return distanceStyle.computeDistance(planetModel, normalizedConnectingPlane, x, y, z, startCutoffPlane, endCutoffPlane) +
+ // distanceStyle.computeDistance(planetModel, normalizedPerpPlane, start.x, start.y, start.z, upperConnectingPlane, lowerConnectingPlane);
+
+ final GeoPoint[] intersectionPoints = normalizedConnectingPlane.findIntersections(planetModel, normalizedPerpPlane);
+ GeoPoint thePoint;
+ if (intersectionPoints.length == 0)
+ throw new RuntimeException("Can't find world intersection for point x="+x+" y="+y+" z="+z);
+ else if (intersectionPoints.length == 1)
+ thePoint = intersectionPoints[0];
+ else {
+ if (startCutoffPlane.isWithin(intersectionPoints[0]) && endCutoffPlane.isWithin(intersectionPoints[0]))
+ thePoint = intersectionPoints[0];
+ else if (startCutoffPlane.isWithin(intersectionPoints[1]) && endCutoffPlane.isWithin(intersectionPoints[1]))
+ thePoint = intersectionPoints[1];
+ else
+ throw new RuntimeException("Can't find world intersection for point x="+x+" y="+y+" z="+z);
+ }
+ return distanceStyle.computeDistance(thePoint, x, y, z) + distanceStyle.computeDistance(start, thePoint.x, thePoint.y, thePoint.z);
+ }
+
+ /** Compute external distance.
+ *@param planetModel is the planet model.
+ *@param distanceStyle is the distance style.
+ *@param x is the point x.
+ *@param y is the point y.
+ *@param z is the point z.
+ *@return the distance metric.
+ */
+ public double outsideDistance(final PlanetModel planetModel, final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double upperDistance = distanceStyle.computeDistance(planetModel, upperConnectingPlane, x,y,z, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
+ final double lowerDistance = distanceStyle.computeDistance(planetModel, lowerConnectingPlane, x,y,z, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+ final double startDistance = distanceStyle.computeDistance(planetModel, startCutoffPlane, x,y,z, endCutoffPlane, lowerConnectingPlane, upperConnectingPlane);
+ final double endDistance = distanceStyle.computeDistance(planetModel, endCutoffPlane, x,y,z, startCutoffPlane, lowerConnectingPlane, upperConnectingPlane);
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ return Math.min(
+ Math.min(
+ Math.min(upperDistance,lowerDistance),
+ Math.min(startDistance,endDistance)),
+ Math.min(
+ Math.min(ULHCDistance, URHCDistance),
+ Math.min(LLHCDistance, LRHCDistance)));
+ }
+
+ /** Determine if this endpoint intersects a specified plane.
+ *@param planetModel is the planet model.
+ *@param p is the plane.
+ *@param notablePoints are the points associated with the plane.
+ *@param bounds are any bounds which the intersection must lie within.
+ *@return true if there is a matching intersection.
+ */
+ public boolean intersects(final PlanetModel planetModel, final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
+ return upperConnectingPlane.intersects(planetModel, p, notablePoints, upperConnectingPlanePoints, bounds, lowerConnectingPlane, startCutoffPlane, endCutoffPlane) ||
+ lowerConnectingPlane.intersects(planetModel, p, notablePoints, lowerConnectingPlanePoints, bounds, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+ }
+
+ /** Get the bounds for a segment endpoint.
+ *@param planetModel is the planet model.
+ *@param bounds are the bounds to be modified.
+ */
+ public void getBounds(final PlanetModel planetModel, Bounds bounds) {
+ // We need to do all bounding planes as well as corner points
+ bounds.addPoint(start).addPoint(end).addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC);
+ bounds.addPlane(planetModel, upperConnectingPlane, lowerConnectingPlane, startCutoffPlane, endCutoffPlane);
+ bounds.addPlane(planetModel, lowerConnectingPlane, upperConnectingPlane, startCutoffPlane, endCutoffPlane);
+ bounds.addPlane(planetModel, startCutoffPlane, endCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
+ bounds.addPlane(planetModel, endCutoffPlane, startCutoffPlane, upperConnectingPlane, lowerConnectingPlane);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPoint.java
new file mode 100755
index 0000000..31ab0aa
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPoint.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * This class represents a point on the surface of a sphere or ellipsoid.
+ *
+ * @lucene.experimental
+ */
+public class GeoPoint extends Vector {
+
+ // By making lazily-evaluated variables be "volatile", we guarantee atomicity when they
+ // are updated. This is necessary if we are using these classes in a multi-thread fashion,
+ // because we don't try to synchronize for the lazy computation.
+
+ /** 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. Does not need to be
+ * synchronized for thread safety, because depends wholly on immutable variables of this class. */
+ protected volatile double magnitude = Double.NEGATIVE_INFINITY;
+ /** Lazily-evaluated latitude. Does not need to be
+ * synchronized for thread safety, because depends wholly on immutable variables of this class. */
+ protected volatile double latitude = Double.NEGATIVE_INFINITY;
+ /** Lazily-evaluated longitude. Does not need to be
+ * synchronized for thread safety, because depends wholly on immutable variables of this class. */
+ protected volatile double longitude = 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.
+ * @param lat is the latitude.
+ * @param lon is the longitude.
+ */
+ public GeoPoint(final PlanetModel planetModel, final double sinLat, final double sinLon, final double cosLat, final double cosLon, final double lat, final double lon) {
+ this(computeDesiredEllipsoidMagnitude(planetModel, cosLat * cosLon, cosLat * sinLon, sinLat),
+ cosLat * cosLon, cosLat * sinLon, sinLat, lat, lon);
+ }
+
+ /** 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(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), lat, 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.
+ * @param lat is the latitude.
+ * @param lon is the longitude.
+ */
+ public GeoPoint(final double magnitude, final double x, final double y, final double z, double lat, double lon) {
+ super(x * magnitude, y * magnitude, z * magnitude);
+ this.magnitude = magnitude;
+ if (lat > Math.PI * 0.5 || lat < -Math.PI * 0.5) {
+ throw new IllegalArgumentException("Latitude " + lat + " is out of range: must range from -Math.PI/2 to Math.PI/2");
+ }
+ if (lon < -Math.PI || lon > Math.PI) {
+ throw new IllegalArgumentException("Longitude " + lon + " is out of range: must range from -Math.PI to Math.PI");
+ }
+ this.latitude = lat;
+ this.longitude = 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.
+ * Note: this is an angular distance, and not a surface distance, and is therefore independent of planet model.
+ * For surface distance, see {@link PlanetModel#surfaceDistance(GeoPoint, GeoPoint)}
+ * @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 an arc distance between two points.
+ * @param x is the x part of the second point.
+ * @param y is the y part of the second point.
+ * @param z is the z part of the second point.
+ * @return the angle, in radians, between the two points.
+ */
+ public double arcDistance(final double x, final double y, final double z) {
+ return Tools.safeAcos(dotProduct(x,y,z)/(magnitude() * Vector.magnitude(x,y,z)));
+ }
+
+ /** Compute the latitude for the point.
+ * @return the latitude.
+ */
+ public double getLatitude() {
+ double lat = this.latitude;//volatile-read once
+ if (lat == Double.NEGATIVE_INFINITY)
+ this.latitude = lat = Math.asin(z / magnitude());
+ return lat;
+ }
+
+ /** Compute the longitude for the point.
+ * @return the longitude value. Uses 0.0 if there is no computable longitude.
+ */
+ public double getLongitude() {
+ double lon = this.longitude;//volatile-read once
+ if (lon == Double.NEGATIVE_INFINITY) {
+ if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(y) < MINIMUM_RESOLUTION)
+ this.longitude = lon = 0.0;
+ else
+ this.longitude = lon = Math.atan2(y,x);
+ }
+ return lon;
+ }
+
+ /** Compute the linear magnitude of the point.
+ * @return the magnitude.
+ */
+ @Override
+ public double magnitude() {
+ double mag = this.magnitude;//volatile-read once
+ if (mag == Double.NEGATIVE_INFINITY) {
+ this.magnitude = mag = super.magnitude();
+ }
+ return mag;
+ }
+
+ /** Compute whether point matches another.
+ *@param x is the x value
+ *@param y is the y value
+ *@param z is the z value
+ *@return true if the same.
+ */
+ public boolean isIdentical(final double x, final double y, final double z) {
+ return Math.abs(this.x - x) < MINIMUM_RESOLUTION &&
+ Math.abs(this.y - y) < MINIMUM_RESOLUTION &&
+ Math.abs(this.z - z) < MINIMUM_RESOLUTION;
+ }
+
+ @Override
+ public String toString() {
+ if (this.longitude == Double.NEGATIVE_INFINITY) {
+ return super.toString();
+ }
+ return "[lat="+getLatitude()+", lon="+getLongitude()+"]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
new file mode 100644
index 0000000..742bdf8
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygon.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * GeoPolygon interface description.
+ *
+ * @lucene.experimental
+ */
+public interface GeoPolygon extends GeoMembershipShape {
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
new file mode 100755
index 0000000..8ee4290
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * Class which constructs a GeoMembershipShape representing an arbitrary polygon.
+ *
+ * @lucene.experimental
+ */
+public class GeoPolygonFactory {
+ private GeoPolygonFactory() {
+ }
+
+ /**
+ * Create a GeoMembershipShape of the right kind given the specified bounds.
+ *
+ * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of.
+ * @param convexPointIndex is the index of a single convex point whose conformation with
+ * its neighbors determines inside/outside for the entire polygon.
+ * @return a GeoPolygon corresponding to what was specified.
+ */
+ public static GeoPolygon makeGeoPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final int convexPointIndex) {
+ // The basic operation uses a set of points, two points determining one particular edge, and a sided plane
+ // describing membership.
+ return buildPolygonShape(planetModel, pointList, convexPointIndex, getLegalIndex(convexPointIndex + 1, pointList.size()),
+ new SidedPlane(pointList.get(getLegalIndex(convexPointIndex - 1, pointList.size())),
+ pointList.get(convexPointIndex), pointList.get(getLegalIndex(convexPointIndex + 1, pointList.size()))),
+ false);
+ }
+
+ /** Build a GeoMembershipShape given points, starting edge, and whether starting edge is internal or not.
+ * @param pointsList is a list of the GeoPoints to build an arbitrary polygon out of.
+ * @param startPointIndex is one of the points constituting the starting edge.
+ * @param endPointIndex is another of the points constituting the starting edge.
+ * @param startingEdge is the plane describing the starting edge.
+ * @param isInternalEdge is true if the specified edge is an internal one.
+ * @return a GeoMembershipShape corresponding to what was specified.
+ */
+ public static GeoPolygon buildPolygonShape(final PlanetModel planetModel, final List<GeoPoint> pointsList, final int startPointIndex, final int endPointIndex, final SidedPlane startingEdge, final boolean isInternalEdge) {
+ // Algorithm as follows:
+ // Start with sided edge. Go through all points in some order. For each new point, determine if the point is within all edges considered so far.
+ // If not, put it into a list of points for recursion. If it is within, add new edge and keep going.
+ // Once we detect a point that is within, if there are points put aside for recursion, then call recursively.
+
+ // Current composite. This is what we'll actually be returning.
+ final GeoCompositePolygon rval = new GeoCompositePolygon();
+
+ final List<GeoPoint> recursionList = new ArrayList<GeoPoint>();
+ final List<GeoPoint> currentList = new ArrayList<GeoPoint>();
+ final BitSet internalEdgeList = new BitSet();
+ final List<SidedPlane> currentPlanes = new ArrayList<SidedPlane>();
+
+ // Initialize the current list and current planes
+ currentList.add(pointsList.get(startPointIndex));
+ currentList.add(pointsList.get(endPointIndex));
+ internalEdgeList.set(currentPlanes.size(), isInternalEdge);
+ currentPlanes.add(startingEdge);
+
+ // Now, scan all remaining points, in order. We'll use an index and just add to it.
+ for (int i = 0; i < pointsList.size() - 2; i++) {
+ GeoPoint newPoint = pointsList.get(getLegalIndex(i + endPointIndex + 1, pointsList.size()));
+ if (isWithin(newPoint, currentPlanes)) {
+ // Construct a sided plane based on the last two points, and the previous point
+ SidedPlane newBoundary = new SidedPlane(currentList.get(currentList.size() - 2), newPoint, currentList.get(currentList.size() - 1));
+ // Construct a sided plane based on the return trip
+ SidedPlane returnBoundary = new SidedPlane(currentList.get(currentList.size() - 1), currentList.get(0), newPoint);
+ // Verify that none of the points beyond the new point in the list are inside the polygon we'd
+ // be creating if we stopped making the current polygon right now.
+ boolean pointInside = false;
+ for (int j = i + 1; j < pointsList.size() - 2; j++) {
+ GeoPoint checkPoint = pointsList.get(getLegalIndex(j + endPointIndex + 1, pointsList.size()));
+ boolean isInside = true;
+ if (isInside && !newBoundary.isWithin(checkPoint))
+ isInside = false;
+ if (isInside && !returnBoundary.isWithin(checkPoint))
+ isInside = false;
+ if (isInside) {
+ for (SidedPlane plane : currentPlanes) {
+ if (!plane.isWithin(checkPoint)) {
+ isInside = false;
+ break;
+ }
+ }
+ }
+ if (isInside) {
+ pointInside = true;
+ break;
+ }
+ }
+ if (!pointInside) {
+ // Any excluded points?
+ boolean isInternalBoundary = recursionList.size() > 0;
+ if (isInternalBoundary) {
+ // Handle exclusion
+ recursionList.add(newPoint);
+ recursionList.add(currentList.get(currentList.size() - 1));
+ if (recursionList.size() == pointsList.size()) {
+ // We are trying to recurse with a list the same size as the one we started with.
+ // Clearly, the polygon cannot be constructed
+ throw new IllegalArgumentException("Polygon is illegal; cannot be decomposed into convex parts");
+ }
+ // We want the other side for the recursion
+ SidedPlane otherSideNewBoundary = new SidedPlane(newBoundary);
+ rval.addShape(buildPolygonShape(planetModel, recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
+ recursionList.clear();
+ }
+ currentList.add(newPoint);
+ internalEdgeList.set(currentPlanes.size(), isInternalBoundary);
+ currentPlanes.add(newBoundary);
+ } else {
+ recursionList.add(newPoint);
+ }
+ } else {
+ recursionList.add(newPoint);
+ }
+ }
+
+ boolean returnEdgeInternalBoundary = recursionList.size() > 0;
+ if (returnEdgeInternalBoundary) {
+ // The last step back to the start point had a recursion, so take care of that before we complete our work
+ recursionList.add(currentList.get(0));
+ recursionList.add(currentList.get(currentList.size() - 1));
+ if (recursionList.size() == pointsList.size()) {
+ // We are trying to recurse with a list the same size as the one we started with.
+ // Clearly, the polygon cannot be constructed
+ throw new IllegalArgumentException("Polygon is illegal; cannot be decomposed into convex parts");
+ }
+ // Construct a sided plane based on these two points, and the previous point
+ SidedPlane newBoundary = new SidedPlane(currentList.get(currentList.size() - 2), currentList.get(0), currentList.get(currentList.size() - 1));
+ // We want the other side for the recursion
+ SidedPlane otherSideNewBoundary = new SidedPlane(newBoundary);
+ rval.addShape(buildPolygonShape(planetModel, recursionList, recursionList.size() - 2, recursionList.size() - 1, otherSideNewBoundary, true));
+ recursionList.clear();
+ }
+ // Now, add in the current shape.
+ rval.addShape(new GeoConvexPolygon(planetModel, currentList, internalEdgeList, returnEdgeInternalBoundary));
+ //System.out.println("Done creating polygon");
+ return rval;
+ }
+
+ /** Check if a point is within a described list of planes.
+ *@param newPoint is the point.
+ *@param currentPlanes is the list of planes.
+ *@return true if within.
+ */
+ protected static boolean isWithin(final GeoPoint newPoint, final List<SidedPlane> currentPlanes) {
+ for (SidedPlane p : currentPlanes) {
+ if (!p.isWithin(newPoint))
+ return false;
+ }
+ return true;
+ }
+
+ /** Convert raw point index into valid array position.
+ *@param index is the array index.
+ *@param size is the array size.
+ *@return an updated index.
+ */
+ protected static int getLegalIndex(int index, int size) {
+ while (index < 0) {
+ index += size;
+ }
+ while (index >= size) {
+ index -= size;
+ }
+ return index;
+ }
+
+}
[33/50] [abbrv] lucene-solr git commit: LUCENE-7075: remove legacy
numericutils usage from test.
Posted by no...@apache.org.
LUCENE-7075: remove legacy numericutils usage from test.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/4cc9ad44
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/4cc9ad44
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/4cc9ad44
Branch: refs/heads/apiv2
Commit: 4cc9ad44df9ce26aadcb8d9ef739e303d32d6db6
Parents: dd1dd46
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 8 08:40:39 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 8 08:41:24 2016 -0500
----------------------------------------------------------------------
.../lucene/search/join/TestBlockJoin.java | 72 +++++++++++---------
.../java/org/apache/lucene/util/TestUtil.java | 23 -------
2 files changed, 38 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4cc9ad44/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
index a198774..b5f2038 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
@@ -26,8 +26,8 @@ import java.util.Locale;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.Field;
-import org.apache.lucene.document.LegacyIntField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.document.StoredField;
@@ -52,10 +52,8 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.LegacyNumericRangeQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
-import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryUtils;
@@ -73,8 +71,6 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefBuilder;
-import org.apache.lucene.util.LegacyNumericUtils;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
@@ -93,7 +89,7 @@ public class TestBlockJoin extends LuceneTestCase {
private Document makeJob(String skill, int year) {
Document job = new Document();
job.add(newStringField("skill", skill, Field.Store.YES));
- job.add(new LegacyIntField("year", year, Field.Store.NO));
+ job.add(new IntPoint("year", year));
job.add(new StoredField("year", year));
return job;
}
@@ -102,7 +98,7 @@ public class TestBlockJoin extends LuceneTestCase {
private Document makeQualification(String qualification, int year) {
Document job = new Document();
job.add(newStringField("qualification", qualification, Field.Store.YES));
- job.add(new LegacyIntField("year", year, Field.Store.NO));
+ job.add(new IntPoint("year", year));
return job;
}
@@ -135,7 +131,7 @@ public class TestBlockJoin extends LuceneTestCase {
BooleanQuery.Builder childQuery = new BooleanQuery.Builder();
childQuery.add(new BooleanClause(new TermQuery(new Term("skill", "java")), Occur.MUST));
- childQuery.add(new BooleanClause(LegacyNumericRangeQuery.newIntRange("year", 2006, 2011, true, true), Occur.MUST));
+ childQuery.add(new BooleanClause(IntPoint.newRangeQuery("year", 2006, 2011), Occur.MUST));
ToParentBlockJoinQuery childJoinQuery = new ToParentBlockJoinQuery(childQuery.build(), parentsFilter, ScoreMode.Avg);
@@ -189,7 +185,7 @@ public class TestBlockJoin extends LuceneTestCase {
// Define child document criteria (finds an example of relevant work experience)
BooleanQuery.Builder childQuery = new BooleanQuery.Builder();
childQuery.add(new BooleanClause(new TermQuery(new Term("skill", "java")), Occur.MUST));
- childQuery.add(new BooleanClause(LegacyNumericRangeQuery.newIntRange("year", 2006, 2011, true, true), Occur.MUST));
+ childQuery.add(new BooleanClause(IntPoint.newRangeQuery("year", 2006, 2011), Occur.MUST));
// Define parent document criteria (find a resident in the UK)
Query parentQuery = new TermQuery(new Term("country", "United Kingdom"));
@@ -269,23 +265,30 @@ public class TestBlockJoin extends LuceneTestCase {
w.close();
IndexSearcher s = newSearcher(r);
- MultiTermQuery qc = LegacyNumericRangeQuery.newIntRange("year", 2007, 2007, true, true);
// Hacky: this causes the query to need 2 rewrite
// iterations:
- qc.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_REWRITE);
+ BooleanQuery.Builder builder = new BooleanQuery.Builder();
+ builder.add(IntPoint.newExactQuery("year", 2007), BooleanClause.Occur.MUST);
+ Query qc = new Query() {
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException {
+ return builder.build();
+ }
+
+ @Override
+ public String toString(String field) {
+ return "hack!";
+ }
+ };
BitSetProducer parentsFilter = new QueryBitSetProducer(new TermQuery(new Term("docType", "resume")));
CheckJoinIndex.check(r, parentsFilter);
- int h1 = qc.hashCode();
Query qw1 = qc.rewrite(r);
- int h2 = qw1.hashCode();
Query qw2 = qw1.rewrite(r);
- int h3 = qw2.hashCode();
- assertTrue(h1 != h2);
- assertTrue(h2 != h3);
- assertTrue(h3 != h1);
+ assertNotSame(qc, qw1);
+ assertNotSame(qw1, qw2);
ToParentBlockJoinQuery qp = new ToParentBlockJoinQuery(qc, parentsFilter, ScoreMode.Max);
ToParentBlockJoinCollector c = new ToParentBlockJoinCollector(Sort.RELEVANCE, 10, true, true);
@@ -342,7 +345,7 @@ public class TestBlockJoin extends LuceneTestCase {
// Define child document criteria (finds an example of relevant work experience)
BooleanQuery.Builder childQuery = new BooleanQuery.Builder();
childQuery.add(new BooleanClause(new TermQuery(new Term("skill", "java")), Occur.MUST));
- childQuery.add(new BooleanClause(LegacyNumericRangeQuery.newIntRange("year", 2006, 2011, true, true), Occur.MUST));
+ childQuery.add(new BooleanClause(IntPoint.newRangeQuery("year", 2006, 2011), Occur.MUST));
// Define parent document criteria (find a resident in the UK)
Query parentQuery = new TermQuery(new Term("country", "United Kingdom"));
@@ -516,7 +519,7 @@ public class TestBlockJoin extends LuceneTestCase {
for(int parentDocID=0;parentDocID<numParentDocs;parentDocID++) {
Document parentDoc = new Document();
Document parentJoinDoc = new Document();
- Field id = new LegacyIntField("parentID", parentDocID, Field.Store.YES);
+ Field id = new StoredField("parentID", parentDocID);
parentDoc.add(id);
parentJoinDoc.add(id);
parentJoinDoc.add(newStringField("isParent", "x", Field.Store.NO));
@@ -538,8 +541,8 @@ public class TestBlockJoin extends LuceneTestCase {
}
if (doDeletes) {
- parentDoc.add(new LegacyIntField("blockID", parentDocID, Field.Store.NO));
- parentJoinDoc.add(new LegacyIntField("blockID", parentDocID, Field.Store.NO));
+ parentDoc.add(new IntPoint("blockID", parentDocID));
+ parentJoinDoc.add(new IntPoint("blockID", parentDocID));
}
final List<Document> joinDocs = new ArrayList<>();
@@ -563,7 +566,7 @@ public class TestBlockJoin extends LuceneTestCase {
Document joinChildDoc = new Document();
joinDocs.add(joinChildDoc);
- Field childID = new LegacyIntField("childID", childDocID, Field.Store.YES);
+ Field childID = new StoredField("childID", childDocID);
childDoc.add(childID);
joinChildDoc.add(childID);
childID = new NumericDocValuesField("childID", childDocID);
@@ -596,7 +599,7 @@ public class TestBlockJoin extends LuceneTestCase {
}
if (doDeletes) {
- joinChildDoc.add(new LegacyIntField("blockID", parentDocID, Field.Store.NO));
+ joinChildDoc.add(new IntPoint("blockID", parentDocID));
}
w.addDocument(childDoc);
@@ -611,14 +614,15 @@ public class TestBlockJoin extends LuceneTestCase {
}
}
- BytesRefBuilder term = new BytesRefBuilder();
- for(int deleteID : toDelete) {
- if (VERBOSE) {
- System.out.println("DELETE parentID=" + deleteID);
+ if (!toDelete.isEmpty()) {
+ // TODO: we should add newSetQuery(String, Collection<T>) ? this is awkward.
+ int[] array = new int[toDelete.size()];
+ for (int i = 0; i < toDelete.size(); i++) {
+ array[i] = toDelete.get(i);
}
- LegacyNumericUtils.intToPrefixCoded(deleteID, 0, term);
- w.deleteDocuments(new Term("blockID", term.toBytesRef()));
- joinW.deleteDocuments(new Term("blockID", term.toBytesRef()));
+ Query query = IntPoint.newSetQuery("blockID", array);
+ w.deleteDocuments(query);
+ joinW.deleteDocuments(query);
}
final IndexReader r = w.getReader();
@@ -1061,11 +1065,11 @@ public class TestBlockJoin extends LuceneTestCase {
// Define child document criteria (finds an example of relevant work experience)
BooleanQuery.Builder childJobQuery = new BooleanQuery.Builder();
childJobQuery.add(new BooleanClause(new TermQuery(new Term("skill", "java")), Occur.MUST));
- childJobQuery.add(new BooleanClause(LegacyNumericRangeQuery.newIntRange("year", 2006, 2011, true, true), Occur.MUST));
+ childJobQuery.add(new BooleanClause(IntPoint.newRangeQuery("year", 2006, 2011), Occur.MUST));
BooleanQuery.Builder childQualificationQuery = new BooleanQuery.Builder();
childQualificationQuery.add(new BooleanClause(new TermQuery(new Term("qualification", "maths")), Occur.MUST));
- childQualificationQuery.add(new BooleanClause(LegacyNumericRangeQuery.newIntRange("year", 1980, 2000, true, true), Occur.MUST));
+ childQualificationQuery.add(new BooleanClause(IntPoint.newRangeQuery("year", 1980, 2000), Occur.MUST));
// Define parent document criteria (find a resident in the UK)
@@ -1210,7 +1214,7 @@ public class TestBlockJoin extends LuceneTestCase {
// Define child document criteria (finds an example of relevant work experience)
BooleanQuery.Builder childQuery = new BooleanQuery.Builder();
childQuery.add(new BooleanClause(new TermQuery(new Term("skill", "java")), Occur.MUST));
- childQuery.add(new BooleanClause(LegacyNumericRangeQuery.newIntRange("year", 2006, 2011, true, true), Occur.MUST));
+ childQuery.add(new BooleanClause(IntPoint.newRangeQuery("year", 2006, 2011), Occur.MUST));
// Wrap the child document query to 'join' any matches
// up to corresponding parent:
@@ -1707,7 +1711,7 @@ public class TestBlockJoin extends LuceneTestCase {
Query resumeQuery = new ToChildBlockJoinQuery(new TermQuery(new Term("country","rv" + qrv)),
resumeFilter);
- Query jobQuery = new ToChildBlockJoinQuery(LegacyNumericRangeQuery.newIntRange("year", qjv, qjv, true, true),
+ Query jobQuery = new ToChildBlockJoinQuery(IntPoint.newRangeQuery("year", qjv, qjv),
jobFilter);
BooleanQuery.Builder fullQuery = new BooleanQuery.Builder();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4cc9ad44/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
index 50692e8..5e328ba 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/TestUtil.java
@@ -61,11 +61,6 @@ import org.apache.lucene.document.BinaryDocValuesField;
import org.apache.lucene.document.BinaryPoint;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType.LegacyNumericType;
-import org.apache.lucene.document.LegacyDoubleField;
-import org.apache.lucene.document.LegacyFloatField;
-import org.apache.lucene.document.LegacyIntField;
-import org.apache.lucene.document.LegacyLongField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.index.CheckIndex;
@@ -1072,7 +1067,6 @@ public final class TestUtil {
final Field field2;
final DocValuesType dvType = field1.fieldType().docValuesType();
final int dimCount = field1.fieldType().pointDimensionCount();
- final LegacyNumericType numType = field1.fieldType().numericType();
if (dvType != DocValuesType.NONE) {
switch(dvType) {
case NUMERIC:
@@ -1092,23 +1086,6 @@ public final class TestUtil {
byte[] bytes = new byte[br.length];
System.arraycopy(br.bytes, br.offset, bytes, 0, br.length);
field2 = new BinaryPoint(field1.name(), bytes, field1.fieldType());
- } else if (numType != null) {
- switch (numType) {
- case INT:
- field2 = new LegacyIntField(field1.name(), field1.numericValue().intValue(), field1.fieldType());
- break;
- case FLOAT:
- field2 = new LegacyFloatField(field1.name(), field1.numericValue().intValue(), field1.fieldType());
- break;
- case LONG:
- field2 = new LegacyLongField(field1.name(), field1.numericValue().intValue(), field1.fieldType());
- break;
- case DOUBLE:
- field2 = new LegacyDoubleField(field1.name(), field1.numericValue().intValue(), field1.fieldType());
- break;
- default:
- throw new IllegalStateException("unknown Type: " + numType);
- }
} else {
field2 = new Field(field1.name(), field1.stringValue(), field1.fieldType());
}
[19/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearDistance.java
deleted file mode 100644
index 9cbedba..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearDistance.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Linear distance computation style.
- *
- * @lucene.experimental
- */
-public class LinearDistance implements DistanceStyle {
-
- /** A convenient instance */
- public final static LinearDistance INSTANCE = new LinearDistance();
-
- /** Constructor.
- */
- public LinearDistance() {
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
- return point1.linearDistance(point2);
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
- return point1.linearDistance(x2,y2,z2);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
- return plane.linearDistance(planetModel, point, bounds);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
- return plane.linearDistance(planetModel, x,y,z, bounds);
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearSquaredDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearSquaredDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearSquaredDistance.java
deleted file mode 100644
index 028d3c4..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/LinearSquaredDistance.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Linear squared distance computation style.
- *
- * @lucene.experimental
- */
-public class LinearSquaredDistance implements DistanceStyle {
-
- /** A convenient instance */
- public final static LinearSquaredDistance INSTANCE = new LinearSquaredDistance();
-
- /** Constructor.
- */
- public LinearSquaredDistance() {
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
- return point1.linearDistanceSquared(point2);
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
- return point1.linearDistanceSquared(x2,y2,z2);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
- return plane.linearDistanceSquared(planetModel, point, bounds);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
- return plane.linearDistanceSquared(planetModel, x,y,z, bounds);
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Membership.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Membership.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Membership.java
deleted file mode 100755
index 3ca6b09..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Membership.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Implemented by Geo3D shapes that can calculate if a point is within it or not.
- *
- * @lucene.experimental
- */
-public interface Membership {
-
- /**
- * Check if a point is within this shape.
- *
- * @param point is the point to check.
- * @return true if the point is within this shape
- */
- public default boolean isWithin(final Vector point) {
- return isWithin(point.x, point.y, point.z);
- }
-
- /**
- * Check if a point is within this shape.
- *
- * @param x is x coordinate of point to check.
- * @param y is y coordinate of point to check.
- * @param z is z coordinate of point to check.
- * @return true if the point is within this shape
- */
- public boolean isWithin(final double x, final double y, final double z);
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalDistance.java
deleted file mode 100644
index cdac0d2..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalDistance.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Normal distance computation style.
- *
- * @lucene.experimental
- */
-public class NormalDistance implements DistanceStyle {
-
- /** A convenient instance */
- public final static NormalDistance INSTANCE = new NormalDistance();
-
- /** Constructor.
- */
- public NormalDistance() {
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
- return point1.normalDistance(point2);
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
- return point1.normalDistance(x2,y2,z2);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
- return plane.normalDistance(point, bounds);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
- return plane.normalDistance(x,y,z, bounds);
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalSquaredDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalSquaredDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalSquaredDistance.java
deleted file mode 100644
index 035fd40..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/NormalSquaredDistance.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Normal squared distance computation style.
- *
- * @lucene.experimental
- */
-public class NormalSquaredDistance implements DistanceStyle {
-
- /** A convenient instance */
- public final static NormalSquaredDistance INSTANCE = new NormalSquaredDistance();
-
- /** Constructor.
- */
- public NormalSquaredDistance() {
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
- return point1.normalDistanceSquared(point2);
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
- return point1.normalDistanceSquared(x2,y2,z2);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
- return plane.normalDistanceSquared(point, bounds);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
- return plane.normalDistanceSquared(x,y,z, bounds);
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Plane.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Plane.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Plane.java
deleted file mode 100755
index 07d0c5b..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Plane.java
+++ /dev/null
@@ -1,1657 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * We know about three kinds of planes. First kind: general plain through two points and origin
- * Second kind: horizontal plane at specified height. Third kind: vertical plane with specified x and y value, through origin.
- *
- * @lucene.experimental
- */
-public class Plane extends Vector {
- /** An array with no points in it */
- protected final static GeoPoint[] NO_POINTS = new GeoPoint[0];
- /** An array with no bounds in it */
- protected final static Membership[] NO_BOUNDS = new Membership[0];
- /** A vertical plane normal to the Y axis */
- protected final static Plane normalYPlane = new Plane(0.0,1.0,0.0,0.0);
- /** A vertical plane normal to the X axis */
- protected final static Plane normalXPlane = new Plane(1.0,0.0,0.0,0.0);
- /** A vertical plane normal to the Z axis */
- protected final static Plane normalZPlane = new Plane(0.0,0.0,1.0,0.0);
-
- /** Ax + By + Cz + D = 0 */
- public final double D;
-
- /**
- * Construct a plane with all four coefficients defined.
- *@param A is A
- *@param B is B
- *@param C is C
- *@param D is D
- */
- public Plane(final double A, final double B, final double C, final double D) {
- super(A, B, C);
- this.D = D;
- }
-
- /**
- * Construct a plane through two points and origin.
- *
- * @param A is the first point (origin based).
- * @param B is the second point (origin based).
- */
- public Plane(final Vector A, final Vector B) {
- super(A, B);
- D = 0.0;
- }
-
- /**
- * Construct a horizontal plane at a specified Z.
- *
- * @param planetModel is the planet model.
- * @param sinLat is the sin(latitude).
- */
- public Plane(final PlanetModel planetModel, final double sinLat) {
- super(0.0, 0.0, 1.0);
- D = -sinLat * computeDesiredEllipsoidMagnitude(planetModel, sinLat);
- }
-
- /**
- * Construct a vertical plane through a specified
- * x, y and origin.
- *
- * @param x is the specified x value.
- * @param y is the specified y value.
- */
- public Plane(final double x, final double y) {
- super(y, -x, 0.0);
- D = 0.0;
- }
-
- /**
- * Construct a plane with a specific vector, and D offset
- * from origin.
- * @param v is the normal vector.
- * @param D is the D offset from the origin.
- */
- public Plane(final Vector v, final double D) {
- super(v.x, v.y, v.z);
- this.D = D;
- }
-
- /** Construct the most accurate normalized plane through an x-y point and including the Z axis.
- * If none of the points can determine the plane, return null.
- * @param planePoints is a set of points to choose from. The best one for constructing the most precise plane is picked.
- * @return the plane
- */
- public static Plane constructNormalizedZPlane(final Vector... planePoints) {
- // Pick the best one (with the greatest x-y distance)
- double bestDistance = 0.0;
- Vector bestPoint = null;
- for (final Vector point : planePoints) {
- final double pointDist = point.x * point.x + point.y * point.y;
- if (pointDist > bestDistance) {
- bestDistance = pointDist;
- bestPoint = point;
- }
- }
- return constructNormalizedZPlane(bestPoint.x, bestPoint.y);
- }
-
- /** Construct the most accurate normalized plane through an x-z point and including the Y axis.
- * If none of the points can determine the plane, return null.
- * @param planePoints is a set of points to choose from. The best one for constructing the most precise plane is picked.
- * @return the plane
- */
- public static Plane constructNormalizedYPlane(final Vector... planePoints) {
- // Pick the best one (with the greatest x-z distance)
- double bestDistance = 0.0;
- Vector bestPoint = null;
- for (final Vector point : planePoints) {
- final double pointDist = point.x * point.x + point.z * point.z;
- if (pointDist > bestDistance) {
- bestDistance = pointDist;
- bestPoint = point;
- }
- }
- return constructNormalizedYPlane(bestPoint.x, bestPoint.z, 0.0);
- }
-
- /** Construct the most accurate normalized plane through an y-z point and including the X axis.
- * If none of the points can determine the plane, return null.
- * @param planePoints is a set of points to choose from. The best one for constructing the most precise plane is picked.
- * @return the plane
- */
- public static Plane constructNormalizedXPlane(final Vector... planePoints) {
- // Pick the best one (with the greatest y-z distance)
- double bestDistance = 0.0;
- Vector bestPoint = null;
- for (final Vector point : planePoints) {
- final double pointDist = point.y * point.y + point.z * point.z;
- if (pointDist > bestDistance) {
- bestDistance = pointDist;
- bestPoint = point;
- }
- }
- return constructNormalizedXPlane(bestPoint.y, bestPoint.z, 0.0);
- }
-
- /** Construct a normalized plane through an x-y point and including the Z axis.
- * If the x-y point is at (0,0), return null.
- * @param x is the x value.
- * @param y is the y value.
- * @return a plane passing through the Z axis and (x,y,0).
- */
- public static Plane constructNormalizedZPlane(final double x, final double y) {
- if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(y) < MINIMUM_RESOLUTION)
- return null;
- final double denom = 1.0 / Math.sqrt(x*x + y*y);
- return new Plane(y * denom, -x * denom, 0.0, 0.0);
- }
-
- /** Construct a normalized plane through an x-z point and parallel to the Y axis.
- * If the x-z point is at (0,0), return null.
- * @param x is the x value.
- * @param z is the z value.
- * @param DValue is the offset from the origin for the plane.
- * @return a plane parallel to the Y axis and perpendicular to the x and z values given.
- */
- public static Plane constructNormalizedYPlane(final double x, final double z, final double DValue) {
- if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(z) < MINIMUM_RESOLUTION)
- return null;
- final double denom = 1.0 / Math.sqrt(x*x + z*z);
- return new Plane(z * denom, 0.0, -x * denom, DValue);
- }
-
- /** Construct a normalized plane through a y-z point and parallel to the X axis.
- * If the y-z point is at (0,0), return null.
- * @param y is the y value.
- * @param z is the z value.
- * @param DValue is the offset from the origin for the plane.
- * @return a plane parallel to the X axis and perpendicular to the y and z values given.
- */
- public static Plane constructNormalizedXPlane(final double y, final double z, final double DValue) {
- if (Math.abs(y) < MINIMUM_RESOLUTION && Math.abs(z) < MINIMUM_RESOLUTION)
- return null;
- final double denom = 1.0 / Math.sqrt(y*y + z*z);
- return new Plane(0.0, z * denom, -y * denom, DValue);
- }
-
- /**
- * Evaluate the plane equation for a given point, as represented
- * by a vector.
- *
- * @param v is the vector.
- * @return the result of the evaluation.
- */
- public double evaluate(final Vector v) {
- return dotProduct(v) + D;
- }
-
- /**
- * Evaluate the plane equation for a given point, as represented
- * by a vector.
- * @param x is the x value.
- * @param y is the y value.
- * @param z is the z value.
- * @return the result of the evaluation.
- */
- public double evaluate(final double x, final double y, final double z) {
- return dotProduct(x, y, z) + D;
- }
-
- /**
- * Evaluate the plane equation for a given point, as represented
- * by a vector.
- *
- * @param v is the vector.
- * @return true if the result is on the plane.
- */
- public boolean evaluateIsZero(final Vector v) {
- return Math.abs(evaluate(v)) < MINIMUM_RESOLUTION;
- }
-
- /**
- * Evaluate the plane equation for a given point, as represented
- * by a vector.
- *
- * @param x is the x value.
- * @param y is the y value.
- * @param z is the z value.
- * @return true if the result is on the plane.
- */
- public boolean evaluateIsZero(final double x, final double y, final double z) {
- return Math.abs(evaluate(x, y, z)) < MINIMUM_RESOLUTION;
- }
-
- /**
- * Build a normalized plane, so that the vector is normalized.
- *
- * @return the normalized plane object, or null if the plane is indeterminate.
- */
- public Plane normalize() {
- Vector normVect = super.normalize();
- if (normVect == null)
- return null;
- return new Plane(normVect, this.D);
- }
-
- /** Compute arc distance from plane to a vector expressed with a {@link GeoPoint}.
- * @see #arcDistance(PlanetModel, double, double, double, Membership...) */
- public double arcDistance(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
- return arcDistance(planetModel, v.x, v.y, v.z, bounds);
- }
-
- /**
- * Compute arc distance from plane to a vector.
- * @param planetModel is the planet model.
- * @param x is the x vector value.
- * @param y is the y vector value.
- * @param z is the z vector value.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the arc distance.
- */
- public double arcDistance(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
-
- if (evaluateIsZero(x,y,z)) {
- if (meetsAllBounds(x,y,z, bounds))
- return 0.0;
- return Double.MAX_VALUE;
- }
-
- // First, compute the perpendicular plane.
- final Plane perpPlane = new Plane(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x, 0.0);
-
- // We need to compute the intersection of two planes on the geo surface: this one, and its perpendicular.
- // Then, we need to choose which of the two points we want to compute the distance to. We pick the
- // shorter distance always.
-
- final GeoPoint[] intersectionPoints = findIntersections(planetModel, perpPlane);
-
- // For each point, compute a linear distance, and take the minimum of them
- double minDistance = Double.MAX_VALUE;
-
- for (final GeoPoint intersectionPoint : intersectionPoints) {
- if (meetsAllBounds(intersectionPoint, bounds)) {
- final double theDistance = intersectionPoint.arcDistance(x,y,z);
- if (theDistance < minDistance) {
- minDistance = theDistance;
- }
- }
- }
- return minDistance;
-
- }
-
- /**
- * Compute normal distance from plane to a vector.
- * @param v is the vector.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the normal distance.
- */
- public double normalDistance(final Vector v, final Membership... bounds) {
- return normalDistance(v.x, v.y, v.z, bounds);
- }
-
- /**
- * Compute normal distance from plane to a vector.
- * @param x is the vector x.
- * @param y is the vector y.
- * @param z is the vector z.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the normal distance.
- */
- public double normalDistance(final double x, final double y, final double z, final Membership... bounds) {
-
- final double dist = evaluate(x,y,z);
- final double perpX = x - dist * this.x;
- final double perpY = y - dist * this.y;
- final double perpZ = z - dist * this.z;
-
- if (!meetsAllBounds(perpX, perpY, perpZ, bounds)) {
- return Double.MAX_VALUE;
- }
-
- return Math.abs(dist);
- }
-
- /**
- * Compute normal distance squared from plane to a vector.
- * @param v is the vector.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the normal distance squared.
- */
- public double normalDistanceSquared(final Vector v, final Membership... bounds) {
- return normalDistanceSquared(v.x, v.y, v.z, bounds);
- }
-
- /**
- * Compute normal distance squared from plane to a vector.
- * @param x is the vector x.
- * @param y is the vector y.
- * @param z is the vector z.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the normal distance squared.
- */
- public double normalDistanceSquared(final double x, final double y, final double z, final Membership... bounds) {
- final double normal = normalDistance(x,y,z,bounds);
- if (normal == Double.MAX_VALUE)
- return normal;
- return normal * normal;
- }
-
- /**
- * Compute linear distance from plane to a vector. This is defined
- * as the distance from the given point to the nearest intersection of
- * this plane with the planet surface.
- * @param planetModel is the planet model.
- * @param v is the point.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the linear distance.
- */
- public double linearDistance(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
- return linearDistance(planetModel, v.x, v.y, v.z, bounds);
- }
-
- /**
- * Compute linear distance from plane to a vector. This is defined
- * as the distance from the given point to the nearest intersection of
- * this plane with the planet surface.
- * @param planetModel is the planet model.
- * @param x is the vector x.
- * @param y is the vector y.
- * @param z is the vector z.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the linear distance.
- */
- public double linearDistance(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
- if (evaluateIsZero(x,y,z)) {
- if (meetsAllBounds(x,y,z, bounds))
- return 0.0;
- return Double.MAX_VALUE;
- }
-
- // First, compute the perpendicular plane.
- final Plane perpPlane = new Plane(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x, 0.0);
-
- // We need to compute the intersection of two planes on the geo surface: this one, and its perpendicular.
- // Then, we need to choose which of the two points we want to compute the distance to. We pick the
- // shorter distance always.
-
- final GeoPoint[] intersectionPoints = findIntersections(planetModel, perpPlane);
-
- // For each point, compute a linear distance, and take the minimum of them
- double minDistance = Double.MAX_VALUE;
-
- for (final GeoPoint intersectionPoint : intersectionPoints) {
- if (meetsAllBounds(intersectionPoint, bounds)) {
- final double theDistance = intersectionPoint.linearDistance(x,y,z);
- if (theDistance < minDistance) {
- minDistance = theDistance;
- }
- }
- }
- return minDistance;
- }
-
- /**
- * Compute linear distance squared from plane to a vector. This is defined
- * as the distance from the given point to the nearest intersection of
- * this plane with the planet surface.
- * @param planetModel is the planet model.
- * @param v is the point.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the linear distance squared.
- */
- public double linearDistanceSquared(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
- return linearDistanceSquared(planetModel, v.x, v.y, v.z, bounds);
- }
-
- /**
- * Compute linear distance squared from plane to a vector. This is defined
- * as the distance from the given point to the nearest intersection of
- * this plane with the planet surface.
- * @param planetModel is the planet model.
- * @param x is the vector x.
- * @param y is the vector y.
- * @param z is the vector z.
- * @param bounds are the bounds which constrain the intersection point.
- * @return the linear distance squared.
- */
- public double linearDistanceSquared(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
- final double linearDistance = linearDistance(planetModel, x, y, z, bounds);
- return linearDistance * linearDistance;
- }
-
- /**
- * Find points on the boundary of the intersection of a plane and the unit sphere,
- * given a starting point, and ending point, and a list of proportions of the arc (e.g. 0.25, 0.5, 0.75).
- * The angle between the starting point and ending point is assumed to be less than pi.
- * @param start is the start point.
- * @param end is the end point.
- * @param proportions is an array of fractional proportions measured between start and end.
- * @return an array of points corresponding to the proportions passed in.
- */
- public GeoPoint[] interpolate(final GeoPoint start, final GeoPoint end, final double[] proportions) {
- // Steps:
- // (1) Translate (x0,y0,z0) of endpoints into origin-centered place:
- // x1 = x0 + D*A
- // y1 = y0 + D*B
- // z1 = z0 + D*C
- // (2) Rotate counterclockwise in x-y:
- // ra = -atan2(B,A)
- // x2 = x1 cos ra - y1 sin ra
- // y2 = x1 sin ra + y1 cos ra
- // z2 = z1
- // Faster:
- // cos ra = A/sqrt(A^2+B^2+C^2)
- // sin ra = -B/sqrt(A^2+B^2+C^2)
- // cos (-ra) = A/sqrt(A^2+B^2+C^2)
- // sin (-ra) = B/sqrt(A^2+B^2+C^2)
- // (3) Rotate clockwise in x-z:
- // ha = pi/2 - asin(C/sqrt(A^2+B^2+C^2))
- // x3 = x2 cos ha - z2 sin ha
- // y3 = y2
- // z3 = x2 sin ha + z2 cos ha
- // At this point, z3 should be zero.
- // Faster:
- // sin(ha) = cos(asin(C/sqrt(A^2+B^2+C^2))) = sqrt(1 - C^2/(A^2+B^2+C^2)) = sqrt(A^2+B^2)/sqrt(A^2+B^2+C^2)
- // cos(ha) = sin(asin(C/sqrt(A^2+B^2+C^2))) = C/sqrt(A^2+B^2+C^2)
- // (4) Compute interpolations by getting longitudes of original points
- // la = atan2(y3,x3)
- // (5) Rotate new points (xN0, yN0, zN0) counter-clockwise in x-z:
- // ha = -(pi - asin(C/sqrt(A^2+B^2+C^2)))
- // xN1 = xN0 cos ha - zN0 sin ha
- // yN1 = yN0
- // zN1 = xN0 sin ha + zN0 cos ha
- // (6) Rotate new points clockwise in x-y:
- // ra = atan2(B,A)
- // xN2 = xN1 cos ra - yN1 sin ra
- // yN2 = xN1 sin ra + yN1 cos ra
- // zN2 = zN1
- // (7) Translate new points:
- // xN3 = xN2 - D*A
- // yN3 = yN2 - D*B
- // zN3 = zN2 - D*C
-
- // First, calculate the angles and their sin/cos values
- double A = x;
- double B = y;
- double C = z;
-
- // Translation amounts
- final double transX = -D * A;
- final double transY = -D * B;
- final double transZ = -D * C;
-
- double cosRA;
- double sinRA;
- double cosHA;
- double sinHA;
-
- double magnitude = magnitude();
- if (magnitude >= MINIMUM_RESOLUTION) {
- final double denom = 1.0 / magnitude;
- A *= denom;
- B *= denom;
- C *= denom;
-
- // cos ra = A/sqrt(A^2+B^2+C^2)
- // sin ra = -B/sqrt(A^2+B^2+C^2)
- // cos (-ra) = A/sqrt(A^2+B^2+C^2)
- // sin (-ra) = B/sqrt(A^2+B^2+C^2)
- final double xyMagnitude = Math.sqrt(A * A + B * B);
- if (xyMagnitude >= MINIMUM_RESOLUTION) {
- final double xyDenom = 1.0 / xyMagnitude;
- cosRA = A * xyDenom;
- sinRA = -B * xyDenom;
- } else {
- cosRA = 1.0;
- sinRA = 0.0;
- }
-
- // sin(ha) = cos(asin(C/sqrt(A^2+B^2+C^2))) = sqrt(1 - C^2/(A^2+B^2+C^2)) = sqrt(A^2+B^2)/sqrt(A^2+B^2+C^2)
- // cos(ha) = sin(asin(C/sqrt(A^2+B^2+C^2))) = C/sqrt(A^2+B^2+C^2)
- sinHA = xyMagnitude;
- cosHA = C;
- } else {
- cosRA = 1.0;
- sinRA = 0.0;
- cosHA = 1.0;
- sinHA = 0.0;
- }
-
- // Forward-translate the start and end points
- final Vector modifiedStart = modify(start, transX, transY, transZ, sinRA, cosRA, sinHA, cosHA);
- final Vector modifiedEnd = modify(end, transX, transY, transZ, sinRA, cosRA, sinHA, cosHA);
- if (Math.abs(modifiedStart.z) >= MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Start point was not on plane: " + modifiedStart.z);
- if (Math.abs(modifiedEnd.z) >= MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("End point was not on plane: " + modifiedEnd.z);
-
- // Compute the angular distance between start and end point
- final double startAngle = Math.atan2(modifiedStart.y, modifiedStart.x);
- final double endAngle = Math.atan2(modifiedEnd.y, modifiedEnd.x);
-
- final double startMagnitude = Math.sqrt(modifiedStart.x * modifiedStart.x + modifiedStart.y * modifiedStart.y);
- double delta;
-
- double newEndAngle = endAngle;
- while (newEndAngle < startAngle) {
- newEndAngle += Math.PI * 2.0;
- }
-
- if (newEndAngle - startAngle <= Math.PI) {
- delta = newEndAngle - startAngle;
- } else {
- double newStartAngle = startAngle;
- while (newStartAngle < endAngle) {
- newStartAngle += Math.PI * 2.0;
- }
- delta = newStartAngle - endAngle;
- }
-
- final GeoPoint[] returnValues = new GeoPoint[proportions.length];
- for (int i = 0; i < returnValues.length; i++) {
- final double newAngle = startAngle + proportions[i] * delta;
- final double sinNewAngle = Math.sin(newAngle);
- final double cosNewAngle = Math.cos(newAngle);
- final Vector newVector = new Vector(cosNewAngle * startMagnitude, sinNewAngle * startMagnitude, 0.0);
- returnValues[i] = reverseModify(newVector, transX, transY, transZ, sinRA, cosRA, sinHA, cosHA);
- }
-
- return returnValues;
- }
-
- /**
- * Modify a point to produce a vector in translated/rotated space.
- * @param start is the start point.
- * @param transX is the translation x value.
- * @param transY is the translation y value.
- * @param transZ is the translation z value.
- * @param sinRA is the sine of the ascension angle.
- * @param cosRA is the cosine of the ascension angle.
- * @param sinHA is the sine of the height angle.
- * @param cosHA is the cosine of the height angle.
- * @return the modified point.
- */
- protected static Vector modify(final GeoPoint start, final double transX, final double transY, final double transZ,
- final double sinRA, final double cosRA, final double sinHA, final double cosHA) {
- return start.translate(transX, transY, transZ).rotateXY(sinRA, cosRA).rotateXZ(sinHA, cosHA);
- }
-
- /**
- * Reverse modify a point to produce a GeoPoint in normal space.
- * @param point is the translated point.
- * @param transX is the translation x value.
- * @param transY is the translation y value.
- * @param transZ is the translation z value.
- * @param sinRA is the sine of the ascension angle.
- * @param cosRA is the cosine of the ascension angle.
- * @param sinHA is the sine of the height angle.
- * @param cosHA is the cosine of the height angle.
- * @return the original point.
- */
- protected static GeoPoint reverseModify(final Vector point, final double transX, final double transY, final double transZ,
- final double sinRA, final double cosRA, final double sinHA, final double cosHA) {
- final Vector result = point.rotateXZ(-sinHA, cosHA).rotateXY(-sinRA, cosRA).translate(-transX, -transY, -transZ);
- return new GeoPoint(result.x, result.y, result.z);
- }
-
- /**
- * Public version of findIntersections.
- * @param planetModel is the planet model.
- * @param q is the plane to intersect with.
- * @param bounds are the bounds to consider to determine legal intersection points.
- * @return the set of legal intersection points.
- */
- public GeoPoint[] findIntersections(final PlanetModel planetModel, final Plane q, final Membership... bounds) {
- if (isNumericallyIdentical(q)) {
- return null;
- }
- return findIntersections(planetModel, q, bounds, NO_BOUNDS);
- }
-
- /**
- * Find the intersection points between two planes, given a set of bounds.
- *
- * @param planetModel is the planet model to use in finding points.
- * @param q is the plane to intersect with.
- * @param bounds is the set of bounds.
- * @param moreBounds is another set of bounds.
- * @return the intersection point(s) on the unit sphere, if there are any.
- */
- protected GeoPoint[] findIntersections(final PlanetModel planetModel, final Plane q, final Membership[] bounds, final Membership[] moreBounds) {
- //System.err.println("Looking for intersection between plane "+this+" and plane "+q+" within bounds");
- // Unnormalized, unchecked...
- final Vector lineVector = new Vector(y * q.z - z * q.y, z * q.x - x * q.z, x * q.y - y * q.x);
- if (Math.abs(lineVector.x) < MINIMUM_RESOLUTION && Math.abs(lineVector.y) < MINIMUM_RESOLUTION && Math.abs(lineVector.z) < MINIMUM_RESOLUTION) {
- // Degenerate case: parallel planes
- //System.err.println(" planes are parallel - no intersection");
- return NO_POINTS;
- }
-
- // The line will have the equation: A t + A0 = x, B t + B0 = y, C t + C0 = z.
- // We have A, B, and C. In order to come up with A0, B0, and C0, we need to find a point that is on both planes.
- // To do this, we find the largest vector value (either x, y, or z), and look for a point that solves both plane equations
- // simultaneous. For example, let's say that the vector is (0.5,0.5,1), and the two plane equations are:
- // 0.7 x + 0.3 y + 0.1 z + 0.0 = 0
- // and
- // 0.9 x - 0.1 y + 0.2 z + 4.0 = 0
- // Then we'd pick z = 0, so the equations to solve for x and y would be:
- // 0.7 x + 0.3y = 0.0
- // 0.9 x - 0.1y = -4.0
- // ... which can readily be solved using standard linear algebra. Generally:
- // Q0 x + R0 y = S0
- // Q1 x + R1 y = S1
- // ... can be solved by Cramer's rule:
- // x = det(S0 R0 / S1 R1) / det(Q0 R0 / Q1 R1)
- // y = det(Q0 S0 / Q1 S1) / det(Q0 R0 / Q1 R1)
- // ... where det( a b / c d ) = ad - bc, so:
- // x = (S0 * R1 - R0 * S1) / (Q0 * R1 - R0 * Q1)
- // y = (Q0 * S1 - S0 * Q1) / (Q0 * R1 - R0 * Q1)
- double x0;
- double y0;
- double z0;
- // We try to maximize the determinant in the denominator
- final double denomYZ = this.y * q.z - this.z * q.y;
- final double denomXZ = this.x * q.z - this.z * q.x;
- final double denomXY = this.x * q.y - this.y * q.x;
- if (Math.abs(denomYZ) >= Math.abs(denomXZ) && Math.abs(denomYZ) >= Math.abs(denomXY)) {
- // X is the biggest, so our point will have x0 = 0.0
- if (Math.abs(denomYZ) < MINIMUM_RESOLUTION_SQUARED) {
- //System.err.println(" Denominator is zero: no intersection");
- return NO_POINTS;
- }
- final double denom = 1.0 / denomYZ;
- x0 = 0.0;
- y0 = (-this.D * q.z - this.z * -q.D) * denom;
- z0 = (this.y * -q.D + this.D * q.y) * denom;
- } else if (Math.abs(denomXZ) >= Math.abs(denomXY) && Math.abs(denomXZ) >= Math.abs(denomYZ)) {
- // Y is the biggest, so y0 = 0.0
- if (Math.abs(denomXZ) < MINIMUM_RESOLUTION_SQUARED) {
- //System.err.println(" Denominator is zero: no intersection");
- return NO_POINTS;
- }
- final double denom = 1.0 / denomXZ;
- x0 = (-this.D * q.z - this.z * -q.D) * denom;
- y0 = 0.0;
- z0 = (this.x * -q.D + this.D * q.x) * denom;
- } else {
- // Z is the biggest, so Z0 = 0.0
- if (Math.abs(denomXY) < MINIMUM_RESOLUTION_SQUARED) {
- //System.err.println(" Denominator is zero: no intersection");
- return NO_POINTS;
- }
- final double denom = 1.0 / denomXY;
- x0 = (-this.D * q.y - this.y * -q.D) * denom;
- y0 = (this.x * -q.D + this.D * q.x) * denom;
- z0 = 0.0;
- }
-
- // Once an intersecting line is determined, the next step is to intersect that line with the ellipsoid, which
- // will yield zero, one, or two points.
- // The ellipsoid equation: 1,0 = x^2/a^2 + y^2/b^2 + z^2/c^2
- // 1.0 = (At+A0)^2/a^2 + (Bt+B0)^2/b^2 + (Ct+C0)^2/c^2
- // A^2 t^2 / a^2 + 2AA0t / a^2 + A0^2 / a^2 + B^2 t^2 / b^2 + 2BB0t / b^2 + B0^2 / b^2 + C^2 t^2 / c^2 + 2CC0t / c^2 + C0^2 / c^2 - 1,0 = 0.0
- // [A^2 / a^2 + B^2 / b^2 + C^2 / c^2] t^2 + [2AA0 / a^2 + 2BB0 / b^2 + 2CC0 / c^2] t + [A0^2 / a^2 + B0^2 / b^2 + C0^2 / c^2 - 1,0] = 0.0
- // Use the quadratic formula to determine t values and candidate point(s)
- final double A = lineVector.x * lineVector.x * planetModel.inverseAbSquared +
- lineVector.y * lineVector.y * planetModel.inverseAbSquared +
- lineVector.z * lineVector.z * planetModel.inverseCSquared;
- final double B = 2.0 * (lineVector.x * x0 * planetModel.inverseAbSquared + lineVector.y * y0 * planetModel.inverseAbSquared + lineVector.z * z0 * planetModel.inverseCSquared);
- final double C = x0 * x0 * planetModel.inverseAbSquared + y0 * y0 * planetModel.inverseAbSquared + z0 * z0 * planetModel.inverseCSquared - 1.0;
-
- final double BsquaredMinus = B * B - 4.0 * A * C;
- if (Math.abs(BsquaredMinus) < MINIMUM_RESOLUTION_SQUARED) {
- //System.err.println(" One point of intersection");
- final double inverse2A = 1.0 / (2.0 * A);
- // One solution only
- final double t = -B * inverse2A;
- GeoPoint point = new GeoPoint(lineVector.x * t + x0, lineVector.y * t + y0, lineVector.z * t + z0);
- //System.err.println(" point: "+point);
- //verifyPoint(planetModel, point, q);
- if (point.isWithin(bounds, moreBounds))
- return new GeoPoint[]{point};
- return NO_POINTS;
- } else if (BsquaredMinus > 0.0) {
- //System.err.println(" Two points of intersection");
- final double inverse2A = 1.0 / (2.0 * A);
- // Two solutions
- final double sqrtTerm = Math.sqrt(BsquaredMinus);
- final double t1 = (-B + sqrtTerm) * inverse2A;
- final double t2 = (-B - sqrtTerm) * inverse2A;
- GeoPoint point1 = new GeoPoint(lineVector.x * t1 + x0, lineVector.y * t1 + y0, lineVector.z * t1 + z0);
- GeoPoint point2 = new GeoPoint(lineVector.x * t2 + x0, lineVector.y * t2 + y0, lineVector.z * t2 + z0);
- //verifyPoint(planetModel, point1, q);
- //verifyPoint(planetModel, point2, q);
- //System.err.println(" "+point1+" and "+point2);
- if (point1.isWithin(bounds, moreBounds)) {
- if (point2.isWithin(bounds, moreBounds))
- return new GeoPoint[]{point1, point2};
- return new GeoPoint[]{point1};
- }
- if (point2.isWithin(bounds, moreBounds))
- return new GeoPoint[]{point2};
- return NO_POINTS;
- } else {
- //System.err.println(" no solutions - no intersection");
- return NO_POINTS;
- }
- }
-
- /*
- protected void verifyPoint(final PlanetModel planetModel, final GeoPoint point, final Plane q) {
- if (!evaluateIsZero(point))
- throw new RuntimeException("Intersection point not on original plane; point="+point+", plane="+this);
- if (!q.evaluateIsZero(point))
- throw new RuntimeException("Intersection point not on intersected plane; point="+point+", plane="+q);
- if (Math.abs(point.x * point.x * planetModel.inverseASquared + point.y * point.y * planetModel.inverseBSquared + point.z * point.z * planetModel.inverseCSquared - 1.0) >= MINIMUM_RESOLUTION)
- throw new RuntimeException("Intersection point not on ellipsoid; point="+point);
- }
- */
-
- /**
- * Accumulate (x,y,z) bounds information for this plane, intersected with the unit sphere.
- * Updates min/max information, using max/min points found
- * within the specified bounds.
- *
- * @param planetModel is the planet model to use in determining bounds.
- * @param boundsInfo is the xyz info to update with additional bounding information.
- * @param bounds are the surfaces delineating what's inside the shape.
- */
- public void recordBounds(final PlanetModel planetModel, final XYZBounds boundsInfo, final Membership... bounds) {
- // Basic plan is to do three intersections of the plane and the planet.
- // For min/max x, we intersect a vertical plane such that y = 0.
- // For min/max y, we intersect a vertical plane such that x = 0.
- // For min/max z, we intersect a vertical plane that is chosen to go through the high point of the arc.
- // For clarity, load local variables with good names
- final double A = this.x;
- final double B = this.y;
- final double C = this.z;
-
- // Do Z. This can be done simply because it is symmetrical.
- if (!boundsInfo.isSmallestMinZ(planetModel) || !boundsInfo.isLargestMaxZ(planetModel)) {
- //System.err.println(" computing Z bound");
- // Compute Z bounds for this arc
- // With ellipsoids, we really have only one viable way to do this computation.
- // Specifically, we compute an appropriate vertical plane, based on the current plane's x-y orientation, and
- // then intersect it with this one and with the ellipsoid. This gives us zero, one, or two points to use
- // as bounds.
- // There is one special case: horizontal circles. These require TWO vertical planes: one for the x, and one for
- // the y, and we use all four resulting points in the bounds computation.
- if ((Math.abs(A) >= MINIMUM_RESOLUTION || Math.abs(B) >= MINIMUM_RESOLUTION)) {
- // NOT a degenerate case
- //System.err.println(" not degenerate");
- final Plane normalizedZPlane = constructNormalizedZPlane(A,B);
- final GeoPoint[] points = findIntersections(planetModel, normalizedZPlane, bounds, NO_BOUNDS);
- for (final GeoPoint point : points) {
- assert planetModel.pointOnSurface(point);
- //System.err.println(" Point = "+point+"; this.evaluate(point)="+this.evaluate(point)+"; normalizedZPlane.evaluate(point)="+normalizedZPlane.evaluate(point));
- addPoint(boundsInfo, bounds, point);
- }
- } else {
- // Since a==b==0, any plane including the Z axis suffices.
- //System.err.println(" Perpendicular to z");
- final GeoPoint[] points = findIntersections(planetModel, normalYPlane, NO_BOUNDS, NO_BOUNDS);
- boundsInfo.addZValue(points[0]);
- }
- }
-
- // First, compute common subexpressions
- final double k = 1.0 / ((x*x + y*y)*planetModel.ab*planetModel.ab + z*z*planetModel.c*planetModel.c);
- final double abSquared = planetModel.ab * planetModel.ab;
- final double cSquared = planetModel.c * planetModel.c;
- final double ASquared = A * A;
- final double BSquared = B * B;
- final double CSquared = C * C;
-
- final double r = 2.0*D*k;
- final double rSquared = r * r;
-
- if (!boundsInfo.isSmallestMinX(planetModel) || !boundsInfo.isLargestMaxX(planetModel)) {
- // For min/max x, we need to use lagrange multipliers.
- //
- // For this, we need grad(F(x,y,z)) = (dF/dx, dF/dy, dF/dz).
- //
- // Minimize and maximize f(x,y,z) = x, with respect to g(x,y,z) = Ax + By + Cz - D and h(x,y,z) = x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1
- //
- // grad(f(x,y,z)) = (1,0,0)
- // grad(g(x,y,z)) = (A,B,C)
- // grad(h(x,y,z)) = (2x/ab^2,2y/ab^2,2z/c^2)
- //
- // Equations we need to simultaneously solve:
- //
- // grad(f(x,y,z)) = l * grad(g(x,y,z)) + m * grad(h(x,y,z))
- // g(x,y,z) = 0
- // h(x,y,z) = 0
- //
- // Equations:
- // 1 = l*A + m*2x/ab^2
- // 0 = l*B + m*2y/ab^2
- // 0 = l*C + m*2z/c^2
- // Ax + By + Cz + D = 0
- // x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1 = 0
- //
- // Solve for x,y,z in terms of (l, m):
- //
- // x = ((1 - l*A) * ab^2 ) / (2 * m)
- // y = (-l*B * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- //
- // Two equations, two unknowns:
- //
- // A * (((1 - l*A) * ab^2 ) / (2 * m)) + B * ((-l*B * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
- //
- // and
- //
- // (((1 - l*A) * ab^2 ) / (2 * m))^2/ab^2 + ((-l*B * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
- //
- // Simple: solve for l and m, then find x from it.
- //
- // (a) Use first equation to find l in terms of m.
- //
- // A * (((1 - l*A) * ab^2 ) / (2 * m)) + B * ((-l*B * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
- // A * ((1 - l*A) * ab^2 ) + B * (-l*B * ab^2) + C * (-l*C * c^2) + D * 2 * m = 0
- // A * ab^2 - l*A^2* ab^2 - B^2 * l * ab^2 - C^2 * l * c^2 + D * 2 * m = 0
- // - l *(A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + (A * ab^2 + D * 2 * m) = 0
- // l = (A * ab^2 + D * 2 * m) / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
- // l = A * ab^2 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + m * 2 * D / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
- //
- // For convenience:
- //
- // k = 1.0 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
- //
- // Then:
- //
- // l = A * ab^2 * k + m * 2 * D * k
- // l = k * (A*ab^2 + m*2*D)
- //
- // For further convenience:
- //
- // q = A*ab^2*k
- // r = 2*D*k
- //
- // l = (r*m + q)
- // l^2 = (r^2 * m^2 + 2*r*m*q + q^2)
- //
- // (b) Simplify the second equation before substitution
- //
- // (((1 - l*A) * ab^2 ) / (2 * m))^2/ab^2 + ((-l*B * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
- // ((1 - l*A) * ab^2 )^2/ab^2 + (-l*B * ab^2)^2/ab^2 + (-l*C * c^2)^2/c^2 = 4 * m^2
- // (1 - l*A)^2 * ab^2 + (-l*B)^2 * ab^2 + (-l*C)^2 * c^2 = 4 * m^2
- // (1 - 2*l*A + l^2*A^2) * ab^2 + l^2*B^2 * ab^2 + l^2*C^2 * c^2 = 4 * m^2
- // ab^2 - 2*A*ab^2*l + A^2*ab^2*l^2 + B^2*ab^2*l^2 + C^2*c^2*l^2 - 4*m^2 = 0
- //
- // (c) Substitute for l, l^2
- //
- // ab^2 - 2*A*ab^2*(r*m + q) + A^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + B^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + C^2*c^2*(r^2 * m^2 + 2*r*m*q + q^2) - 4*m^2 = 0
- // ab^2 - 2*A*ab^2*r*m - 2*A*ab^2*q + A^2*ab^2*r^2*m^2 + 2*A^2*ab^2*r*q*m +
- // A^2*ab^2*q^2 + B^2*ab^2*r^2*m^2 + 2*B^2*ab^2*r*q*m + B^2*ab^2*q^2 + C^2*c^2*r^2*m^2 + 2*C^2*c^2*r*q*m + C^2*c^2*q^2 - 4*m^2 = 0
- //
- // (d) Group
- //
- // m^2 * [A^2*ab^2*r^2 + B^2*ab^2*r^2 + C^2*c^2*r^2 - 4] +
- // m * [- 2*A*ab^2*r + 2*A^2*ab^2*r*q + 2*B^2*ab^2*r*q + 2*C^2*c^2*r*q] +
- // [ab^2 - 2*A*ab^2*q + A^2*ab^2*q^2 + B^2*ab^2*q^2 + C^2*c^2*q^2] = 0
-
- //System.err.println(" computing X bound");
-
- // Useful subexpressions for this bound
- final double q = A*abSquared*k;
- final double qSquared = q * q;
-
- // Quadratic equation
- final double a = ASquared*abSquared*rSquared + BSquared*abSquared*rSquared + CSquared*cSquared*rSquared - 4.0;
- final double b = - 2.0*A*abSquared*r + 2.0*ASquared*abSquared*r*q + 2.0*BSquared*abSquared*r*q + 2.0*CSquared*cSquared*r*q;
- final double c = abSquared - 2.0*A*abSquared*q + ASquared*abSquared*qSquared + BSquared*abSquared*qSquared + CSquared*cSquared*qSquared;
-
- if (Math.abs(a) >= MINIMUM_RESOLUTION_SQUARED) {
- final double sqrtTerm = b*b - 4.0*a*c;
- if (Math.abs(sqrtTerm) < MINIMUM_RESOLUTION_SQUARED) {
- // One solution
- final double m = -b / (2.0 * a);
- final double l = r * m + q;
- // x = ((1 - l*A) * ab^2 ) / (2 * m)
- // y = (-l*B * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- final double denom0 = 0.5 / m;
- final GeoPoint thePoint = new GeoPoint((1.0-l*A) * abSquared * denom0, -l*B * abSquared * denom0, -l*C * cSquared * denom0);
- //Math is not quite accurate enough for this
- //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
- //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
- addPoint(boundsInfo, bounds, thePoint);
- } else if (sqrtTerm > 0.0) {
- // Two solutions
- final double sqrtResult = Math.sqrt(sqrtTerm);
- final double commonDenom = 0.5/a;
- final double m1 = (-b + sqrtResult) * commonDenom;
- assert Math.abs(a * m1 * m1 + b * m1 + c) < MINIMUM_RESOLUTION;
- final double m2 = (-b - sqrtResult) * commonDenom;
- assert Math.abs(a * m2 * m2 + b * m2 + c) < MINIMUM_RESOLUTION;
- final double l1 = r * m1 + q;
- final double l2 = r * m2 + q;
- // x = ((1 - l*A) * ab^2 ) / (2 * m)
- // y = (-l*B * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- final double denom1 = 0.5 / m1;
- final double denom2 = 0.5 / m2;
- final GeoPoint thePoint1 = new GeoPoint((1.0-l1*A) * abSquared * denom1, -l1*B * abSquared * denom1, -l1*C * cSquared * denom1);
- final GeoPoint thePoint2 = new GeoPoint((1.0-l2*A) * abSquared * denom2, -l2*B * abSquared * denom2, -l2*C * cSquared * denom2);
- //Math is not quite accurate enough for this
- //assert planetModel.pointOnSurface(thePoint1): "Point1: "+thePoint1+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint1.x*thePoint1.x*planetModel.inverseAb*planetModel.inverseAb + thePoint1.y*thePoint1.y*planetModel.inverseAb*planetModel.inverseAb + thePoint1.z*thePoint1.z*planetModel.inverseC*planetModel.inverseC);
- //assert planetModel.pointOnSurface(thePoint2): "Point1: "+thePoint2+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint2.x*thePoint2.x*planetModel.inverseAb*planetModel.inverseAb + thePoint2.y*thePoint2.y*planetModel.inverseAb*planetModel.inverseAb + thePoint2.z*thePoint2.z*planetModel.inverseC*planetModel.inverseC);
- //assert evaluateIsZero(thePoint1): "Evaluation of point1: "+evaluate(thePoint1);
- //assert evaluateIsZero(thePoint2): "Evaluation of point2: "+evaluate(thePoint2);
- addPoint(boundsInfo, bounds, thePoint1);
- addPoint(boundsInfo, bounds, thePoint2);
- } else {
- // No solutions
- }
- } else if (Math.abs(b) > MINIMUM_RESOLUTION_SQUARED) {
- //System.err.println("Not x quadratic");
- // a = 0, so m = - c / b
- final double m = -c / b;
- final double l = r * m + q;
- // x = ((1 - l*A) * ab^2 ) / (2 * m)
- // y = (-l*B * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- final double denom0 = 0.5 / m;
- final GeoPoint thePoint = new GeoPoint((1.0-l*A) * abSquared * denom0, -l*B * abSquared * denom0, -l*C * cSquared * denom0);
- //Math is not quite accurate enough for this
- //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
- //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
- addPoint(boundsInfo, bounds, thePoint);
- } else {
- // Something went very wrong; a = b = 0
- }
- }
-
- // Do Y
- if (!boundsInfo.isSmallestMinY(planetModel) || !boundsInfo.isLargestMaxY(planetModel)) {
- // For min/max x, we need to use lagrange multipliers.
- //
- // For this, we need grad(F(x,y,z)) = (dF/dx, dF/dy, dF/dz).
- //
- // Minimize and maximize f(x,y,z) = y, with respect to g(x,y,z) = Ax + By + Cz - D and h(x,y,z) = x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1
- //
- // grad(f(x,y,z)) = (0,1,0)
- // grad(g(x,y,z)) = (A,B,C)
- // grad(h(x,y,z)) = (2x/ab^2,2y/ab^2,2z/c^2)
- //
- // Equations we need to simultaneously solve:
- //
- // grad(f(x,y,z)) = l * grad(g(x,y,z)) + m * grad(h(x,y,z))
- // g(x,y,z) = 0
- // h(x,y,z) = 0
- //
- // Equations:
- // 0 = l*A + m*2x/ab^2
- // 1 = l*B + m*2y/ab^2
- // 0 = l*C + m*2z/c^2
- // Ax + By + Cz + D = 0
- // x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1 = 0
- //
- // Solve for x,y,z in terms of (l, m):
- //
- // x = (-l*A * ab^2 ) / (2 * m)
- // y = ((1 - l*B) * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- //
- // Two equations, two unknowns:
- //
- // A * ((-l*A * ab^2 ) / (2 * m)) + B * (((1 - l*B) * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
- //
- // and
- //
- // ((-l*A * ab^2 ) / (2 * m))^2/ab^2 + (((1 - l*B) * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
- //
- // Simple: solve for l and m, then find y from it.
- //
- // (a) Use first equation to find l in terms of m.
- //
- // A * ((-l*A * ab^2 ) / (2 * m)) + B * (((1 - l*B) * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
- // A * (-l*A * ab^2 ) + B * ((1-l*B) * ab^2) + C * (-l*C * c^2) + D * 2 * m = 0
- // -A^2*l*ab^2 + B*ab^2 - l*B^2*ab^2 - C^2*l*c^2 + D*2*m = 0
- // - l *(A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + (B * ab^2 + D * 2 * m) = 0
- // l = (B * ab^2 + D * 2 * m) / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
- // l = B * ab^2 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + m * 2 * D / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
- //
- // For convenience:
- //
- // k = 1.0 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
- //
- // Then:
- //
- // l = B * ab^2 * k + m * 2 * D * k
- // l = k * (B*ab^2 + m*2*D)
- //
- // For further convenience:
- //
- // q = B*ab^2*k
- // r = 2*D*k
- //
- // l = (r*m + q)
- // l^2 = (r^2 * m^2 + 2*r*m*q + q^2)
- //
- // (b) Simplify the second equation before substitution
- //
- // ((-l*A * ab^2 ) / (2 * m))^2/ab^2 + (((1 - l*B) * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
- // (-l*A * ab^2 )^2/ab^2 + ((1 - l*B) * ab^2)^2/ab^2 + (-l*C * c^2)^2/c^2 = 4 * m^2
- // (-l*A)^2 * ab^2 + (1 - l*B)^2 * ab^2 + (-l*C)^2 * c^2 = 4 * m^2
- // l^2*A^2 * ab^2 + (1 - 2*l*B + l^2*B^2) * ab^2 + l^2*C^2 * c^2 = 4 * m^2
- // A^2*ab^2*l^2 + ab^2 - 2*B*ab^2*l + B^2*ab^2*l^2 + C^2*c^2*l^2 - 4*m^2 = 0
- //
- // (c) Substitute for l, l^2
- //
- // A^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + ab^2 - 2*B*ab^2*(r*m + q) + B^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + C^2*c^2*(r^2 * m^2 + 2*r*m*q + q^2) - 4*m^2 = 0
- // A^2*ab^2*r^2*m^2 + 2*A^2*ab^2*r*q*m + A^2*ab^2*q^2 + ab^2 - 2*B*ab^2*r*m - 2*B*ab^2*q + B^2*ab^2*r^2*m^2 +
- // 2*B^2*ab^2*r*q*m + B^2*ab^2*q^2 + C^2*c^2*r^2*m^2 + 2*C^2*c^2*r*q*m + C^2*c^2*q^2 - 4*m^2 = 0
- //
- // (d) Group
- //
- // m^2 * [A^2*ab^2*r^2 + B^2*ab^2*r^2 + C^2*c^2*r^2 - 4] +
- // m * [2*A^2*ab^2*r*q - 2*B*ab^2*r + 2*B^2*ab^2*r*q + 2*C^2*c^2*r*q] +
- // [A^2*ab^2*q^2 + ab^2 - 2*B*ab^2*q + B^2*ab^2*q^2 + C^2*c^2*q^2] = 0
-
- //System.err.println(" computing Y bound");
-
- // Useful subexpressions for this bound
- final double q = B*abSquared*k;
- final double qSquared = q * q;
-
- // Quadratic equation
- final double a = ASquared*abSquared*rSquared + BSquared*abSquared*rSquared + CSquared*cSquared*rSquared - 4.0;
- final double b = 2.0*ASquared*abSquared*r*q - 2.0*B*abSquared*r + 2.0*BSquared*abSquared*r*q + 2.0*CSquared*cSquared*r*q;
- final double c = ASquared*abSquared*qSquared + abSquared - 2.0*B*abSquared*q + BSquared*abSquared*qSquared + CSquared*cSquared*qSquared;
-
- if (Math.abs(a) >= MINIMUM_RESOLUTION_SQUARED) {
- final double sqrtTerm = b*b - 4.0*a*c;
- if (Math.abs(sqrtTerm) < MINIMUM_RESOLUTION_SQUARED) {
- // One solution
- final double m = -b / (2.0 * a);
- final double l = r * m + q;
- // x = (-l*A * ab^2 ) / (2 * m)
- // y = ((1.0-l*B) * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- final double denom0 = 0.5 / m;
- final GeoPoint thePoint = new GeoPoint(-l*A * abSquared * denom0, (1.0-l*B) * abSquared * denom0, -l*C * cSquared * denom0);
- //Math is not quite accurate enough for this
- //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint1.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
- //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
- addPoint(boundsInfo, bounds, thePoint);
- } else if (sqrtTerm > 0.0) {
- // Two solutions
- final double sqrtResult = Math.sqrt(sqrtTerm);
- final double commonDenom = 0.5/a;
- final double m1 = (-b + sqrtResult) * commonDenom;
- assert Math.abs(a * m1 * m1 + b * m1 + c) < MINIMUM_RESOLUTION;
- final double m2 = (-b - sqrtResult) * commonDenom;
- assert Math.abs(a * m2 * m2 + b * m2 + c) < MINIMUM_RESOLUTION;
- final double l1 = r * m1 + q;
- final double l2 = r * m2 + q;
- // x = (-l*A * ab^2 ) / (2 * m)
- // y = ((1.0-l*B) * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- final double denom1 = 0.5 / m1;
- final double denom2 = 0.5 / m2;
- final GeoPoint thePoint1 = new GeoPoint(-l1*A * abSquared * denom1, (1.0-l1*B) * abSquared * denom1, -l1*C * cSquared * denom1);
- final GeoPoint thePoint2 = new GeoPoint(-l2*A * abSquared * denom2, (1.0-l2*B) * abSquared * denom2, -l2*C * cSquared * denom2);
- //Math is not quite accurate enough for this
- //assert planetModel.pointOnSurface(thePoint1): "Point1: "+thePoint1+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint1.x*thePoint1.x*planetModel.inverseAb*planetModel.inverseAb + thePoint1.y*thePoint1.y*planetModel.inverseAb*planetModel.inverseAb + thePoint1.z*thePoint1.z*planetModel.inverseC*planetModel.inverseC);
- //assert planetModel.pointOnSurface(thePoint2): "Point2: "+thePoint2+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint2.x*thePoint2.x*planetModel.inverseAb*planetModel.inverseAb + thePoint2.y*thePoint2.y*planetModel.inverseAb*planetModel.inverseAb + thePoint2.z*thePoint2.z*planetModel.inverseC*planetModel.inverseC);
- //assert evaluateIsZero(thePoint1): "Evaluation of point1: "+evaluate(thePoint1);
- //assert evaluateIsZero(thePoint2): "Evaluation of point2: "+evaluate(thePoint2);
- addPoint(boundsInfo, bounds, thePoint1);
- addPoint(boundsInfo, bounds, thePoint2);
- } else {
- // No solutions
- }
- } else if (Math.abs(b) > MINIMUM_RESOLUTION_SQUARED) {
- // a = 0, so m = - c / b
- final double m = -c / b;
- final double l = r * m + q;
- // x = ( -l*A * ab^2 ) / (2 * m)
- // y = ((1-l*B) * ab^2) / ( 2 * m)
- // z = (-l*C * c^2)/ (2 * m)
- final double denom0 = 0.5 / m;
- final GeoPoint thePoint = new GeoPoint(-l*A * abSquared * denom0, (1.0-l*B) * abSquared * denom0, -l*C * cSquared * denom0);
- //Math is not quite accurate enough for this
- //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
- // (thePoint.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
- //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
- addPoint(boundsInfo, bounds, thePoint);
- } else {
- // Something went very wrong; a = b = 0
- }
- }
- }
-
- /**
- * Accumulate bounds information for this plane, intersected with the unit sphere.
- * Updates both latitude and longitude information, using max/min points found
- * within the specified bounds.
- *
- * @param planetModel is the planet model to use in determining bounds.
- * @param boundsInfo is the lat/lon info to update with additional bounding information.
- * @param bounds are the surfaces delineating what's inside the shape.
- */
- public void recordBounds(final PlanetModel planetModel, final LatLonBounds boundsInfo, final Membership... bounds) {
- // For clarity, load local variables with good names
- final double A = this.x;
- final double B = this.y;
- final double C = this.z;
-
- // Now compute latitude min/max points
- if (!boundsInfo.checkNoTopLatitudeBound() || !boundsInfo.checkNoBottomLatitudeBound()) {
- //System.err.println("Looking at latitude for plane "+this);
- // With ellipsoids, we really have only one viable way to do this computation.
- // Specifically, we compute an appropriate vertical plane, based on the current plane's x-y orientation, and
- // then intersect it with this one and with the ellipsoid. This gives us zero, one, or two points to use
- // as bounds.
- // There is one special case: horizontal circles. These require TWO vertical planes: one for the x, and one for
- // the y, and we use all four resulting points in the bounds computation.
- if ((Math.abs(A) >= MINIMUM_RESOLUTION || Math.abs(B) >= MINIMUM_RESOLUTION)) {
- // NOT a horizontal circle!
- //System.err.println(" Not a horizontal circle");
- final Plane verticalPlane = constructNormalizedZPlane(A,B);
- final GeoPoint[] points = findIntersections(planetModel, verticalPlane, bounds, NO_BOUNDS);
- for (final GeoPoint point : points) {
- addPoint(boundsInfo, bounds, point);
- }
- } else {
- // Horizontal circle. Since a==b, any vertical plane suffices.
- final GeoPoint[] points = findIntersections(planetModel, normalXPlane, NO_BOUNDS, NO_BOUNDS);
- boundsInfo.addZValue(points[0]);
- }
- //System.err.println("Done latitude bounds");
- }
-
- // First, figure out our longitude bounds, unless we no longer need to consider that
- if (!boundsInfo.checkNoLongitudeBound()) {
- //System.err.println("Computing longitude bounds for "+this);
- //System.out.println("A = "+A+" B = "+B+" C = "+C+" D = "+D);
- // Compute longitude bounds
-
- double a;
- double b;
- double c;
-
- if (Math.abs(C) < MINIMUM_RESOLUTION) {
- // Degenerate; the equation describes a line
- //System.out.println("It's a zero-width ellipse");
- // Ax + By + D = 0
- if (Math.abs(D) >= MINIMUM_RESOLUTION) {
- if (Math.abs(A) > Math.abs(B)) {
- // Use equation suitable for A != 0
- // We need to find the endpoints of the zero-width ellipse.
- // Geometrically, we have a line segment in x-y space. We need to locate the endpoints
- // of that line. But luckily, we know some things: specifically, since it is a
- // degenerate situation in projection, the C value had to have been 0. That
- // means that our line's endpoints will coincide with the projected ellipse. All we
- // need to do then is to find the intersection of the projected ellipse and the line
- // equation:
- //
- // A x + B y + D = 0
- //
- // Since A != 0:
- // x = (-By - D)/A
- //
- // The projected ellipse:
- // x^2/a^2 + y^2/b^2 - 1 = 0
- // Substitute:
- // [(-By-D)/A]^2/a^2 + y^2/b^2 -1 = 0
- // Multiply through by A^2:
- // [-By - D]^2/a^2 + A^2*y^2/b^2 - A^2 = 0
- // Multiply out:
- // B^2*y^2/a^2 + 2BDy/a^2 + D^2/a^2 + A^2*y^2/b^2 - A^2 = 0
- // Group:
- // y^2 * [B^2/a^2 + A^2/b^2] + y [2BD/a^2] + [D^2/a^2-A^2] = 0
-
- a = B * B * planetModel.inverseAbSquared + A * A * planetModel.inverseAbSquared;
- b = 2.0 * B * D * planetModel.inverseAbSquared;
- c = D * D * planetModel.inverseAbSquared - A * A;
-
- double sqrtClause = b * b - 4.0 * a * c;
-
- if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_SQUARED) {
- double y0 = -b / (2.0 * a);
- double x0 = (-D - B * y0) / A;
- double z0 = 0.0;
- addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
- } else if (sqrtClause > 0.0) {
- double sqrtResult = Math.sqrt(sqrtClause);
- double denom = 1.0 / (2.0 * a);
- double Hdenom = 1.0 / A;
-
- double y0a = (-b + sqrtResult) * denom;
- double y0b = (-b - sqrtResult) * denom;
-
- double x0a = (-D - B * y0a) * Hdenom;
- double x0b = (-D - B * y0b) * Hdenom;
-
- double z0a = 0.0;
- double z0b = 0.0;
-
- addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
- addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
- }
-
- } else {
- // Use equation suitable for B != 0
- // Since I != 0, we rewrite:
- // y = (-Ax - D)/B
- a = B * B * planetModel.inverseAbSquared + A * A * planetModel.inverseAbSquared;
- b = 2.0 * A * D * planetModel.inverseAbSquared;
- c = D * D * planetModel.inverseAbSquared - B * B;
-
- double sqrtClause = b * b - 4.0 * a * c;
-
- if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_SQUARED) {
- double x0 = -b / (2.0 * a);
- double y0 = (-D - A * x0) / B;
- double z0 = 0.0;
- addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
- } else if (sqrtClause > 0.0) {
- double sqrtResult = Math.sqrt(sqrtClause);
- double denom = 1.0 / (2.0 * a);
- double Idenom = 1.0 / B;
-
- double x0a = (-b + sqrtResult) * denom;
- double x0b = (-b - sqrtResult) * denom;
- double y0a = (-D - A * x0a) * Idenom;
- double y0b = (-D - A * x0b) * Idenom;
- double z0a = 0.0;
- double z0b = 0.0;
-
- addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
- addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
- }
- }
- }
-
- } else {
- //System.err.println("General longitude bounds...");
-
- // NOTE WELL: The x,y,z values generated here are NOT on the unit sphere.
- // They are for lat/lon calculation purposes only. x-y is meant to be used for longitude determination,
- // and z for latitude, and that's all the values are good for.
-
- // (1) Intersect the plane and the ellipsoid, and project the results into the x-y plane:
- // From plane:
- // z = (-Ax - By - D) / C
- // From ellipsoid:
- // x^2/a^2 + y^2/b^2 + [(-Ax - By - D) / C]^2/c^2 = 1
- // Simplify/expand:
- // C^2*x^2/a^2 + C^2*y^2/b^2 + (-Ax - By - D)^2/c^2 = C^2
- //
- // x^2 * C^2/a^2 + y^2 * C^2/b^2 + x^2 * A^2/c^2 + ABxy/c^2 + ADx/c^2 + ABxy/c^2 + y^2 * B^2/c^2 + BDy/c^2 + ADx/c^2 + BDy/c^2 + D^2/c^2 = C^2
- // Group:
- // [A^2/c^2 + C^2/a^2] x^2 + [B^2/c^2 + C^2/b^2] y^2 + [2AB/c^2]xy + [2AD/c^2]x + [2BD/c^2]y + [D^2/c^2-C^2] = 0
- // For convenience, introduce post-projection coefficient variables to make life easier.
- // E x^2 + F y^2 + G xy + H x + I y + J = 0
- double E = A * A * planetModel.inverseCSquared + C * C * planetModel.inverseAbSquared;
- double F = B * B * planetModel.inverseCSquared + C * C * planetModel.inverseAbSquared;
- double G = 2.0 * A * B * planetModel.inverseCSquared;
- double H = 2.0 * A * D * planetModel.inverseCSquared;
- double I = 2.0 * B * D * planetModel.inverseCSquared;
- double J = D * D * planetModel.inverseCSquared - C * C;
-
- //System.err.println("E = " + E + " F = " + F + " G = " + G + " H = "+ H + " I = " + I + " J = " + J);
-
- // Check if the origin is within, by substituting x = 0, y = 0 and seeing if less than zero
- if (Math.abs(J) >= MINIMUM_RESOLUTION && J > 0.0) {
- // The derivative of the curve above is:
- // 2Exdx + 2Fydy + G(xdy+ydx) + Hdx + Idy = 0
- // (2Ex + Gy + H)dx + (2Fy + Gx + I)dy = 0
- // dy/dx = - (2Ex + Gy + H) / (2Fy + Gx + I)
- //
- // The equation of a line going through the origin with the slope dy/dx is:
- // y = dy/dx x
- // y = - (2Ex + Gy + H) / (2Fy + Gx + I) x
- // Rearrange:
- // (2Fy + Gx + I) y + (2Ex + Gy + H) x = 0
- // 2Fy^2 + Gxy + Iy + 2Ex^2 + Gxy + Hx = 0
- // 2Ex^2 + 2Fy^2 + 2Gxy + Hx + Iy = 0
- //
- // Multiply the original equation by 2:
- // 2E x^2 + 2F y^2 + 2G xy + 2H x + 2I y + 2J = 0
- // Subtract one from the other, to remove the high-order terms:
- // Hx + Iy + 2J = 0
- // Now, we can substitute either x = or y = into the derivative equation, or into the original equation.
- // But we will need to base this on which coefficient is non-zero
-
- if (Math.abs(H) > Math.abs(I)) {
- //System.err.println(" Using the y quadratic");
- // x = (-2J - Iy)/H
-
- // Plug into the original equation:
- // E [(-2J - Iy)/H]^2 + F y^2 + G [(-2J - Iy)/H]y + H [(-2J - Iy)/H] + I y + J = 0
- // E [(-2J - Iy)/H]^2 + F y^2 + G [(-2J - Iy)/H]y - J = 0
- // Same equation as derivative equation, except for a factor of 2! So it doesn't matter which we pick.
-
- // Plug into derivative equation:
- // 2E[(-2J - Iy)/H]^2 + 2Fy^2 + 2G[(-2J - Iy)/H]y + H[(-2J - Iy)/H] + Iy = 0
- // 2E[(-2J - Iy)/H]^2 + 2Fy^2 + 2G[(-2J - Iy)/H]y - 2J = 0
- // E[(-2J - Iy)/H]^2 + Fy^2 + G[(-2J - Iy)/H]y - J = 0
-
- // Multiply by H^2 to make manipulation easier
- // E[(-2J - Iy)]^2 + F*H^2*y^2 + GH[(-2J - Iy)]y - J*H^2 = 0
- // Do the square
- // E[4J^2 + 4IJy + I^2*y^2] + F*H^2*y^2 + GH(-2Jy - I*y^2) - J*H^2 = 0
-
- // Multiply it out
- // 4E*J^2 + 4EIJy + E*I^2*y^2 + H^2*Fy^2 - 2GHJy - GH*I*y^2 - J*H^2 = 0
- // Group:
- // y^2 [E*I^2 - GH*I + F*H^2] + y [4EIJ - 2GHJ] + [4E*J^2 - J*H^2] = 0
-
- a = E * I * I - G * H * I + F * H * H;
- b = 4.0 * E * I * J - 2.0 * G * H * J;
- c = 4.0 * E * J * J - J * H * H;
-
- //System.out.println("a="+a+" b="+b+" c="+c);
- double sqrtClause = b * b - 4.0 * a * c;
- //System.out.println("sqrtClause="+sqrtClause);
-
- if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_CUBED) {
- //System.err.println(" One solution");
- double y0 = -b / (2.0 * a);
- double x0 = (-2.0 * J - I * y0) / H;
- double z0 = (-A * x0 - B * y0 - D) / C;
-
- addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
- } else if (sqrtClause > 0.0) {
- //System.err.println(" Two solutions");
- double sqrtResult = Math.sqrt(sqrtClause);
- double denom = 1.0 / (2.0 * a);
- double Hdenom = 1.0 / H;
- double Cdenom = 1.0 / C;
-
- double y0a = (-b + sqrtResult) * denom;
- double y0b = (-b - sqrtResult) * denom;
- double x0a = (-2.0 * J - I * y0a) * Hdenom;
- double x0b = (-2.0 * J - I * y0b) * Hdenom;
- double z0a = (-A * x0a - B * y0a - D) * Cdenom;
- double z0b = (-A * x0b - B * y0b - D) * Cdenom;
-
- addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
- addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
- }
-
- } else {
- //System.err.println(" Using the x quadratic");
- // y = (-2J - Hx)/I
-
- // Plug into the original equation:
- // E x^2 + F [(-2J - Hx)/I]^2 + G x[(-2J - Hx)/I] - J = 0
-
- // Multiply by I^2 to make manipulation easier
- // E * I^2 * x^2 + F [(-2J - Hx)]^2 + GIx[(-2J - Hx)] - J * I^2 = 0
- // Do the square
- // E * I^2 * x^2 + F [ 4J^2 + 4JHx + H^2*x^2] + GI[(-2Jx - H*x^2)] - J * I^2 = 0
-
- // Multiply it out
- // E * I^2 * x^2 + 4FJ^2 + 4FJHx + F*H^2*x^2 - 2GIJx - HGI*x^2 - J * I^2 = 0
- // Group:
- // x^2 [E*I^2 - GHI + F*H^2] + x [4FJH - 2GIJ] + [4FJ^2 - J*I^2] = 0
-
- // E x^2 + F y^2 + G xy + H x + I y + J = 0
-
- a = E * I * I - G * H * I + F * H * H;
- b = 4.0 * F * H * J - 2.0 * G * I * J;
- c = 4.0 * F * J * J - J * I * I;
-
- //System.out.println("a="+a+" b="+b+" c="+c);
- double sqrtClause = b * b - 4.0 * a * c;
- //System.out.println("sqrtClause="+sqrtClause);
- if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_CUBED) {
- //System.err.println(" One solution; sqrt clause was "+sqrtClause);
- double x0 = -b / (2.0 * a);
- double y0 = (-2.0 * J - H * x0) / I;
- double z0 = (-A * x0 - B * y0 - D) / C;
- // Verify that x&y fulfill the equation
- // 2Ex^2 + 2Fy^2 + 2Gxy + Hx + Iy = 0
- addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
- } else if (sqrtClause > 0.0) {
- //System.err.println(" Two solutions");
- double sqrtResult = Math.sqrt(sqrtClause);
- double denom = 1.0 / (2.0 * a);
- double Idenom = 1.0 / I;
- double Cdenom = 1.0 / C;
-
- double x0a = (-b + sqrtResult) * denom;
- double x0b = (-b - sqrtResult) * denom;
- double y0a = (-2.0 * J - H * x0a) * Idenom;
- double y0b = (-2.0 * J - H * x0b) * Idenom;
- double z0a = (-A * x0a - B * y0a - D) * Cdenom;
- double z0b = (-A * x0b - B * y0b - D) * Cdenom;
-
- addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
- addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
- }
- }
- }
- }
- }
-
- }
-
- /** Add a point to boundsInfo if within a specifically bounded area.
- * @param boundsInfo is the object to be modified.
- * @param bounds is the area that the point must be within.
- * @param point is the point.
- */
- protected static void addPoint(final Bounds boundsInfo, final Membership[] bounds, final GeoPoint point) {
- // Make sure the discovered point is within the bounds
- for (Membership bound : bounds) {
- if (!bound.isWithin(point))
- return;
- }
- // Add the point
- boundsInfo.addPoint(point);
- }
-
- /** Add a point to boundsInfo if within a specifically bounded area.
- * @param boundsInfo is the object to be modified.
- * @param bounds is the area that the point must be within.
- * @param x is the x value.
- * @param y is the y value.
- * @param z is the z value.
- */
- /*
- protected static void addPoint(final Bounds boundsInfo, final Membership[] bounds, final double x, final double y, final double z) {
- //System.err.println(" Want to add point x="+x+" y="+y+" z="+z);
- // Make sure the discovered point is within the bounds
- for (Membership bound : bounds) {
- if (!bound.isWithin(x, y, z))
- return;
- }
- // Add the point
- //System.err.println(" point added");
- //System.out.println("Adding point x="+x+" y="+y+" z="+z);
- boundsInfo.addPoint(x, y, z);
- }
- */
-
- /**
- * Determine whether the plane intersects another plane within the
- * bounds provided.
- *
- * @param planetModel is the planet model to use in determining intersection.
- * @param q is the other plane.
- * @param notablePoints are points to look at to disambiguate cases when the two planes are identical.
- * @param moreNotablePoints are additional points to look at to disambiguate cases when the two planes are identical.
- * @param bounds is one part of the bounds.
- * @param moreBounds are more bounds.
- * @return true if there's an intersection.
- */
- public boolean intersects(final PlanetModel planetModel, final Plane q, final GeoPoint[] notablePoints, final GeoPoint[] moreNotablePoints, final Membership[] bounds, final Membership... moreBounds) {
- //System.err.println("Does plane "+this+" intersect with plane "+q);
- // If the two planes are identical, then the math will find no points of intersection.
- // So a special case of this is to check for plane equality. But that is not enough, because
- // what we really need at that point is to determine whether overlap occurs between the two parts of the intersection
- // of plane and circle. That is, are there *any* points on the plane that are within the bounds described?
- if (isNumericallyIdentical(q)) {
- //System.err.println(" Identical plane");
- // The only way to efficiently figure this out will be to have a list of trial points available to evaluate.
- // We look for any point that fulfills all the bounds.
- for (GeoPoint p : notablePoints) {
- if (meetsAllBounds(p, bounds, moreBounds)) {
- //System.err.println(" found a notable point in bounds, so intersects");
- return true;
- }
- }
- for (GeoPoint p : moreNotablePoints) {
- if (meetsAllBounds(p, bounds, moreBounds)) {
- //System.err.println(" found a notable point in bounds, so intersects");
- return true;
- }
- }
- //System.err.println(" no notable points inside found; no intersection");
- return false;
- }
- return findIntersections(planetModel, q, bounds, moreBounds).length > 0;
- }
-
- /**
- * Returns true if this plane and the other plane are identical within the margin of error.
- * @param p is the plane to compare against.
- * @return true if the planes are numerically identical.
- */
- protected boolean isNumericallyIdentical(final Plane p) {
- // We can get the correlation by just doing a parallel plane check. If that passes, then compute a point on the plane
- // (using D) and see if it also on the other plane.
- if (Math.abs(this.y * p.z - this.z * p.y) >= MINIMUM_RESOLUTION)
- return false;
- if (Math.abs(this.z * p.x - this.x * p.z) >= MINIMUM_RESOLUTION)
- return false;
- if (Math.abs(this.x * p.y - this.y * p.x) >= MINIMUM_RESOLUTION)
- return false;
-
- // Now, see whether the parallel planes are in fact on top of one another.
- // The math:
- // We need a single point that fulfills:
- // Ax + By + Cz + D = 0
- // Pick:
- // x0 = -(A * D) / (A^2 + B^2 + C^2)
- // y0 = -(B * D) / (A^2 + B^2 + C^2)
- // z0 = -(C * D) / (A^2 + B^2 + C^2)
- // Check:
- // A (x0) + B (y0) + C (z0) + D =? 0
- // A (-(A * D) / (A^2 + B^2 + C^2)) + B (-(B * D) / (A^2 + B^2 + C^2)) + C (-(C * D) / (A^2 + B^2 + C^2)) + D ?= 0
- // -D [ A^2 / (A^2 + B^2 + C^2) + B^2 / (A^2 + B^2 + C^2) + C^2 / (A^2 + B^2 + C^2)] + D ?= 0
- // Yes.
- final double denom = 1.0 / (p.x * p.x + p.y * p.y + p.z * p.z);
- return evaluateIsZero(-p.x * p.D * denom, -p.y * p.D * denom, -p.z * p.D * denom);
- }
-
- /**
- * Check if a vector meets the provided bounds.
- * @param p is the vector.
- * @param bounds are the bounds.
- * @return true if the vector describes a point within the bounds.
- */
- protected static boolean meetsAllBounds(final Vector p, final Membership[] bounds) {
- return meetsAllBounds(p.x, p.y, p.z, bounds);
- }
-
- /**
- * Check if a vector meets the provided bounds.
- * @param x is the x value.
- * @param y is the y value.
- * @param z is the z value.
- * @param bounds are the bounds.
- * @return true if the vector describes a point within the bounds.
- */
- protected static boolean meetsAllBounds(final double x, final double y, final double z, final Membership[] bounds) {
- for (final Membership bound : bounds) {
- if (!bound.isWithin(x,y,z))
- return false;
- }
- return true;
- }
-
- /**
- * Check if a vector meets the provided bounds.
- * @param p is the vector.
- * @param bounds are the bounds.
- * @param moreBounds are an additional set of bounds.
- * @return true if the vector describes a point within the bounds.
- */
- protected static boolean meetsAllBounds(final Vector p, final Membership[] bounds, final Membership[] moreBounds) {
- return meetsAllBounds(p.x, p.y, p.z, bounds, moreBounds);
- }
-
- /**
- * Check if a vector meets the provided bounds.
- * @param x is the x value.
- * @param y is the y value.
- * @param z is the z value.
- * @param bounds are the bounds.
- * @param moreBounds are an additional set of bounds.
- * @return true if the vector describes a point within the bounds.
- */
- protected static boolean meetsAllBounds(final double x, final double y, final double z, final Membership[] bounds,
- final Membership[] moreBounds) {
- return meetsAllBounds(x,y,z, bounds) && meetsAllBounds(x,y,z, moreBounds);
- }
-
- /**
- * Find a sample point on the intersection between two planes and the world.
- * @param planetModel is the planet model.
- * @param q is the second plane to consider.
- * @return a sample point that is on the intersection between the two planes and the world.
- */
- public GeoPoint getSampleIntersectionPoint(final PlanetModel planetModel, final Plane q) {
- final GeoPoint[] intersections = findIntersections(planetModel, q, NO_BOUNDS, NO_BOUNDS);
- if (intersections.length == 0)
- return null;
- return intersections[0];
- }
-
- @Override
- public String toString() {
- return "[A=" + x + ", B=" + y + "; C=" + z + "; D=" + D + "]";
- }
-
- @Override
- public boolean equals(Object o) {
- if (!super.equals(o))
- return false;
- if (!(o instanceof Plane))
- return false;
- Plane other = (Plane) o;
- return other.D == D;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp;
- temp = Double.doubleToLongBits(D);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-}
[28/50] [abbrv] lucene-solr git commit: LUCENE-7077: fail precommit
on useless assignment
Posted by no...@apache.org.
LUCENE-7077: fail precommit on useless assignment
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/bfd58bc9
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/bfd58bc9
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/bfd58bc9
Branch: refs/heads/apiv2
Commit: bfd58bc9defc85fd4669885329dbfd259fcc118a
Parents: 5bb072d
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 8 06:42:35 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 8 06:42:35 2016 -0500
----------------------------------------------------------------------
.../src/java/org/apache/lucene/codecs/memory/FSTTermsWriter.java | 2 +-
lucene/tools/javadoc/ecj.javadocs.prefs | 2 +-
.../src/test/org/apache/solr/update/DirectUpdateHandlerTest.java | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bfd58bc9/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsWriter.java
----------------------------------------------------------------------
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsWriter.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsWriter.java
index 50044f1..8284d74 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsWriter.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/FSTTermsWriter.java
@@ -167,7 +167,7 @@ public class FSTTermsWriter extends FieldsConsumer {
FieldInfo fieldInfo = fieldInfos.fieldInfo(field);
boolean hasFreq = fieldInfo.getIndexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) >= 0;
TermsEnum termsEnum = terms.iterator();
- TermsWriter termsWriter = termsWriter = new TermsWriter(fieldInfo);
+ TermsWriter termsWriter = new TermsWriter(fieldInfo);
long sumTotalTermFreq = 0;
long sumDocFreq = 0;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bfd58bc9/lucene/tools/javadoc/ecj.javadocs.prefs
----------------------------------------------------------------------
diff --git a/lucene/tools/javadoc/ecj.javadocs.prefs b/lucene/tools/javadoc/ecj.javadocs.prefs
index 63f22e6..d01148c 100644
--- a/lucene/tools/javadoc/ecj.javadocs.prefs
+++ b/lucene/tools/javadoc/ecj.javadocs.prefs
@@ -51,7 +51,7 @@ org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=ignore
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nullReference=ignore
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bfd58bc9/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
index d35614d..2bde118 100644
--- a/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java
@@ -299,7 +299,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 {
assertU(commit("expungeDeletes","true"));
sr = req("q","foo");
- r = r = sr.getSearcher().getIndexReader();
+ r = sr.getSearcher().getIndexReader();
assertEquals(r.maxDoc(), r.numDocs()); // no deletions
assertEquals(4,r.maxDoc()); // no dups
sr.close();
[48/50] [abbrv] lucene-solr git commit: LUCENE-7080: Sort files to
corrupt to prevent HashSet iteration order issues across JVMs
Posted by no...@apache.org.
LUCENE-7080: Sort files to corrupt to prevent HashSet iteration order issues across JVMs
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/588aeeaa
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/588aeeaa
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/588aeeaa
Branch: refs/heads/apiv2
Commit: 588aeeaab731f34af9063ec0dedb714f8740e0b2
Parents: 12f7ad6
Author: Simon Willnauer <si...@apache.org>
Authored: Wed Mar 9 10:56:13 2016 +0100
Committer: Simon Willnauer <si...@apache.org>
Committed: Wed Mar 9 10:56:13 2016 +0100
----------------------------------------------------------------------
.../java/org/apache/lucene/store/MockDirectoryWrapper.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/588aeeaa/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java b/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java
index 962062e..7fe7c3b 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java
@@ -45,6 +45,7 @@ import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.NoDeletionPolicy;
import org.apache.lucene.index.SegmentInfos;
+import org.apache.lucene.util.CollectionUtil;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
@@ -296,7 +297,11 @@ public class MockDirectoryWrapper extends BaseDirectoryWrapper {
public synchronized void corruptFiles(Collection<String> files) throws IOException {
// Must make a copy because we change the incoming unsyncedFiles
// when we create temp files, delete, etc., below:
- for(String name : new ArrayList<>(files)) {
+ final List<String> filesToCorrupt = new ArrayList<>(files);
+ // sort the files otherwise we have reproducibility issues
+ // across JVMs if the incoming collection is a hashSet etc.
+ CollectionUtil.timSort(filesToCorrupt);
+ for(String name : filesToCorrupt) {
int damage = randomState.nextInt(6);
String action = null;
[11/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SidedPlane.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SidedPlane.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SidedPlane.java
new file mode 100755
index 0000000..e080bc0
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SidedPlane.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Combination of a plane, and a sign value indicating what evaluation values are on the correct
+ * side of the plane.
+ *
+ * @lucene.experimental
+ */
+public class SidedPlane extends Plane implements Membership {
+ /** The sign value for evaluation of a point on the correct side of the plane */
+ public final double sigNum;
+
+ /**
+ * Construct a SidedPlane identical to an existing one, but reversed.
+ *
+ * @param sidedPlane is the existing plane.
+ */
+ public SidedPlane(SidedPlane sidedPlane) {
+ super(sidedPlane, sidedPlane.D);
+ this.sigNum = -sidedPlane.sigNum;
+ }
+
+ /**
+ * Construct a sided plane from a pair of vectors describing points, and including
+ * origin, plus a point p which describes the side.
+ *
+ * @param p point to evaluate
+ * @param A is the first in-plane point
+ * @param B is the second in-plane point
+ */
+ public SidedPlane(Vector p, Vector A, Vector B) {
+ super(A, B);
+ sigNum = Math.signum(evaluate(p));
+ if (sigNum == 0.0)
+ throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
+ }
+
+ /**
+ * Construct a sided plane from a point and a Z coordinate.
+ *
+ * @param p point to evaluate.
+ * @param planetModel is the planet model.
+ * @param sinLat is the sin of the latitude of the plane.
+ */
+ public SidedPlane(Vector p, final PlanetModel planetModel, double sinLat) {
+ super(planetModel, sinLat);
+ sigNum = Math.signum(evaluate(p));
+ if (sigNum == 0.0)
+ throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
+ }
+
+ /**
+ * Construct a sided vertical plane from a point and specified x and y coordinates.
+ *
+ * @param p point to evaluate.
+ * @param x is the specified x.
+ * @param y is the specified y.
+ */
+ public SidedPlane(Vector p, double x, double y) {
+ super(x, y);
+ sigNum = Math.signum(evaluate(p));
+ if (sigNum == 0.0)
+ throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
+ }
+
+ /**
+ * Construct a sided plane with a normal vector and offset.
+ *
+ * @param p point to evaluate.
+ * @param v is the normal vector.
+ * @param D is the origin offset for the plan.
+ */
+ public SidedPlane(Vector p, Vector v, double D) {
+ super(v, D);
+ sigNum = Math.signum(evaluate(p));
+ if (sigNum == 0.0)
+ throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
+ }
+
+ /**
+ * Construct a sided plane with a normal vector and offset.
+ *
+ * @param pX X coord of point to evaluate.
+ * @param pY Y coord of point to evaluate.
+ * @param pZ Z coord of point to evaluate.
+ * @param v is the normal vector.
+ * @param D is the origin offset for the plan.
+ */
+ public SidedPlane(double pX, double pY, double pZ, Vector v, double D) {
+ super(v, D);
+ sigNum = Math.signum(evaluate(pX,pY,pZ));
+ if (sigNum == 0.0)
+ throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
+ }
+
+ /** Construct a sided plane from two points and a third normal vector.
+ */
+ public static SidedPlane constructNormalizedPerpendicularSidedPlane(final Vector insidePoint,
+ final Vector normalVector, final Vector point1, final Vector point2) {
+ final Vector pointsVector = new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z);
+ final Vector newNormalVector = new Vector(normalVector, pointsVector);
+ try {
+ // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
+ return new SidedPlane(insidePoint, newNormalVector, -newNormalVector.dotProduct(point1));
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /** Construct a sided plane from three points.
+ */
+ public static SidedPlane constructNormalizedThreePointSidedPlane(final Vector insidePoint,
+ final Vector point1, final Vector point2, final Vector point3) {
+ try {
+ final Vector planeNormal = new Vector(
+ new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z),
+ new Vector(point2.x - point3.x, point2.y - point3.y, point2.z - point3.z));
+ return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isWithin(double x, double y, double z) {
+ double evalResult = evaluate(x, y, z);
+ if (Math.abs(evalResult) < MINIMUM_RESOLUTION)
+ return true;
+ double sigNum = Math.signum(evalResult);
+ return sigNum == this.sigNum;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SidedPlane)) return false;
+ if (!super.equals(o)) return false;
+
+ SidedPlane that = (SidedPlane) o;
+
+ return Double.compare(that.sigNum, sigNum) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp;
+ temp = Double.doubleToLongBits(sigNum);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "[A=" + x + ", B=" + y + ", C=" + z + ", D=" + D + ", side=" + sigNum + "]";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardXYZSolid.java
new file mode 100644
index 0000000..492f7b4
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardXYZSolid.java
@@ -0,0 +1,417 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits
+ *
+ * @lucene.internal
+ */
+public class StandardXYZSolid extends BaseXYZSolid {
+
+ /** Whole world? */
+ protected final boolean isWholeWorld;
+ /** Min-X plane */
+ protected final SidedPlane minXPlane;
+ /** Max-X plane */
+ protected final SidedPlane maxXPlane;
+ /** Min-Y plane */
+ protected final SidedPlane minYPlane;
+ /** Max-Y plane */
+ protected final SidedPlane maxYPlane;
+ /** Min-Z plane */
+ protected final SidedPlane minZPlane;
+ /** Max-Z plane */
+ protected final SidedPlane maxZPlane;
+
+ /** These are the edge points of the shape, which are defined to be at least one point on
+ * each surface area boundary. In the case of a solid, this includes points which represent
+ * the intersection of XYZ bounding planes and the planet, as well as points representing
+ * the intersection of single bounding planes with the planet itself.
+ */
+ protected final GeoPoint[] edgePoints;
+
+ /** Notable points for minXPlane */
+ protected final GeoPoint[] notableMinXPoints;
+ /** Notable points for maxXPlane */
+ protected final GeoPoint[] notableMaxXPoints;
+ /** Notable points for minYPlane */
+ protected final GeoPoint[] notableMinYPoints;
+ /** Notable points for maxYPlane */
+ protected final GeoPoint[] notableMaxYPoints;
+ /** Notable points for minZPlane */
+ protected final GeoPoint[] notableMinZPoints;
+ /** Notable points for maxZPlane */
+ protected final GeoPoint[] notableMaxZPoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param minX is the minimum X value.
+ *@param maxX is the maximum X value.
+ *@param minY is the minimum Y value.
+ *@param maxY is the maximum Y value.
+ *@param minZ is the minimum Z value.
+ *@param maxZ is the maximum Z value.
+ */
+ public StandardXYZSolid(final PlanetModel planetModel,
+ final double minX,
+ final double maxX,
+ final double minY,
+ final double maxY,
+ final double minZ,
+ final double maxZ) {
+ super(planetModel);
+ // Argument checking
+ if (maxX - minX < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("X values in wrong order or identical");
+ if (maxY - minY < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Y values in wrong order or identical");
+ if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Z values in wrong order or identical");
+
+ final double worldMinX = planetModel.getMinimumXValue();
+ final double worldMaxX = planetModel.getMaximumXValue();
+ final double worldMinY = planetModel.getMinimumYValue();
+ final double worldMaxY = planetModel.getMaximumYValue();
+ final double worldMinZ = planetModel.getMinimumZValue();
+ final double worldMaxZ = planetModel.getMaximumZValue();
+
+ // We must distinguish between the case where the solid represents the entire world,
+ // and when the solid has no overlap with any part of the surface. In both cases,
+ // there will be no edgepoints.
+ isWholeWorld =
+ (minX - worldMinX < -Vector.MINIMUM_RESOLUTION) &&
+ (maxX - worldMaxX > Vector.MINIMUM_RESOLUTION) &&
+ (minY - worldMinY < -Vector.MINIMUM_RESOLUTION) &&
+ (maxY - worldMaxY > Vector.MINIMUM_RESOLUTION) &&
+ (minZ - worldMinZ < -Vector.MINIMUM_RESOLUTION) &&
+ (maxZ - worldMaxZ > Vector.MINIMUM_RESOLUTION);
+
+ if (isWholeWorld) {
+ minXPlane = null;
+ maxXPlane = null;
+ minYPlane = null;
+ maxYPlane = null;
+ minZPlane = null;
+ maxZPlane = null;
+ notableMinXPoints = null;
+ notableMaxXPoints = null;
+ notableMinYPoints = null;
+ notableMaxYPoints = null;
+ notableMinZPoints = null;
+ notableMaxZPoints = null;
+ edgePoints = null;
+ } else {
+ // Construct the planes
+ minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
+ maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
+ minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
+ maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
+ minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
+ maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
+
+ // We need at least one point on the planet surface for each manifestation of the shape.
+ // There can be up to 2 (on opposite sides of the world). But we have to go through
+ // 12 combinations of adjacent planes in order to find out if any have 2 intersection solution.
+ // Typically, this requires 12 square root operations.
+ final GeoPoint[] minXminY = minXPlane.findIntersections(planetModel,minYPlane,maxXPlane,maxYPlane,minZPlane,maxZPlane);
+ final GeoPoint[] minXmaxY = minXPlane.findIntersections(planetModel,maxYPlane,maxXPlane,minYPlane,minZPlane,maxZPlane);
+ final GeoPoint[] minXminZ = minXPlane.findIntersections(planetModel,minZPlane,maxXPlane,maxZPlane,minYPlane,maxYPlane);
+ final GeoPoint[] minXmaxZ = minXPlane.findIntersections(planetModel,maxZPlane,maxXPlane,minZPlane,minYPlane,maxYPlane);
+
+ final GeoPoint[] maxXminY = maxXPlane.findIntersections(planetModel,minYPlane,minXPlane,maxYPlane,minZPlane,maxZPlane);
+ final GeoPoint[] maxXmaxY = maxXPlane.findIntersections(planetModel,maxYPlane,minXPlane,minYPlane,minZPlane,maxZPlane);
+ final GeoPoint[] maxXminZ = maxXPlane.findIntersections(planetModel,minZPlane,minXPlane,maxZPlane,minYPlane,maxYPlane);
+ final GeoPoint[] maxXmaxZ = maxXPlane.findIntersections(planetModel,maxZPlane,minXPlane,minZPlane,minYPlane,maxYPlane);
+
+ final GeoPoint[] minYminZ = minYPlane.findIntersections(planetModel,minZPlane,maxYPlane,maxZPlane,minXPlane,maxXPlane);
+ final GeoPoint[] minYmaxZ = minYPlane.findIntersections(planetModel,maxZPlane,maxYPlane,minZPlane,minXPlane,maxXPlane);
+ final GeoPoint[] maxYminZ = maxYPlane.findIntersections(planetModel,minZPlane,minYPlane,maxZPlane,minXPlane,maxXPlane);
+ final GeoPoint[] maxYmaxZ = maxYPlane.findIntersections(planetModel,maxZPlane,minYPlane,minZPlane,minXPlane,maxXPlane);
+
+ notableMinXPoints = glueTogether(minXminY, minXmaxY, minXminZ, minXmaxZ);
+ notableMaxXPoints = glueTogether(maxXminY, maxXmaxY, maxXminZ, maxXmaxZ);
+ notableMinYPoints = glueTogether(minXminY, maxXminY, minYminZ, minYmaxZ);
+ notableMaxYPoints = glueTogether(minXmaxY, maxXmaxY, maxYminZ, maxYmaxZ);
+ notableMinZPoints = glueTogether(minXminZ, maxXminZ, minYminZ, maxYminZ);
+ notableMaxZPoints = glueTogether(minXmaxZ, maxXmaxZ, minYmaxZ, maxYmaxZ);
+
+ // Now, compute the edge points.
+ // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
+ // we'll start there.
+ // There can be a number of shapes, each of which needs an edgepoint. Each side by itself might contribute
+ // an edgepoint, for instance, if the plane describing that side intercepts the planet in such a way that the ellipse
+ // of interception does not meet any other planes. Plane intersections can each contribute 0, 1, or 2 edgepoints.
+ //
+ // All of this makes for a lot of potential edgepoints, but I believe these can be pruned back with careful analysis.
+ // I haven't yet done that analysis, however, so I will treat them all as individual edgepoints.
+
+ // The cases we are looking for are when the four corner points for any given
+ // plane are all outside of the world, AND that plane intersects the world.
+ // There are eight corner points all told; we must evaluate these WRT the planet surface.
+ final boolean minXminYminZ = planetModel.pointOutside(minX, minY, minZ);
+ final boolean minXminYmaxZ = planetModel.pointOutside(minX, minY, maxZ);
+ final boolean minXmaxYminZ = planetModel.pointOutside(minX, maxY, minZ);
+ final boolean minXmaxYmaxZ = planetModel.pointOutside(minX, maxY, maxZ);
+ final boolean maxXminYminZ = planetModel.pointOutside(maxX, minY, minZ);
+ final boolean maxXminYmaxZ = planetModel.pointOutside(maxX, minY, maxZ);
+ final boolean maxXmaxYminZ = planetModel.pointOutside(maxX, maxY, minZ);
+ final boolean maxXmaxYmaxZ = planetModel.pointOutside(maxX, maxY, maxZ);
+
+ // Look at single-plane/world intersections.
+ // We detect these by looking at the world model and noting its x, y, and z bounds.
+
+ final GeoPoint[] minXEdges;
+ if (minX - worldMinX >= -Vector.MINIMUM_RESOLUTION && minX - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
+ minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
+ minXminYminZ && minXminYmaxZ && minXmaxYminZ && minXmaxYmaxZ) {
+ // Find any point on the minX plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = minXPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
+ if (intPoint != null) {
+ minXEdges = new GeoPoint[]{intPoint};
+ } else {
+ // No intersection found?
+ minXEdges = EMPTY_POINTS;
+ }
+ } else {
+ minXEdges = EMPTY_POINTS;
+ }
+
+ final GeoPoint[] maxXEdges;
+ if (maxX - worldMinX >= -Vector.MINIMUM_RESOLUTION && maxX - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
+ minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
+ maxXminYminZ && maxXminYmaxZ && maxXmaxYminZ && maxXmaxYmaxZ) {
+ // Find any point on the maxX plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = maxXPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
+ if (intPoint != null) {
+ maxXEdges = new GeoPoint[]{intPoint};
+ } else {
+ maxXEdges = EMPTY_POINTS;
+ }
+ } else {
+ maxXEdges = EMPTY_POINTS;
+ }
+
+ final GeoPoint[] minYEdges;
+ if (minY - worldMinY >= -Vector.MINIMUM_RESOLUTION && minY - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
+ minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
+ minXminYminZ && minXminYmaxZ && maxXminYminZ && maxXminYmaxZ) {
+ // Find any point on the minY plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = minYPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
+ if (intPoint != null) {
+ minYEdges = new GeoPoint[]{intPoint};
+ } else {
+ minYEdges = EMPTY_POINTS;
+ }
+ } else {
+ minYEdges = EMPTY_POINTS;
+ }
+
+ final GeoPoint[] maxYEdges;
+ if (maxY - worldMinY >= -Vector.MINIMUM_RESOLUTION && maxY - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
+ minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
+ minXmaxYminZ && minXmaxYmaxZ && maxXmaxYminZ && maxXmaxYmaxZ) {
+ // Find any point on the maxY plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = maxYPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
+ if (intPoint != null) {
+ maxYEdges = new GeoPoint[]{intPoint};
+ } else {
+ maxYEdges = EMPTY_POINTS;
+ }
+ } else {
+ maxYEdges = EMPTY_POINTS;
+ }
+
+ final GeoPoint[] minZEdges;
+ if (minZ - worldMinZ >= -Vector.MINIMUM_RESOLUTION && minZ - worldMaxZ <= Vector.MINIMUM_RESOLUTION &&
+ minX < 0.0 && maxX > 0.0 && minY < 0.0 && maxY > 0.0 &&
+ minXminYminZ && minXmaxYminZ && maxXminYminZ && maxXmaxYminZ) {
+ // Find any point on the minZ plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = minZPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
+ if (intPoint != null) {
+ minZEdges = new GeoPoint[]{intPoint};
+ } else {
+ minZEdges = EMPTY_POINTS;
+ }
+ } else {
+ minZEdges = EMPTY_POINTS;
+ }
+
+ final GeoPoint[] maxZEdges;
+ if (maxZ - worldMinZ >= -Vector.MINIMUM_RESOLUTION && maxZ - worldMaxZ <= Vector.MINIMUM_RESOLUTION &&
+ minX < 0.0 && maxX > 0.0 && minY < 0.0 && maxY > 0.0 &&
+ minXminYmaxZ && minXmaxYmaxZ && maxXminYmaxZ && maxXmaxYmaxZ) {
+ // Find any point on the maxZ plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (1,0,0) (that is, its orientation doesn't matter)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = maxZPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
+ if (intPoint != null) {
+ maxZEdges = new GeoPoint[]{intPoint};
+ } else {
+ maxZEdges = EMPTY_POINTS;
+ }
+ } else {
+ maxZEdges = EMPTY_POINTS;
+ }
+
+ // Glue everything together. This is not a minimal set of edgepoints, as of now, but it does completely describe all shapes on the
+ // planet.
+ this.edgePoints = glueTogether(minXminY, minXmaxY, minXminZ, minXmaxZ,
+ maxXminY, maxXmaxY, maxXminZ, maxXmaxZ,
+ minYminZ, minYmaxZ, maxYminZ, maxYmaxZ,
+ minXEdges, maxXEdges, minYEdges, maxYEdges, minZEdges, maxZEdges);
+ }
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ if (isWholeWorld) {
+ return true;
+ }
+ return minXPlane.isWithin(x, y, z) &&
+ maxXPlane.isWithin(x, y, z) &&
+ minYPlane.isWithin(x, y, z) &&
+ maxYPlane.isWithin(x, y, z) &&
+ minZPlane.isWithin(x, y, z) &&
+ maxZPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ if (isWholeWorld) {
+ if (path.getEdgePoints().length > 0)
+ return WITHIN;
+ return OVERLAPS;
+ }
+
+ /*
+ for (GeoPoint p : getEdgePoints()) {
+ System.err.println(" Edge point "+p+" path.isWithin()? "+path.isWithin(p));
+ }
+
+ for (GeoPoint p : path.getEdgePoints()) {
+ System.err.println(" path edge point "+p+" isWithin()? "+isWithin(p)+" minx="+minXPlane.evaluate(p)+" maxx="+maxXPlane.evaluate(p)+" miny="+minYPlane.evaluate(p)+" maxy="+maxYPlane.evaluate(p)+" minz="+minZPlane.evaluate(p)+" maxz="+maxZPlane.evaluate(p));
+ }
+ */
+
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some shape points inside area");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ //System.err.println(" some area points inside shape");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(minXPlane, notableMinXPoints, maxXPlane, minYPlane, maxYPlane, minZPlane, maxZPlane) ||
+ path.intersects(maxXPlane, notableMaxXPoints, minXPlane, minYPlane, maxYPlane, minZPlane, maxZPlane) ||
+ path.intersects(minYPlane, notableMinYPoints, maxYPlane, minXPlane, maxXPlane, minZPlane, maxZPlane) ||
+ path.intersects(maxYPlane, notableMaxYPoints, minYPlane, minXPlane, maxXPlane, minZPlane, maxZPlane) ||
+ path.intersects(minZPlane, notableMinZPoints, maxZPlane, minXPlane, maxXPlane, minYPlane, maxYPlane) ||
+ path.intersects(maxZPlane, notableMaxZPoints, minZPlane, minXPlane, maxXPlane, minYPlane, maxYPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" all shape points inside area");
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" all area points inside shape");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof StandardXYZSolid))
+ return false;
+ StandardXYZSolid other = (StandardXYZSolid) o;
+ if (!super.equals(other) ||
+ other.isWholeWorld != isWholeWorld) {
+ return false;
+ }
+ if (!isWholeWorld) {
+ return other.minXPlane.equals(minXPlane) &&
+ other.maxXPlane.equals(maxXPlane) &&
+ other.minYPlane.equals(minYPlane) &&
+ other.maxYPlane.equals(maxYPlane) &&
+ other.minZPlane.equals(minZPlane) &&
+ other.maxZPlane.equals(maxZPlane);
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (isWholeWorld?1:0);
+ if (!isWholeWorld) {
+ result = 31 * result + minXPlane.hashCode();
+ result = 31 * result + maxXPlane.hashCode();
+ result = 31 * result + minYPlane.hashCode();
+ result = 31 * result + maxYPlane.hashCode();
+ result = 31 * result + minZPlane.hashCode();
+ result = 31 * result + maxZPlane.hashCode();
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "StandardXYZSolid: {planetmodel="+planetModel+", isWholeWorld="+isWholeWorld+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Tools.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Tools.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Tools.java
new file mode 100755
index 0000000..e8ee29e
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Tools.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Static methods globally useful for 3d geometric work.
+ *
+ * @lucene.experimental
+ */
+public class Tools {
+ private Tools() {
+ }
+
+ /**
+ * Java acos yields a NAN if you take an arc-cos of an
+ * angle that's just a tiny bit greater than 1.0, so
+ * here's a more resilient version.
+ */
+ public static double safeAcos(double value) {
+ if (value > 1.0)
+ value = 1.0;
+ else if (value < -1.0)
+ value = -1.0;
+ return Math.acos(value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Vector.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Vector.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Vector.java
new file mode 100755
index 0000000..3a1b233
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Vector.java
@@ -0,0 +1,378 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * A 3d vector in space, not necessarily
+ * going through the origin.
+ *
+ * @lucene.experimental
+ */
+public class Vector {
+ /**
+ * Values that are all considered to be essentially zero have a magnitude
+ * less than this.
+ */
+ public static final double MINIMUM_RESOLUTION = 1.0e-12;
+ /**
+ * For squared quantities, the bound is squared too.
+ */
+ public static final double MINIMUM_RESOLUTION_SQUARED = MINIMUM_RESOLUTION * MINIMUM_RESOLUTION;
+ /**
+ * For cubed quantities, cube the bound.
+ */
+ public static final double MINIMUM_RESOLUTION_CUBED = MINIMUM_RESOLUTION_SQUARED * MINIMUM_RESOLUTION;
+
+ /** The x value */
+ public final double x;
+ /** The y value */
+ public final double y;
+ /** The z value */
+ public final double z;
+
+ /**
+ * Construct from (U.S.) x,y,z coordinates.
+ *@param x is the x value.
+ *@param y is the y value.
+ *@param z is the z value.
+ */
+ public Vector(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /**
+ * Construct a vector that is perpendicular to
+ * two other (non-zero) vectors. If the vectors are parallel,
+ * IllegalArgumentException will be thrown.
+ * Produces a normalized final vector.
+ *
+ * @param A is the first vector
+ * @param B is the second
+ */
+ public Vector(final Vector A, final Vector B) {
+ // x = u2v3 - u3v2
+ // y = u3v1 - u1v3
+ // z = u1v2 - u2v1
+ final double thisX = A.y * B.z - A.z * B.y;
+ final double thisY = A.z * B.x - A.x * B.z;
+ final double thisZ = A.x * B.y - A.y * B.x;
+ final double magnitude = magnitude(thisX, thisY, thisZ);
+ if (Math.abs(magnitude) < MINIMUM_RESOLUTION) {
+ throw new IllegalArgumentException("Degenerate/parallel vector constructed");
+ }
+ final double inverseMagnitude = 1.0 / magnitude;
+ this.x = thisX * inverseMagnitude;
+ this.y = thisY * inverseMagnitude;
+ this.z = thisZ * inverseMagnitude;
+ }
+
+ /** Compute a magnitude of an x,y,z value.
+ */
+ public static double magnitude(final double x, final double y, final double z) {
+ return Math.sqrt(x*x + y*y + z*z);
+ }
+
+ /**
+ * Compute a normalized unit vector based on the current vector.
+ *
+ * @return the normalized vector, or null if the current vector has
+ * a magnitude of zero.
+ */
+ public Vector normalize() {
+ double denom = magnitude();
+ if (denom < MINIMUM_RESOLUTION)
+ // Degenerate, can't normalize
+ return null;
+ double normFactor = 1.0 / denom;
+ return new Vector(x * normFactor, y * normFactor, z * normFactor);
+ }
+
+ /**
+ * Do a dot product.
+ *
+ * @param v is the vector to multiply.
+ * @return the result.
+ */
+ public double dotProduct(final Vector v) {
+ return this.x * v.x + this.y * v.y + this.z * v.z;
+ }
+
+ /**
+ * Do a dot product.
+ *
+ * @param x is the x value of the vector to multiply.
+ * @param y is the y value of the vector to multiply.
+ * @param z is the z value of the vector to multiply.
+ * @return the result.
+ */
+ public double dotProduct(final double x, final double y, final double z) {
+ return this.x * x + this.y * y + this.z * z;
+ }
+
+ /**
+ * Determine if this vector, taken from the origin,
+ * describes a point within a set of planes.
+ *
+ * @param bounds is the first part of the set of planes.
+ * @param moreBounds is the second part of the set of planes.
+ * @return true if the point is within the bounds.
+ */
+ public boolean isWithin(final Membership[] bounds, final Membership[] moreBounds) {
+ // Return true if the point described is within all provided bounds
+ //System.err.println(" checking if "+this+" is within bounds");
+ for (Membership bound : bounds) {
+ if (bound != null && !bound.isWithin(this)) {
+ //System.err.println(" NOT within "+bound);
+ return false;
+ }
+ }
+ for (Membership bound : moreBounds) {
+ if (bound != null && !bound.isWithin(this)) {
+ //System.err.println(" NOT within "+bound);
+ return false;
+ }
+ }
+ //System.err.println(" is within");
+ return true;
+ }
+
+ /**
+ * Translate vector.
+ */
+ public Vector translate(final double xOffset, final double yOffset, final double zOffset) {
+ return new Vector(x - xOffset, y - yOffset, z - zOffset);
+ }
+
+ /**
+ * Rotate vector counter-clockwise in x-y by an angle.
+ */
+ public Vector rotateXY(final double angle) {
+ return rotateXY(Math.sin(angle), Math.cos(angle));
+ }
+
+ /**
+ * Rotate vector counter-clockwise in x-y by an angle, expressed as sin and cos.
+ */
+ public Vector rotateXY(final double sinAngle, final double cosAngle) {
+ return new Vector(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z);
+ }
+
+ /**
+ * Rotate vector counter-clockwise in x-z by an angle.
+ */
+ public Vector rotateXZ(final double angle) {
+ return rotateXZ(Math.sin(angle), Math.cos(angle));
+ }
+
+ /**
+ * Rotate vector counter-clockwise in x-z by an angle, expressed as sin and cos.
+ */
+ public Vector rotateXZ(final double sinAngle, final double cosAngle) {
+ return new Vector(x * cosAngle - z * sinAngle, y, x * sinAngle + z * cosAngle);
+ }
+
+ /**
+ * Rotate vector counter-clockwise in z-y by an angle.
+ */
+ public Vector rotateZY(final double angle) {
+ return rotateZY(Math.sin(angle), Math.cos(angle));
+ }
+
+ /**
+ * Rotate vector counter-clockwise in z-y by an angle, expressed as sin and cos.
+ */
+ public Vector rotateZY(final double sinAngle, final double cosAngle) {
+ return new Vector(x, z * sinAngle + y * cosAngle, z * cosAngle - y * sinAngle);
+ }
+
+ /**
+ * Compute the square of a straight-line distance to a point described by the
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI.
+ *
+ * @param v is the vector to compute a distance to.
+ * @return the square of the linear distance.
+ */
+ public double linearDistanceSquared(final Vector v) {
+ double deltaX = this.x - v.x;
+ double deltaY = this.y - v.y;
+ double deltaZ = this.z - v.z;
+ return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
+ }
+
+ /**
+ * Compute the square of a straight-line distance to a point described by the
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI.
+ *
+ * @param x is the x part of the vector to compute a distance to.
+ * @param y is the y part of the vector to compute a distance to.
+ * @param z is the z part of the vector to compute a distance to.
+ * @return the square of the linear distance.
+ */
+ public double linearDistanceSquared(final double x, final double y, final double z) {
+ double deltaX = this.x - x;
+ double deltaY = this.y - y;
+ double deltaZ = this.z - z;
+ return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
+ }
+
+ /**
+ * Compute the straight-line distance to a point described by the
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI.
+ *
+ * @param v is the vector to compute a distance to.
+ * @return the linear distance.
+ */
+ public double linearDistance(final Vector v) {
+ return Math.sqrt(linearDistanceSquared(v));
+ }
+
+ /**
+ * Compute the straight-line distance to a point described by the
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI.
+ *
+ * @param x is the x part of the vector to compute a distance to.
+ * @param y is the y part of the vector to compute a distance to.
+ * @param z is the z part of the vector to compute a distance to.
+ * @return the linear distance.
+ */
+ public double linearDistance(final double x, final double y, final double z) {
+ return Math.sqrt(linearDistanceSquared(x, y, z));
+ }
+
+ /**
+ * Compute the square of the normal distance to a vector described by a
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI/2.
+ *
+ * @param v is the vector to compute a distance to.
+ * @return the square of the normal distance.
+ */
+ public double normalDistanceSquared(final Vector v) {
+ double t = dotProduct(v);
+ double deltaX = this.x * t - v.x;
+ double deltaY = this.y * t - v.y;
+ double deltaZ = this.z * t - v.z;
+ return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
+ }
+
+ /**
+ * Compute the square of the normal distance to a vector described by a
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI/2.
+ *
+ * @param x is the x part of the vector to compute a distance to.
+ * @param y is the y part of the vector to compute a distance to.
+ * @param z is the z part of the vector to compute a distance to.
+ * @return the square of the normal distance.
+ */
+ public double normalDistanceSquared(final double x, final double y, final double z) {
+ double t = dotProduct(x, y, z);
+ double deltaX = this.x * t - x;
+ double deltaY = this.y * t - y;
+ double deltaZ = this.z * t - z;
+ return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
+ }
+
+ /**
+ * Compute the normal (perpendicular) distance to a vector described by a
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI/2.
+ *
+ * @param v is the vector to compute a distance to.
+ * @return the normal distance.
+ */
+ public double normalDistance(final Vector v) {
+ return Math.sqrt(normalDistanceSquared(v));
+ }
+
+ /**
+ * Compute the normal (perpendicular) distance to a vector described by a
+ * vector taken from the origin.
+ * Monotonically increasing for arc distances up to PI/2.
+ *
+ * @param x is the x part of the vector to compute a distance to.
+ * @param y is the y part of the vector to compute a distance to.
+ * @param z is the z part of the vector to compute a distance to.
+ * @return the normal distance.
+ */
+ public double normalDistance(final double x, final double y, final double z) {
+ return Math.sqrt(normalDistanceSquared(x, y, z));
+ }
+
+ /**
+ * Compute the magnitude of this vector.
+ *
+ * @return the magnitude.
+ */
+ public double magnitude() {
+ return magnitude(x,y,z);
+ }
+
+ /** 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 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 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 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))
+ return false;
+ Vector other = (Vector) o;
+ return (other.x == x && other.y == y && other.z == z);
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(x);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(y);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(z);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "[X=" + x + ", Y=" + y + ", Z=" + z + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java
new file mode 100644
index 0000000..c3ee53d
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZBounds.java
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * An object for accumulating XYZ bounds information.
+ *
+ * @lucene.experimental
+ */
+public class XYZBounds implements Bounds {
+
+ /** A 'fudge factor', which is added to maximums and subtracted from minimums,
+ * in order to compensate for potential error deltas. This would not be necessary
+ * except that our 'bounds' is defined as always equaling or exceeding the boundary
+ * of the shape, and we cannot guarantee that without making MINIMUM_RESOLUTION
+ * unacceptably large.
+ */
+ protected static final double FUDGE_FACTOR = Vector.MINIMUM_RESOLUTION * 2.0;
+
+ /** Minimum x */
+ protected Double minX = null;
+ /** Maximum x */
+ protected Double maxX = null;
+ /** Minimum y */
+ protected Double minY = null;
+ /** Maximum y */
+ protected Double maxY = null;
+ /** Minimum z */
+ protected Double minZ = null;
+ /** Maximum z */
+ protected Double maxZ = null;
+
+ /** Set to true if no longitude bounds can be stated */
+ protected boolean noLongitudeBound = false;
+ /** Set to true if no top latitude bound can be stated */
+ protected boolean noTopLatitudeBound = false;
+ /** Set to true if no bottom latitude bound can be stated */
+ protected boolean noBottomLatitudeBound = false;
+
+ /** Construct an empty bounds object */
+ public XYZBounds() {
+ }
+
+ // Accessor methods
+
+ /** Return the minimum X value.
+ *@return minimum X value.
+ */
+ public Double getMinimumX() {
+ return minX;
+ }
+
+ /** Return the maximum X value.
+ *@return maximum X value.
+ */
+ public Double getMaximumX() {
+ return maxX;
+ }
+
+ /** Return the minimum Y value.
+ *@return minimum Y value.
+ */
+ public Double getMinimumY() {
+ return minY;
+ }
+
+ /** Return the maximum Y value.
+ *@return maximum Y value.
+ */
+ public Double getMaximumY() {
+ return maxY;
+ }
+
+ /** Return the minimum Z value.
+ *@return minimum Z value.
+ */
+ public Double getMinimumZ() {
+ return minZ;
+ }
+
+ /** Return the maximum Z value.
+ *@return maximum Z value.
+ */
+ public Double getMaximumZ() {
+ return maxZ;
+ }
+
+ /** Return true if minX is as small as the planet model allows.
+ *@return true if minX has reached its bound.
+ */
+ public boolean isSmallestMinX(final PlanetModel planetModel) {
+ if (minX == null)
+ return false;
+ return minX - planetModel.getMinimumXValue() < Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Return true if maxX is as large as the planet model allows.
+ *@return true if maxX has reached its bound.
+ */
+ public boolean isLargestMaxX(final PlanetModel planetModel) {
+ if (maxX == null)
+ return false;
+ return planetModel.getMaximumXValue() - maxX < Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Return true if minY is as small as the planet model allows.
+ *@return true if minY has reached its bound.
+ */
+ public boolean isSmallestMinY(final PlanetModel planetModel) {
+ if (minY == null)
+ return false;
+ return minY - planetModel.getMinimumYValue() < Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Return true if maxY is as large as the planet model allows.
+ *@return true if maxY has reached its bound.
+ */
+ public boolean isLargestMaxY(final PlanetModel planetModel) {
+ if (maxY == null)
+ return false;
+ return planetModel.getMaximumYValue() - maxY < Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Return true if minZ is as small as the planet model allows.
+ *@return true if minZ has reached its bound.
+ */
+ public boolean isSmallestMinZ(final PlanetModel planetModel) {
+ if (minZ == null)
+ return false;
+ return minZ - planetModel.getMinimumZValue() < Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Return true if maxZ is as large as the planet model allows.
+ *@return true if maxZ has reached its bound.
+ */
+ public boolean isLargestMaxZ(final PlanetModel planetModel) {
+ if (maxZ == null)
+ return false;
+ return planetModel.getMaximumZValue() - maxZ < Vector.MINIMUM_RESOLUTION;
+ }
+
+ // Modification methods
+
+ @Override
+ public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds) {
+ plane.recordBounds(planetModel, this, bounds);
+ return this;
+ }
+
+ /** Add a horizontal plane to the bounds description.
+ * This method should EITHER use the supplied latitude, OR use the supplied
+ * plane, depending on what is most efficient.
+ *@param planetModel is the planet model.
+ *@param latitude is the latitude.
+ *@param horizontalPlane is the plane.
+ *@param bounds are the constraints on the plane.
+ *@return updated Bounds object.
+ */
+ public Bounds addHorizontalPlane(final PlanetModel planetModel,
+ final double latitude,
+ final Plane horizontalPlane,
+ final Membership... bounds) {
+ return addPlane(planetModel, horizontalPlane, bounds);
+ }
+
+ /** Add a vertical plane to the bounds description.
+ * This method should EITHER use the supplied longitude, OR use the supplied
+ * plane, depending on what is most efficient.
+ *@param planetModel is the planet model.
+ *@param longitude is the longitude.
+ *@param verticalPlane is the plane.
+ *@param bounds are the constraints on the plane.
+ *@return updated Bounds object.
+ */
+ public Bounds addVerticalPlane(final PlanetModel planetModel,
+ final double longitude,
+ final Plane verticalPlane,
+ final Membership... bounds) {
+ return addPlane(planetModel, verticalPlane, bounds);
+ }
+
+ @Override
+ public Bounds addXValue(final GeoPoint point) {
+ final double x = point.x;
+ final double small = x - FUDGE_FACTOR;
+ if (minX == null || minX > small) {
+ minX = new Double(small);
+ }
+ final double large = x + FUDGE_FACTOR;
+ if (maxX == null || maxX < large) {
+ maxX = new Double(large);
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addYValue(final GeoPoint point) {
+ final double y = point.y;
+ final double small = y - FUDGE_FACTOR;
+ if (minY == null || minY > small) {
+ minY = new Double(small);
+ }
+ final double large = y + FUDGE_FACTOR;
+ if (maxY == null || maxY < large) {
+ maxY = new Double(large);
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addZValue(final GeoPoint point) {
+ final double z = point.z;
+ final double small = z - FUDGE_FACTOR;
+ if (minZ == null || minZ > small) {
+ minZ = new Double(small);
+ }
+ final double large = z + FUDGE_FACTOR;
+ if (maxZ == null || maxZ < large) {
+ maxZ = new Double(large);
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addPoint(final GeoPoint point) {
+ return addXValue(point).addYValue(point).addZValue(point);
+ }
+
+ @Override
+ public Bounds isWide() {
+ // No specific thing we need to do.
+ return this;
+ }
+
+ @Override
+ public Bounds noLongitudeBound() {
+ // No specific thing we need to do.
+ return this;
+ }
+
+ @Override
+ public Bounds noTopLatitudeBound() {
+ // No specific thing we need to do.
+ return this;
+ }
+
+ @Override
+ public Bounds noBottomLatitudeBound() {
+ // No specific thing we need to do.
+ return this;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolid.java
new file mode 100644
index 0000000..9298079
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolid.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Interface for a family of 3D rectangles, bounded on six sides by X,Y,Z limits
+ *
+ * @lucene.internal
+ */
+public interface XYZSolid extends GeoArea {
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolidFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolidFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolidFactory.java
new file mode 100644
index 0000000..25ea400
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYZSolidFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Factory for {@link XYZSolid}.
+ *
+ * @lucene.experimental
+ */
+public class XYZSolidFactory {
+ private XYZSolidFactory() {
+ }
+
+ /**
+ * Create a XYZSolid of the right kind given (x,y,z) bounds.
+ * @param planetModel is the planet model
+ * @param minX is the min X boundary
+ * @param maxX is the max X boundary
+ * @param minY is the min Y boundary
+ * @param maxY is the max Y boundary
+ * @param minZ is the min Z boundary
+ * @param maxZ is the max Z boundary
+ */
+ public static XYZSolid makeXYZSolid(final PlanetModel planetModel, final double minX, final double maxX, final double minY, final double maxY, final double minZ, final double maxZ) {
+ if (Math.abs(maxX - minX) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(maxY - minY) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
+ return new dXdYdZSolid(planetModel, (minX+maxX) * 0.5, (minY+maxY) * 0.5, minZ);
+ } else {
+ return new dXdYZSolid(planetModel, (minX+maxX) * 0.5, (minY+maxY) * 0.5, minZ, maxZ);
+ }
+ } else {
+ if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
+ return new dXYdZSolid(planetModel, (minX+maxX) * 0.5, minY, maxY, (minZ+maxZ) * 0.5);
+ } else {
+ return new dXYZSolid(planetModel, (minX+maxX) * 0.5, minY, maxY, minZ, maxZ);
+ }
+ }
+ }
+ if (Math.abs(maxY - minY) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
+ return new XdYdZSolid(planetModel, minX, maxX, (minY+maxY) * 0.5, (minZ+maxZ) * 0.5);
+ } else {
+ return new XdYZSolid(planetModel, minX, maxX, (minY+maxY) * 0.5, minZ, maxZ);
+ }
+ }
+ if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
+ return new XYdZSolid(planetModel, minX, maxX, minY, maxY, (minZ+maxZ) * 0.5);
+ }
+ return new StandardXYZSolid(planetModel, minX, maxX, minY, maxY, minZ, maxZ);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYdZSolid.java
new file mode 100644
index 0000000..66aac84
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XYdZSolid.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Z
+ *
+ * @lucene.internal
+ */
+public class XYdZSolid extends BaseXYZSolid {
+
+ /** Min-X plane */
+ protected final SidedPlane minXPlane;
+ /** Max-X plane */
+ protected final SidedPlane maxXPlane;
+ /** Min-Y plane */
+ protected final SidedPlane minYPlane;
+ /** Max-Y plane */
+ protected final SidedPlane maxYPlane;
+ /** Z plane */
+ protected final Plane zPlane;
+
+ /** These are the edge points of the shape, which are defined to be at least one point on
+ * each surface area boundary. In the case of a solid, this includes points which represent
+ * the intersection of XYZ bounding planes and the planet, as well as points representing
+ * the intersection of single bounding planes with the planet itself.
+ */
+ protected final GeoPoint[] edgePoints;
+
+ /** Notable points for ZPlane */
+ protected final GeoPoint[] notableZPoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param minX is the minimum X value.
+ *@param maxX is the maximum X value.
+ *@param minY is the minimum Y value.
+ *@param maxY is the maximum Y value.
+ *@param Z is the Z value.
+ */
+ public XYdZSolid(final PlanetModel planetModel,
+ final double minX,
+ final double maxX,
+ final double minY,
+ final double maxY,
+ final double Z) {
+ super(planetModel);
+ // Argument checking
+ if (maxX - minX < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("X values in wrong order or identical");
+ if (maxY - minY < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Y values in wrong order or identical");
+
+ final double worldMinZ = planetModel.getMinimumZValue();
+ final double worldMaxZ = planetModel.getMaximumZValue();
+
+ // Construct the planes
+ minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
+ maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
+ minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
+ maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
+ zPlane = new Plane(zUnitVector,-Z);
+
+ // We need at least one point on the planet surface for each manifestation of the shape.
+ // There can be up to 2 (on opposite sides of the world). But we have to go through
+ // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
+ // Typically, this requires 4 square root operations.
+ final GeoPoint[] minXZ = minXPlane.findIntersections(planetModel,zPlane,maxXPlane,minYPlane,maxYPlane);
+ final GeoPoint[] maxXZ = maxXPlane.findIntersections(planetModel,zPlane,minXPlane,minYPlane,maxYPlane);
+ final GeoPoint[] minYZ = minYPlane.findIntersections(planetModel,zPlane,maxYPlane,minXPlane,maxXPlane);
+ final GeoPoint[] maxYZ = maxYPlane.findIntersections(planetModel,zPlane,minYPlane,minXPlane,maxXPlane);
+
+ notableZPoints = glueTogether(minXZ, maxXZ, minYZ, maxYZ);
+
+ // Now, compute the edge points.
+ // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
+ // we'll start there. We know that at most there will be two disconnected shapes on the planet surface.
+ // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
+ // intersections do. Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
+
+ // If we still haven't encountered anything, we need to look at single-plane/world intersections.
+ // We detect these by looking at the world model and noting its x, y, and z bounds.
+ // The cases we are looking for are when the four corner points for any given
+ // plane are all outside of the world, AND that plane intersects the world.
+ // There are four corner points all told; we must evaluate these WRT the planet surface.
+ final boolean minXminYZ = planetModel.pointOutside(minX, minY, Z);
+ final boolean minXmaxYZ = planetModel.pointOutside(minX, maxY, Z);
+ final boolean maxXminYZ = planetModel.pointOutside(maxX, minY, Z);
+ final boolean maxXmaxYZ = planetModel.pointOutside(maxX, maxY, Z);
+
+ final GeoPoint[] zEdges;
+ if (Z - worldMinZ >= -Vector.MINIMUM_RESOLUTION && Z - worldMaxZ <= Vector.MINIMUM_RESOLUTION &&
+ minX < 0.0 && maxX > 0.0 && minY < 0.0 && maxY > 0.0 &&
+ minXminYZ && minXmaxYZ && maxXminYZ && maxXmaxYZ) {
+ // Find any point on the minZ plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = zPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
+ if (intPoint != null) {
+ zEdges = new GeoPoint[]{intPoint};
+ } else {
+ zEdges = EMPTY_POINTS;
+ }
+ } else {
+ zEdges= EMPTY_POINTS;
+ }
+
+ this.edgePoints = glueTogether(minXZ, maxXZ, minYZ, maxYZ, zEdges);
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return minXPlane.isWithin(x, y, z) &&
+ maxXPlane.isWithin(x, y, z) &&
+ minYPlane.isWithin(x, y, z) &&
+ maxYPlane.isWithin(x, y, z) &&
+ zPlane.evaluateIsZero(x, y, z);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(zPlane, notableZPoints, minXPlane, maxXPlane, minYPlane, maxYPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof XYdZSolid))
+ return false;
+ XYdZSolid other = (XYdZSolid) o;
+ if (!super.equals(other)) {
+ return false;
+ }
+ return other.minXPlane.equals(minXPlane) &&
+ other.maxXPlane.equals(maxXPlane) &&
+ other.minYPlane.equals(minYPlane) &&
+ other.maxYPlane.equals(maxYPlane) &&
+ other.zPlane.equals(zPlane);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + minXPlane.hashCode();
+ result = 31 * result + maxXPlane.hashCode();
+ result = 31 * result + minYPlane.hashCode();
+ result = 31 * result + maxYPlane.hashCode();
+ result = 31 * result + zPlane.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "XYdZSolid: {planetmodel="+planetModel+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", zplane="+zPlane+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYZSolid.java
new file mode 100644
index 0000000..d9e11b8
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYZSolid.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Y
+ *
+ * @lucene.internal
+ */
+public class XdYZSolid extends BaseXYZSolid {
+
+ /** Min-X plane */
+ protected final SidedPlane minXPlane;
+ /** Max-X plane */
+ protected final SidedPlane maxXPlane;
+ /** Y plane */
+ protected final Plane yPlane;
+ /** Min-Z plane */
+ protected final SidedPlane minZPlane;
+ /** Max-Z plane */
+ protected final SidedPlane maxZPlane;
+
+ /** These are the edge points of the shape, which are defined to be at least one point on
+ * each surface area boundary. In the case of a solid, this includes points which represent
+ * the intersection of XYZ bounding planes and the planet, as well as points representing
+ * the intersection of single bounding planes with the planet itself.
+ */
+ protected final GeoPoint[] edgePoints;
+
+ /** Notable points for YPlane */
+ protected final GeoPoint[] notableYPoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param minX is the minimum X value.
+ *@param maxX is the maximum X value.
+ *@param Y is the Y value.
+ *@param minZ is the minimum Z value.
+ *@param maxZ is the maximum Z value.
+ */
+ public XdYZSolid(final PlanetModel planetModel,
+ final double minX,
+ final double maxX,
+ final double Y,
+ final double minZ,
+ final double maxZ) {
+ super(planetModel);
+ // Argument checking
+ if (maxX - minX < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("X values in wrong order or identical");
+ if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Z values in wrong order or identical");
+
+ final double worldMinY = planetModel.getMinimumYValue();
+ final double worldMaxY = planetModel.getMaximumYValue();
+
+ // Construct the planes
+ minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
+ maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
+ yPlane = new Plane(yUnitVector,-Y);
+ minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
+ maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
+
+ // We need at least one point on the planet surface for each manifestation of the shape.
+ // There can be up to 2 (on opposite sides of the world). But we have to go through
+ // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
+ // Typically, this requires 4 square root operations.
+ final GeoPoint[] minXY = minXPlane.findIntersections(planetModel,yPlane,maxXPlane,minZPlane,maxZPlane);
+ final GeoPoint[] maxXY = maxXPlane.findIntersections(planetModel,yPlane,minXPlane,minZPlane,maxZPlane);
+ final GeoPoint[] YminZ = yPlane.findIntersections(planetModel,minZPlane,maxZPlane,minXPlane,maxXPlane);
+ final GeoPoint[] YmaxZ = yPlane.findIntersections(planetModel,maxZPlane,minZPlane,minXPlane,maxXPlane);
+
+ notableYPoints = glueTogether(minXY, maxXY, YminZ, YmaxZ);
+
+ // Now, compute the edge points.
+ // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
+ // we'll start there. We know that at most there will be two disconnected shapes on the planet surface.
+ // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
+ // intersections do. Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
+
+ // We need to look at single-plane/world intersections.
+ // We detect these by looking at the world model and noting its x, y, and z bounds.
+ // The cases we are looking for are when the four corner points for any given
+ // plane are all outside of the world, AND that plane intersects the world.
+ // There are four corner points all told; we must evaluate these WRT the planet surface.
+ final boolean minXYminZ = planetModel.pointOutside(minX, Y, minZ);
+ final boolean minXYmaxZ = planetModel.pointOutside(minX, Y, maxZ);
+ final boolean maxXYminZ = planetModel.pointOutside(maxX, Y, minZ);
+ final boolean maxXYmaxZ = planetModel.pointOutside(maxX, Y, maxZ);
+
+ final GeoPoint[] yEdges;
+ if (Y - worldMinY >= -Vector.MINIMUM_RESOLUTION && Y - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
+ minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
+ minXYminZ && minXYmaxZ && maxXYminZ && maxXYmaxZ) {
+ // Find any point on the minY plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = yPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
+ if (intPoint != null) {
+ yEdges = new GeoPoint[]{intPoint};
+ } else {
+ yEdges = EMPTY_POINTS;
+ }
+ } else {
+ yEdges = EMPTY_POINTS;
+ }
+
+ this.edgePoints = glueTogether(minXY, maxXY, YminZ, YmaxZ, yEdges);
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return minXPlane.isWithin(x, y, z) &&
+ maxXPlane.isWithin(x, y, z) &&
+ yPlane.evaluateIsZero(x, y, z) &&
+ minZPlane.isWithin(x, y, z) &&
+ maxZPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(yPlane, notableYPoints, minXPlane, maxXPlane, minZPlane, maxZPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof XdYZSolid))
+ return false;
+ XdYZSolid other = (XdYZSolid) o;
+ if (!super.equals(other)) {
+ return false;
+ }
+ return other.minXPlane.equals(minXPlane) &&
+ other.maxXPlane.equals(maxXPlane) &&
+ other.yPlane.equals(yPlane) &&
+ other.minZPlane.equals(minZPlane) &&
+ other.maxZPlane.equals(maxZPlane);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + minXPlane.hashCode();
+ result = 31 * result + maxXPlane.hashCode();
+ result = 31 * result + yPlane.hashCode();
+ result = 31 * result + minZPlane.hashCode();
+ result = 31 * result + maxZPlane.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "XdYZSolid: {planetmodel="+planetModel+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", yplane="+yPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYdZSolid.java
new file mode 100644
index 0000000..33d0bea
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/XdYdZSolid.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Y and Z.
+ * This figure, in fact, represents either zero, one, or two points, so the
+ * actual data stored is minimal.
+ *
+ * @lucene.internal
+ */
+public class XdYdZSolid extends BaseXYZSolid {
+
+ /** The points in this figure on the planet surface; also doubles for edge points */
+ protected final GeoPoint[] surfacePoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param minX is the minimum X value.
+ *@param maxX is the maximum X value.
+ *@param Y is the Y value.
+ *@param Z is the Z value.
+ */
+ public XdYdZSolid(final PlanetModel planetModel,
+ final double minX,
+ final double maxX,
+ final double Y,
+ final double Z) {
+ super(planetModel);
+ // Argument checking
+ if (maxX - minX < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("X values in wrong order or identical");
+
+ // Build the planes and intersect them.
+ final Plane yPlane = new Plane(yUnitVector,-Y);
+ final Plane zPlane = new Plane(zUnitVector,-Z);
+ final SidedPlane minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
+ final SidedPlane maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
+ surfacePoints = yPlane.findIntersections(planetModel,zPlane,minXPlane,maxXPlane);
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return surfacePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (final GeoPoint p : surfacePoints) {
+ if (p.isIdentical(x,y,z))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof XdYdZSolid))
+ return false;
+ XdYdZSolid other = (XdYdZSolid) o;
+ if (!super.equals(other) || surfacePoints.length != other.surfacePoints.length ) {
+ return false;
+ }
+ for (int i = 0; i < surfacePoints.length; i++) {
+ if (!surfacePoints[i].equals(other.surfacePoints[i]))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ for (final GeoPoint p : surfacePoints) {
+ result = 31 * result + p.hashCode();
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ for (final GeoPoint p : surfacePoints) {
+ sb.append(" ").append(p).append(" ");
+ }
+ return "XdYdZSolid: {planetmodel="+planetModel+", "+sb.toString()+"}";
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYZSolid.java
new file mode 100644
index 0000000..48fe714
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/dXYZSolid.java
@@ -0,0 +1,216 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in X.
+ *
+ * @lucene.internal
+ */
+public class dXYZSolid extends BaseXYZSolid {
+
+ /** X plane */
+ protected final Plane xPlane;
+ /** Min-Y plane */
+ protected final SidedPlane minYPlane;
+ /** Max-Y plane */
+ protected final SidedPlane maxYPlane;
+ /** Min-Z plane */
+ protected final SidedPlane minZPlane;
+ /** Max-Z plane */
+ protected final SidedPlane maxZPlane;
+
+ /** These are the edge points of the shape, which are defined to be at least one point on
+ * each surface area boundary. In the case of a solid, this includes points which represent
+ * the intersection of XYZ bounding planes and the planet, as well as points representing
+ * the intersection of single bounding planes with the planet itself.
+ */
+ protected final GeoPoint[] edgePoints;
+
+ /** Notable points for XPlane */
+ protected final GeoPoint[] notableXPoints;
+
+ /**
+ * Sole constructor
+ *
+ *@param planetModel is the planet model.
+ *@param X is the X value.
+ *@param minY is the minimum Y value.
+ *@param maxY is the maximum Y value.
+ *@param minZ is the minimum Z value.
+ *@param maxZ is the maximum Z value.
+ */
+ public dXYZSolid(final PlanetModel planetModel,
+ final double X,
+ final double minY,
+ final double maxY,
+ final double minZ,
+ final double maxZ) {
+ super(planetModel);
+ // Argument checking
+ if (maxY - minY < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Y values in wrong order or identical");
+ if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Z values in wrong order or identical");
+
+ final double worldMinX = planetModel.getMinimumXValue();
+ final double worldMaxX = planetModel.getMaximumXValue();
+
+ // Construct the planes
+ xPlane = new Plane(xUnitVector,-X);
+ minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
+ maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
+ minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
+ maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
+
+ // We need at least one point on the planet surface for each manifestation of the shape.
+ // There can be up to 2 (on opposite sides of the world). But we have to go through
+ // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
+ // Typically, this requires 4 square root operations.
+ final GeoPoint[] XminY = xPlane.findIntersections(planetModel,minYPlane,maxYPlane,minZPlane,maxZPlane);
+ final GeoPoint[] XmaxY = xPlane.findIntersections(planetModel,maxYPlane,minYPlane,minZPlane,maxZPlane);
+ final GeoPoint[] XminZ = xPlane.findIntersections(planetModel,minZPlane,maxZPlane,minYPlane,maxYPlane);
+ final GeoPoint[] XmaxZ = xPlane.findIntersections(planetModel,maxZPlane,minZPlane,minYPlane,maxYPlane);
+
+ notableXPoints = glueTogether(XminY, XmaxY, XminZ, XmaxZ);
+
+ // Now, compute the edge points.
+ // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
+ // we'll start there. We know that at most there will be two disconnected shapes on the planet surface.
+ // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
+ // intersections do. Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
+
+ // We need to look at single-plane/world intersections.
+ // We detect these by looking at the world model and noting its x, y, and z bounds.
+ // For the single-dimension degenerate case, there's really only one plane that can possibly intersect the world.
+ // The cases we are looking for are when the four corner points for any given
+ // plane are all outside of the world, AND that plane intersects the world.
+ // There are four corner points all told; we must evaluate these WRT the planet surface.
+ final boolean XminYminZ = planetModel.pointOutside(X, minY, minZ);
+ final boolean XminYmaxZ = planetModel.pointOutside(X, minY, maxZ);
+ final boolean XmaxYminZ = planetModel.pointOutside(X, maxY, minZ);
+ final boolean XmaxYmaxZ = planetModel.pointOutside(X, maxY, maxZ);
+
+ final GeoPoint[] xEdges;
+ if (X - worldMinX >= -Vector.MINIMUM_RESOLUTION && X - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
+ minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
+ XminYminZ && XminYmaxZ && XmaxYminZ && XmaxYmaxZ) {
+ // Find any point on the X plane that intersects the world
+ // First construct a perpendicular plane that will allow us to find a sample point.
+ // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
+ // Then use it to compute a sample point.
+ final GeoPoint intPoint = xPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
+ if (intPoint != null) {
+ xEdges = new GeoPoint[]{intPoint};
+ } else {
+ xEdges = EMPTY_POINTS;
+ }
+ } else {
+ xEdges = EMPTY_POINTS;
+ }
+
+ this.edgePoints = glueTogether(XminY,XmaxY,XminZ,XmaxZ,xEdges);
+ }
+
+ @Override
+ protected GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return xPlane.evaluateIsZero(x, y, z) &&
+ minYPlane.isWithin(x, y, z) &&
+ maxYPlane.isWithin(x, y, z) &&
+ minZPlane.isWithin(x, y, z) &&
+ maxZPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideArea(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some shape points inside area");
+ return OVERLAPS;
+ }
+
+ // Figure out if the entire XYZArea is contained by the shape.
+ final int insideShape = isAreaInsideShape(path);
+ if (insideShape == SOME_INSIDE) {
+ //System.err.println(" some area points inside shape");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ // The entire locus of points in this shape is on a single plane, so we only need ot look for an intersection with that plane.
+ //System.err.println("xPlane = "+xPlane);
+ if (path.intersects(xPlane, notableXPoints, minYPlane, maxYPlane, minZPlane, maxZPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape points inside area");
+ return WITHIN;
+ }
+
+ if (insideShape == ALL_INSIDE) {
+ //System.err.println(" shape contains all area");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof dXYZSolid))
+ return false;
+ dXYZSolid other = (dXYZSolid) o;
+ if (!super.equals(other)) {
+ return false;
+ }
+ return other.xPlane.equals(xPlane) &&
+ other.minYPlane.equals(minYPlane) &&
+ other.maxYPlane.equals(maxYPlane) &&
+ other.minZPlane.equals(minZPlane) &&
+ other.maxZPlane.equals(maxZPlane);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + xPlane.hashCode();
+ result = 31 * result + minYPlane.hashCode();
+ result = 31 * result + maxYPlane.hashCode();
+ result = 31 * result + minZPlane.hashCode();
+ result = 31 * result + maxZPlane.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "dXYZSolid: {planetmodel="+planetModel+", xplane="+xPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
+ }
+
+}
+
[22/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoConvexPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoConvexPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoConvexPolygon.java
deleted file mode 100755
index fc07c4b..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoConvexPolygon.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-
-/**
- * GeoConvexPolygon objects are generic building blocks of more complex structures.
- * The only restrictions on these objects are: (1) they must be convex; (2) they must have
- * a maximum extent no larger than PI. Violating either one of these limits will
- * cause the logic to fail.
- *
- * @lucene.experimental
- */
-public class GeoConvexPolygon extends GeoBasePolygon {
- /** The list of polygon points */
- protected final List<GeoPoint> points;
- /** A bitset describing, for each edge, whether it is internal or not */
- protected final BitSet isInternalEdges;
-
- /** A list of edges */
- protected SidedPlane[] edges = null;
- /** The set of notable points for each edge */
- protected GeoPoint[][] notableEdgePoints = null;
- /** A point which is on the boundary of the polygon */
- protected GeoPoint[] edgePoints = null;
- /** Tracking the maximum distance we go at any one time, so to be sure it's legal */
- protected double fullDistance = 0.0;
- /** Set to true when the polygon is complete */
- protected boolean isDone = false;
-
- /**
- * Create a convex polygon from a list of points. The first point must be on the
- * external edge.
- *@param planetModel is the planet model.
- *@param pointList is the list of points to create the polygon from.
- */
- public GeoConvexPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList) {
- super(planetModel);
- this.points = pointList;
- this.isInternalEdges = new BitSet();
- done(false);
- }
-
- /**
- * Create a convex polygon from a list of points, keeping track of which boundaries
- * are internal. This is used when creating a polygon as a building block for another shape.
- *@param planetModel is the planet model.
- *@param pointList is the set of points to create the polygon from.
- *@param internalEdgeFlags is a bitset describing whether each edge is internal or not.
- *@param returnEdgeInternal is true when the final return edge is an internal one.
- */
- public GeoConvexPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final BitSet internalEdgeFlags,
- final boolean returnEdgeInternal) {
- super(planetModel);
- this.points = pointList;
- this.isInternalEdges = internalEdgeFlags;
- done(returnEdgeInternal);
- }
-
- /**
- * Create a convex polygon, with a starting latitude and longitude.
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *@param planetModel is the planet model.
- *@param startLatitude is the latitude of the first point.
- *@param startLongitude is the longitude of the first point.
- */
- public GeoConvexPolygon(final PlanetModel planetModel, final double startLatitude, final double startLongitude) {
- super(planetModel);
- points = new ArrayList<>();
- isInternalEdges = new BitSet();
- points.add(new GeoPoint(planetModel, startLatitude, startLongitude));
- }
-
- /**
- * Add a point to the polygon.
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *
- * @param latitude is the latitude of the next point.
- * @param longitude is the longitude of the next point.
- * @param isInternalEdge is true if the edge just added with this point should be considered "internal", and not
- * intersected as part of the intersects() operation.
- */
- public void addPoint(final double latitude, final double longitude, final boolean isInternalEdge) {
- if (isDone)
- throw new IllegalStateException("Can't call addPoint() if done() already called");
- if (isInternalEdge)
- isInternalEdges.set(points.size() - 1);
- points.add(new GeoPoint(planetModel, latitude, longitude));
- }
-
- /**
- * Finish the polygon, by connecting the last added point with the starting point.
- *@param isInternalReturnEdge is true if the return edge (back to start) is an internal one.
- */
- public void done(final boolean isInternalReturnEdge) {
- if (isDone)
- throw new IllegalStateException("Can't call done() more than once");
- // If fewer than 3 points, can't do it.
- if (points.size() < 3)
- throw new IllegalArgumentException("Polygon needs at least three points.");
-
- if (isInternalReturnEdge)
- isInternalEdges.set(points.size() - 1);
-
- isDone = true;
-
- // Time to construct the planes. If the polygon is truly convex, then any adjacent point
- // to a segment can provide an interior measurement.
- edges = new SidedPlane[points.size()];
- notableEdgePoints = new GeoPoint[points.size()][];
-
- for (int i = 0; i < points.size(); i++) {
- final GeoPoint start = points.get(i);
- final GeoPoint end = points.get(legalIndex(i + 1));
- final double distance = start.arcDistance(end);
- if (distance > fullDistance)
- fullDistance = distance;
- final GeoPoint check = points.get(legalIndex(i + 2));
- final SidedPlane sp = new SidedPlane(check, start, end);
- //System.out.println("Created edge "+sp+" using start="+start+" end="+end+" check="+check);
- edges[i] = sp;
- notableEdgePoints[i] = new GeoPoint[]{start, end};
- }
- createCenterPoint();
- }
-
- /** Compute a reasonable center point.
- */
- protected void createCenterPoint() {
- // In order to naively confirm that the polygon is convex, I would need to
- // check every edge, and verify that every point (other than the edge endpoints)
- // is within the edge's sided plane. This is an order n^2 operation. That's still
- // not wrong, though, because everything else about polygons has a similar cost.
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final SidedPlane edge = edges[edgeIndex];
- for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) {
- if (pointIndex != edgeIndex && pointIndex != legalIndex(edgeIndex + 1)) {
- if (!edge.isWithin(points.get(pointIndex)))
- throw new IllegalArgumentException("Polygon is not convex: Point " + points.get(pointIndex) + " Edge " + edge);
- }
- }
- }
- edgePoints = new GeoPoint[]{points.get(0)};
- }
-
- /** Compute a legal point index from a possibly illegal one, that may have wrapped.
- *@param index is the index.
- *@return the normalized index.
- */
- protected int legalIndex(int index) {
- while (index >= points.size())
- index -= points.size();
- return index;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- for (final SidedPlane edge : edges) {
- if (!edge.isWithin(x, y, z))
- return false;
- }
- return true;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- //System.err.println("Checking for polygon intersection with plane "+p+"...");
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final SidedPlane edge = edges[edgeIndex];
- final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
- if (!isInternalEdges.get(edgeIndex)) {
- //System.err.println(" non-internal edge "+edge);
- // Edges flagged as 'internal only' are excluded from the matching
- // Construct boundaries
- final Membership[] membershipBounds = new Membership[edges.length - 1];
- int count = 0;
- for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
- if (otherIndex != edgeIndex) {
- membershipBounds[count++] = edges[otherIndex];
- }
- }
- if (edge.intersects(planetModel, p, notablePoints, points, bounds, membershipBounds)) {
- //System.err.println(" intersects!");
- return true;
- }
- }
- }
- //System.err.println(" no intersection");
- return false;
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
-
- // Add all the points
- for (final GeoPoint point : points) {
- bounds.addPoint(point);
- }
-
- // Add planes with membership.
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final SidedPlane edge = edges[edgeIndex];
- // Construct boundaries
- final Membership[] membershipBounds = new Membership[edges.length - 1];
- int count = 0;
- for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
- if (otherIndex != edgeIndex) {
- membershipBounds[count++] = edges[otherIndex];
- }
- }
- bounds.addPlane(planetModel, edge, membershipBounds);
- }
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- double minimumDistance = Double.MAX_VALUE;
- for (final GeoPoint edgePoint : points) {
- final double newDist = distanceStyle.computeDistance(edgePoint, x,y,z);
- if (newDist < minimumDistance) {
- minimumDistance = newDist;
- }
- }
- for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
- final Plane edgePlane = edges[edgeIndex];
- final Membership[] membershipBounds = new Membership[edges.length - 1];
- int count = 0;
- for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
- if (otherIndex != edgeIndex) {
- membershipBounds[count++] = edges[otherIndex];
- }
- }
- final double newDist = distanceStyle.computeDistance(planetModel, edgePlane, x, y, z, membershipBounds);
- if (newDist < minimumDistance) {
- minimumDistance = newDist;
- }
- }
- return minimumDistance;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoConvexPolygon))
- return false;
- GeoConvexPolygon other = (GeoConvexPolygon) o;
- if (!super.equals(other))
- return false;
- if (!other.isInternalEdges.equals(isInternalEdges))
- return false;
- return (other.points.equals(points));
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + points.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoConvexPolygon: {planetmodel=" + planetModel + ", points=" + points + "}";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateHorizontalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateHorizontalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateHorizontalLine.java
deleted file mode 100644
index 6644f0d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateHorizontalLine.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Degenerate bounding box limited on two sides (left lon, right lon).
- * The left-right maximum extent for this shape is PI; for anything larger, use
- * GeoWideDegenerateHorizontalLine.
- *
- * @lucene.internal
- */
-public class GeoDegenerateHorizontalLine extends GeoBaseBBox {
- /** Latitude of horizontal line */
- protected final double latitude;
- /** Left bounding longitude of line */
- protected final double leftLon;
- /** Right bounding longitude of line */
- protected final double rightLon;
-
- /** Left hand endpoint of line */
- protected final GeoPoint LHC;
- /** Right hand endpoint of line */
- protected final GeoPoint RHC;
-
- /** The plane describing the line */
- protected final Plane plane;
- /** The left side end plane */
- protected final SidedPlane leftPlane;
- /** The right side end plane */
- protected final SidedPlane rightPlane;
-
- /** Notable points for the line */
- protected final GeoPoint[] planePoints;
-
- /** Center of line */
- protected final GeoPoint centerPoint;
- /** A point that's on the line */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *@param planetModel is the planet model.
- *@param latitude is the latitude of the line.
- *@param leftLon is the left end longitude.
- *@param rightLon is the right end longitude.
- */
- public GeoDegenerateHorizontalLine(final PlanetModel planetModel, final double latitude, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
- throw new IllegalArgumentException("Latitude out of range");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent > Math.PI)
- throw new IllegalArgumentException("Width of rectangle too great");
-
- this.latitude = latitude;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinLatitude = Math.sin(latitude);
- final double cosLatitude = Math.cos(latitude);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the two points
- this.LHC = new GeoPoint(planetModel, sinLatitude, sinLeftLon, cosLatitude, cosLeftLon, latitude, leftLon);
- this.RHC = new GeoPoint(planetModel, sinLatitude, sinRightLon, cosLatitude, cosRightLon, latitude, rightLon);
-
- this.plane = new Plane(planetModel, sinLatitude);
-
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.planePoints = new GeoPoint[]{LHC, RHC};
-
- this.edgePoints = new GeoPoint[]{centerPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- double newTopLat = latitude + angle;
- double newBottomLat = latitude - angle;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return plane.evaluateIsZero(x, y, z) &&
- leftPlane.isWithin(x, y, z) &&
- rightPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- double topAngle = centerPoint.arcDistance(RHC);
- double bottomAngle = centerPoint.arcDistance(LHC);
- return Math.max(topAngle, bottomAngle);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, leftPlane, rightPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.addHorizontalPlane(planetModel, latitude, plane, leftPlane, rightPlane)
- .addPoint(LHC).addPoint(RHC);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println("getting relationship between "+this+" and "+path);
- if (path.intersects(plane, planePoints, leftPlane, rightPlane)) {
- //System.err.println(" overlaps");
- return OVERLAPS;
- }
-
- if (path.isWithin(centerPoint)) {
- //System.err.println(" contains");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, leftPlane, rightPlane);
-
- final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
- final double RHCDistance = distanceStyle.computeDistance(RHC, x,y,z);
-
- return Math.min(
- distance,
- Math.min(LHCDistance, RHCDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoDegenerateHorizontalLine))
- return false;
- GeoDegenerateHorizontalLine other = (GeoDegenerateHorizontalLine) o;
- return super.equals(other) && other.LHC.equals(LHC) && other.RHC.equals(RHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + LHC.hashCode();
- result = 31 * result + RHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateHorizontalLine: {planetmodel="+planetModel+", latitude=" + latitude + "(" + latitude * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightLon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLatitudeZone.java
deleted file mode 100644
index 4890733..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLatitudeZone.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * This GeoBBox represents an area rectangle of one specific latitude with
- * no longitude bounds.
- *
- * @lucene.internal
- */
-public class GeoDegenerateLatitudeZone extends GeoBaseBBox {
- /** The latitude */
- protected final double latitude;
- /** Sine of the latitude */
- protected final double sinLatitude;
- /** Plane describing the latitude zone */
- protected final Plane plane;
- /** A point on the world that's also on the zone */
- protected final GeoPoint interiorPoint;
- /** An array consisting of the interiorPoint */
- protected final GeoPoint[] edgePoints;
- /** No notable points */
- protected final static GeoPoint[] planePoints = new GeoPoint[0];
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- *@param latitude is the latitude of the latitude zone.
- */
- public GeoDegenerateLatitudeZone(final PlanetModel planetModel, final double latitude) {
- super(planetModel);
- this.latitude = latitude;
-
- this.sinLatitude = Math.sin(latitude);
- double cosLatitude = Math.cos(latitude);
- this.plane = new Plane(planetModel, sinLatitude);
- // Compute an interior point.
- interiorPoint = new GeoPoint(planetModel, sinLatitude, 0.0, cosLatitude, 1.0);
- edgePoints = new GeoPoint[]{interiorPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- double newTopLat = latitude + angle;
- double newBottomLat = latitude - angle;
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return Math.abs(z - this.sinLatitude) < 1e-10;
- }
-
- @Override
- public double getRadius() {
- return Math.PI;
- }
-
- @Override
- public GeoPoint getCenter() {
- // Totally arbitrary
- return interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, plane, notablePoints, planePoints, bounds);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.noLongitudeBound()
- .addHorizontalPlane(planetModel, latitude, plane);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
- //System.out.println("Got here! latitude="+latitude+" path="+path);
-
- if (path.intersects(plane, planePoints)) {
- return OVERLAPS;
- }
-
- if (path.isWithin(interiorPoint)) {
- return CONTAINS;
- }
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(planetModel, plane, x,y,z);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoDegenerateLatitudeZone))
- return false;
- GeoDegenerateLatitudeZone other = (GeoDegenerateLatitudeZone) o;
- return super.equals(other) && other.latitude == latitude;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp = Double.doubleToLongBits(latitude);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateLatitudeZone: {planetmodel="+planetModel+", lat=" + latitude + "(" + latitude * 180.0 / Math.PI + ")}";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLongitudeSlice.java
deleted file mode 100644
index b5eb902..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateLongitudeSlice.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Degenerate longitude slice.
- *
- * @lucene.internal
- */
-public class GeoDegenerateLongitudeSlice extends GeoBaseBBox {
- /** The longitude of the slice */
- protected final double longitude;
-
- /** The bounding plane for the slice (through both poles, perpendicular to the slice) */
- protected final SidedPlane boundingPlane;
- /** The plane of the slice */
- protected final Plane plane;
- /** A point on the slice */
- protected final GeoPoint interiorPoint;
- /** An array consisting of the one point chosen on the slice */
- protected final GeoPoint[] edgePoints;
- /** Notable points for the slice (north and south poles) */
- protected final GeoPoint[] planePoints;
-
- /**
- * Accepts only values in the following ranges: lon: {@code -PI -> PI}
- */
- public GeoDegenerateLongitudeSlice(final PlanetModel planetModel, final double longitude) {
- super(planetModel);
- // Argument checking
- if (longitude < -Math.PI || longitude > Math.PI)
- throw new IllegalArgumentException("Longitude out of range");
- this.longitude = longitude;
-
- final double sinLongitude = Math.sin(longitude);
- final double cosLongitude = Math.cos(longitude);
-
- this.plane = new Plane(cosLongitude, sinLongitude);
- // We need a bounding plane too, which is perpendicular to the longitude plane and sided so that the point (0.0, longitude) is inside.
- this.interiorPoint = new GeoPoint(planetModel, 0.0, sinLongitude, 1.0, cosLongitude);
- this.boundingPlane = new SidedPlane(interiorPoint, -sinLongitude, cosLongitude);
- this.edgePoints = new GeoPoint[]{interiorPoint};
- this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- // Figuring out when we escalate to a special case requires some prefiguring
- double newLeftLon = longitude - angle;
- double newRightLon = longitude + angle;
- double currentLonSpan = 2.0 * angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return plane.evaluateIsZero(x, y, z) &&
- boundingPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- return Math.PI * 0.5;
- }
-
- @Override
- public GeoPoint getCenter() {
- return interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, boundingPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds
- .addVerticalPlane(planetModel, longitude, plane, boundingPlane)
- .addPoint(planetModel.NORTH_POLE).addPoint(planetModel.SOUTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- // Look for intersections.
- if (path.intersects(plane, planePoints, boundingPlane))
- return OVERLAPS;
-
- if (path.isWithin(interiorPoint))
- return CONTAINS;
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, boundingPlane);
-
- final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
- final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
-
- return Math.min(
- distance,
- Math.min(northDistance, southDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoDegenerateLongitudeSlice))
- return false;
- GeoDegenerateLongitudeSlice other = (GeoDegenerateLongitudeSlice) o;
- return super.equals(other) && other.longitude == longitude;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp = Double.doubleToLongBits(longitude);
- result = result * 31 + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateLongitudeSlice: {planetmodel="+planetModel+", longitude=" + longitude + "(" + longitude * 180.0 / Math.PI + ")}";
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegeneratePoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegeneratePoint.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegeneratePoint.java
deleted file mode 100644
index 63670d7..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegeneratePoint.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * This class represents a degenerate point bounding box.
- * It is not a simple GeoPoint because we must have the latitude and longitude.
- *
- * @lucene.internal
- */
-public class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
- /** Current planet model, since we don't extend BasePlanetObject */
- protected final PlanetModel planetModel;
- /** Edge point is an area containing just this */
- protected final GeoPoint[] edgePoints;
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- *@param lat is the latitude.
- *@param lon is the longitude.
- */
- public GeoDegeneratePoint(final PlanetModel planetModel, final double lat, final double lon) {
- super(planetModel, lat, lon);
- this.planetModel = planetModel;
- this.edgePoints = new GeoPoint[]{this};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = latitude + angle;
- final double newBottomLat = latitude - angle;
- final double newLeftLon = longitude - angle;
- final double newRightLon = longitude + angle;
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
- // If not on the plane, no intersection
- if (!plane.evaluateIsZero(this))
- return false;
-
- for (Membership m : bounds) {
- if (!m.isWithin(this))
- return false;
- }
- return true;
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- bounds.addPoint(this);
- }
-
- @Override
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
- return distanceStyle.computeDistance(this, point);
- }
-
- @Override
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(this, x,y,z);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoDegeneratePoint))
- return false;
- GeoDegeneratePoint other = (GeoDegeneratePoint) o;
- return super.equals(other) && other.latitude == latitude && other.longitude == longitude;
- }
-
- @Override
- public String toString() {
- return "GeoDegeneratePoint: {planetmodel="+planetModel+", lat=" + latitude + "(" + latitude * 180.0 / Math.PI + "), lon=" + longitude + "(" + longitude * 180.0 / Math.PI + ")}";
- }
-
- @Override
- public boolean isWithin(final Vector point) {
- return isWithin(point.x, point.y, point.z);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return x == this.x && y == this.y && z == this.z;
- }
-
- @Override
- public double getRadius() {
- return 0.0;
- }
-
- @Override
- public GeoPoint getCenter() {
- return this;
- }
-
- @Override
- public int getRelationship(final GeoShape shape) {
- if (shape.isWithin(this)) {
- //System.err.println("Degenerate point "+this+" is WITHIN shape "+shape);
- return CONTAINS;
- }
-
- //System.err.println("Degenerate point "+this+" is NOT within shape "+shape);
- return DISJOINT;
- }
-
- @Override
- public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (isWithin(x,y,z))
- return 0.0;
- return Double.MAX_VALUE;
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateVerticalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateVerticalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateVerticalLine.java
deleted file mode 100644
index f21f774..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDegenerateVerticalLine.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Degenerate bounding box limited on two sides (top lat, bottom lat).
- *
- * @lucene.internal
- */
-public class GeoDegenerateVerticalLine extends GeoBaseBBox {
- /** Top latitude of the vertical line */
- protected final double topLat;
- /** Bottom latitude of the vertical line */
- protected final double bottomLat;
- /** Longitude of the vertical line */
- protected final double longitude;
-
- /** Point at the upper end of the vertical line */
- protected final GeoPoint UHC;
- /** Point at the lower end of the vertical line */
- protected final GeoPoint LHC;
-
- /** Top end cutoff plane */
- protected final SidedPlane topPlane;
- /** Bottom end cutoff plane */
- protected final SidedPlane bottomPlane;
- /** Back-side cutoff plane */
- protected final SidedPlane boundingPlane;
- /** The vertical line plane */
- protected final Plane plane;
- /** Notable points for the line (end points) */
- protected final GeoPoint[] planePoints;
- /** A computed center point for the line */
- protected final GeoPoint centerPoint;
- /** A point that's on the line */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, longitude: {@code -PI -> PI}
- */
- public GeoDegenerateVerticalLine(final PlanetModel planetModel, final double topLat, final double bottomLat, final double longitude) {
- super(planetModel);
- // Argument checking
- if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Top latitude out of range");
- if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Bottom latitude out of range");
- if (topLat < bottomLat)
- throw new IllegalArgumentException("Top latitude less than bottom latitude");
- if (longitude < -Math.PI || longitude > Math.PI)
- throw new IllegalArgumentException("Longitude out of range");
-
- this.topLat = topLat;
- this.bottomLat = bottomLat;
- this.longitude = longitude;
-
- final double sinTopLat = Math.sin(topLat);
- final double cosTopLat = Math.cos(topLat);
- final double sinBottomLat = Math.sin(bottomLat);
- final double cosBottomLat = Math.cos(bottomLat);
- final double sinLongitude = Math.sin(longitude);
- final double cosLongitude = Math.cos(longitude);
-
- // Now build the two points
- this.UHC = new GeoPoint(planetModel, sinTopLat, sinLongitude, cosTopLat, cosLongitude, topLat, longitude);
- this.LHC = new GeoPoint(planetModel, sinBottomLat, sinLongitude, cosBottomLat, cosLongitude, bottomLat, longitude);
-
- this.plane = new Plane(cosLongitude, sinLongitude);
-
- final double middleLat = (topLat + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- final double cosMiddleLat = Math.cos(middleLat);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinLongitude, cosMiddleLat, cosLongitude);
-
- this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
- this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
-
- this.boundingPlane = new SidedPlane(centerPoint, -sinLongitude, cosLongitude);
-
- this.planePoints = new GeoPoint[]{UHC, LHC};
-
- this.edgePoints = new GeoPoint[]{centerPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = bottomLat - angle;
- double newLeftLon = longitude - angle;
- double newRightLon = longitude + angle;
- double currentLonSpan = 2.0 * angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return plane.evaluateIsZero(x, y, z) &&
- boundingPlane.isWithin(x, y, z) &&
- topPlane.isWithin(x, y, z) &&
- bottomPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double topAngle = centerPoint.arcDistance(UHC);
- final double bottomAngle = centerPoint.arcDistance(LHC);
- return Math.max(topAngle, bottomAngle);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, boundingPlane, topPlane, bottomPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.addVerticalPlane(planetModel, longitude, plane, boundingPlane, topPlane, bottomPlane)
- .addPoint(UHC).addPoint(LHC);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" relationship to "+path);
- if (path.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane)) {
- //System.err.println(" overlaps");
- return OVERLAPS;
- }
-
- if (path.isWithin(centerPoint)) {
- //System.err.println(" contains");
- return CONTAINS;
- }
-
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, topPlane, bottomPlane, boundingPlane);
-
- final double UHCDistance = distanceStyle.computeDistance(UHC, x,y,z);
- final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
-
- return Math.min(
- distance,
- Math.min(UHCDistance, LHCDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoDegenerateVerticalLine))
- return false;
- GeoDegenerateVerticalLine other = (GeoDegenerateVerticalLine) o;
- return super.equals(other) && other.UHC.equals(UHC) && other.LHC.equals(LHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + UHC.hashCode();
- result = 31 * result + LHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoDegenerateVerticalLine: {longitude=" + longitude + "(" + longitude * 180.0 / Math.PI + "), toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistance.java
deleted file mode 100755
index 899a687..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistance.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * An implementer of this interface is capable of computing the described "distance" values,
- * which are meant to provide both actual distance values, as well as
- * distance estimates that can be computed more cheaply.
- *
- * @lucene.experimental
- */
-public interface GeoDistance extends Membership {
-
- // The following methods compute distances from the shape to a point
- // expected to be INSIDE the shape. Typically a value of Double.MAX_VALUE
- // is returned for points that happen to be outside the shape.
-
- /**
- * Compute this shape's <em>internal</em> "distance" to the GeoPoint.
- * Implementations should clarify how this is computed when it's non-obvious.
- * A return value of Double.MAX_VALUE should be returned for
- * points outside of the shape.
- *
- * @param distanceStyle is the distance style.
- * @param point is the point to compute the distance to.
- * @return the distance.
- */
- public default double computeDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
- return computeDistance(distanceStyle, point.x, point.y, point.z);
- }
-
- /**
- * Compute this shape's <em>internal</em> "distance" to the GeoPoint.
- * Implementations should clarify how this is computed when it's non-obvious.
- * A return value of Double.MAX_VALUE should be returned for
- * points outside of the shape.
- *
- * @param x is the point's unit x coordinate (using U.S. convention).
- * @param y is the point's unit y coordinate (using U.S. convention).
- * @param z is the point's unit z coordinate (using U.S. convention).
- * @return the distance.
- */
- public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistanceShape.java
deleted file mode 100755
index 1e82f48..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoDistanceShape.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Distance shapes have capabilities of both geohashing and distance
- * computation (which also includes point membership determination).
- *
- * @lucene.experimental
- */
-public interface GeoDistanceShape extends GeoMembershipShape, GeoDistance {
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLatitudeZone.java
deleted file mode 100755
index 3fc4423..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLatitudeZone.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * This GeoBBox represents an area rectangle limited only in latitude.
- *
- * @lucene.internal
- */
-public class GeoLatitudeZone extends GeoBaseBBox {
- /** The top latitude of the zone */
- protected final double topLat;
- /** The bottom latitude of the zone */
- protected final double bottomLat;
- /** Cosine of the top lat */
- protected final double cosTopLat;
- /** Cosine of the bottom lat */
- protected final double cosBottomLat;
- /** The top plane */
- protected final SidedPlane topPlane;
- /** The bottom plane */
- protected final SidedPlane bottomPlane;
- /** An interior point */
- protected final GeoPoint interiorPoint;
- /** Notable points (none) */
- protected final static GeoPoint[] planePoints = new GeoPoint[0];
-
- // We need two additional points because a latitude zone's boundaries don't intersect. This is a very
- // special case that most GeoBBox's do not have.
-
- /** Top boundary point */
- protected final GeoPoint topBoundaryPoint;
- /** Bottom boundary point */
- protected final GeoPoint bottomBoundaryPoint;
- /** A point on each distinct edge */
- protected final GeoPoint[] edgePoints;
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- *@param topLat is the top latitude.
- *@param bottomLat is the bottom latitude.
- */
- public GeoLatitudeZone(final PlanetModel planetModel, final double topLat, final double bottomLat) {
- super(planetModel);
- this.topLat = topLat;
- this.bottomLat = bottomLat;
-
- final double sinTopLat = Math.sin(topLat);
- final double sinBottomLat = Math.sin(bottomLat);
- this.cosTopLat = Math.cos(topLat);
- this.cosBottomLat = Math.cos(bottomLat);
-
- // Compute an interior point. Pick one whose lat is between top and bottom.
- final double middleLat = (topLat + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
- this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0);
- this.bottomBoundaryPoint = new GeoPoint(planetModel, sinBottomLat, 0.0, Math.sqrt(1.0 - sinBottomLat * sinBottomLat), 1.0);
-
- this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat);
- this.bottomPlane = new SidedPlane(interiorPoint, planetModel, sinBottomLat);
-
- this.edgePoints = new GeoPoint[]{topBoundaryPoint, bottomBoundaryPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = topLat + angle;
- final double newBottomLat = bottomLat - angle;
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return topPlane.isWithin(x, y, z) &&
- bottomPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
- // would contain all the bounding box points, when starting in the "center".
- if (topLat > 0.0 && bottomLat < 0.0)
- return Math.PI;
- double maxCosLat = cosTopLat;
- if (maxCosLat < cosBottomLat)
- maxCosLat = cosBottomLat;
- return maxCosLat * Math.PI;
- }
-
- @Override
- public GeoPoint getCenter() {
- // This is totally arbitrary and only a cartesian could agree with it.
- return interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, topPlane, notablePoints, planePoints, bounds, bottomPlane) ||
- p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds, topPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds.noLongitudeBound()
- .addHorizontalPlane(planetModel, topLat, topPlane)
- .addHorizontalPlane(planetModel, bottomLat, bottomPlane);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean topBoundaryInsideShape = path.isWithin(topBoundaryPoint);
- final boolean bottomBoundaryInsideShape = path.isWithin(bottomBoundaryPoint);
-
- if (topBoundaryInsideShape && !bottomBoundaryInsideShape ||
- !topBoundaryInsideShape && bottomBoundaryInsideShape)
- return OVERLAPS;
-
- final boolean insideShape = topBoundaryInsideShape && bottomBoundaryInsideShape;
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(topPlane, planePoints, bottomPlane) ||
- path.intersects(bottomPlane, planePoints, topPlane))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane);
- final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane);
-
- return Math.min(topDistance, bottomDistance);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoLatitudeZone))
- return false;
- GeoLatitudeZone other = (GeoLatitudeZone) o;
- return super.equals(other) && other.topBoundaryPoint.equals(topBoundaryPoint) && other.bottomBoundaryPoint.equals(bottomBoundaryPoint);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + topBoundaryPoint.hashCode();
- result = 31 * result + bottomBoundaryPoint.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoLatitudeZone: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLongitudeSlice.java
deleted file mode 100755
index f5de7e7..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoLongitudeSlice.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box limited on left and right.
- * The left-right maximum extent for this shape is PI; for anything larger, use
- * {@link GeoWideLongitudeSlice}.
- *
- * @lucene.internal
- */
-public class GeoLongitudeSlice extends GeoBaseBBox {
- /** The left longitude of the slice */
- protected final double leftLon;
- /** The right longitude of the slice */
- protected final double rightLon;
- /** The left plane of the slice */
- protected final SidedPlane leftPlane;
- /** The right plane of the slice */
- protected final SidedPlane rightPlane;
- /** The notable points for the slice (north and south poles) */
- protected final GeoPoint[] planePoints;
- /** The center point of the slice */
- protected final GeoPoint centerPoint;
- /** A point on the edge of the slice */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lon: {@code -PI -> PI}
- *@param planetModel is the planet model.
- *@param leftLon is the left longitude of the slice.
- *@param rightLon is the right longitude of the slice.
- */
- public GeoLongitudeSlice(final PlanetModel planetModel, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent > Math.PI)
- throw new IllegalArgumentException("Width of rectangle too great");
-
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- this.centerPoint = new GeoPoint(planetModel, 0.0, middleLon);
-
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
- this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return leftPlane.isWithin(x, y, z) &&
- rightPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // Compute the extent and divide by two
- double extent = rightLon - leftLon;
- if (extent < 0.0)
- extent += Math.PI * 2.0;
- return Math.max(Math.PI * 0.5, extent * 0.5);
- }
-
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return p.intersects(planetModel, leftPlane, notablePoints, planePoints, bounds, rightPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds, leftPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds
- .addVerticalPlane(planetModel, leftLon, leftPlane, rightPlane)
- .addVerticalPlane(planetModel, rightLon, rightPlane, leftPlane)
- .addPoint(planetModel.NORTH_POLE)
- .addPoint(planetModel.SOUTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- if (path.intersects(leftPlane, planePoints, rightPlane) ||
- path.intersects(rightPlane, planePoints, leftPlane)) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- return WITHIN;
- }
-
- if (insideShape) {
- return CONTAINS;
- }
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane);
-
- final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
- final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
-
- return
- Math.min(
- Math.min(northDistance, southDistance),
- Math.min(leftDistance, rightDistance));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoLongitudeSlice))
- return false;
- GeoLongitudeSlice other = (GeoLongitudeSlice) o;
- return super.equals(other) && other.leftLon == leftLon && other.rightLon == rightLon;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp = Double.doubleToLongBits(leftLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(rightLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoLongitudeSlice: {planetmodel="+planetModel+", leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoMembershipShape.java
deleted file mode 100755
index 54b2551..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoMembershipShape.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Membership shapes have capabilities of both geohashing and membership
- * determination.
- *
- * @lucene.experimental
- */
-public interface GeoMembershipShape extends GeoShape, GeoOutsideDistance, Membership {
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthLatitudeZone.java
deleted file mode 100644
index 43338bb..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthLatitudeZone.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * This GeoBBox represents an area rectangle limited only in south latitude.
- *
- * @lucene.internal
- */
-public class GeoNorthLatitudeZone extends GeoBaseBBox {
- /** The bottom latitude of the zone */
- protected final double bottomLat;
- /** Cosine of the bottom latitude of the zone */
- protected final double cosBottomLat;
- /** The bottom plane of the zone */
- protected final SidedPlane bottomPlane;
- /** An interior point of the zone */
- protected final GeoPoint interiorPoint;
- /** Notable points: none */
- protected final static GeoPoint[] planePoints = new GeoPoint[0];
- /** A point on the bottom boundary */
- protected final GeoPoint bottomBoundaryPoint;
- /** A reference to the point on the boundary */
- protected final GeoPoint[] edgePoints;
-
- /** Constructor.
- *@param planetModel is the planet model.
- *@param bottomLat is the bottom latitude.
- */
- public GeoNorthLatitudeZone(final PlanetModel planetModel, final double bottomLat) {
- super(planetModel);
- this.bottomLat = bottomLat;
-
- final double sinBottomLat = Math.sin(bottomLat);
- this.cosBottomLat = Math.cos(bottomLat);
-
- // Compute an interior point. Pick one whose lat is between top and bottom.
- final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
- this.bottomBoundaryPoint = new GeoPoint(planetModel, sinBottomLat, 0.0, Math.sqrt(1.0 - sinBottomLat * sinBottomLat), 1.0);
-
- this.bottomPlane = new SidedPlane(interiorPoint, planetModel, sinBottomLat);
-
- this.edgePoints = new GeoPoint[]{bottomBoundaryPoint};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = Math.PI * 0.5;
- final double newBottomLat = bottomLat - angle;
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return
- bottomPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
- // would contain all the bounding box points, when starting in the "center".
- if (bottomLat < 0.0)
- return Math.PI;
- double maxCosLat = cosBottomLat;
- return maxCosLat * Math.PI;
- }
-
- @Override
- public GeoPoint getCenter() {
- return interiorPoint;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return
- p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds
- .addHorizontalPlane(planetModel, bottomLat, bottomPlane);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE)
- return OVERLAPS;
-
- final boolean insideShape = path.isWithin(bottomBoundaryPoint);
-
- if (insideRectangle == ALL_INSIDE && insideShape)
- return OVERLAPS;
-
- // Second, the shortcut of seeing whether endpoints are in/out is not going to
- // work with no area endpoints. So we rely entirely on intersections.
-
- if (path.intersects(bottomPlane, planePoints))
- return OVERLAPS;
-
- // There is another case for latitude zones only. This is when the boundaries of the shape all fit
- // within the zone, but the shape includes areas outside the zone crossing a pole.
- // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
- // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
- // one such point is within, then OVERLAPS is the right answer.
-
- if (insideShape)
- return CONTAINS;
-
- if (insideRectangle == ALL_INSIDE)
- return WITHIN;
-
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- return distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z);
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoNorthLatitudeZone))
- return false;
- GeoNorthLatitudeZone other = (GeoNorthLatitudeZone) o;
- return super.equals(other) && other.bottomBoundaryPoint.equals(bottomBoundaryPoint);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + bottomBoundaryPoint.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoNorthLatitudeZone: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthRectangle.java
deleted file mode 100644
index 66b9480..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoNorthRectangle.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Bounding box limited on three sides (bottom lat, left lon, right lon), including
- * the north pole.
- * The left-right maximum extent for this shape is PI; for anything larger, use
- * {@link GeoWideNorthRectangle}.
- *
- * @lucene.internal
- */
-public class GeoNorthRectangle extends GeoBaseBBox {
- /** The bottom latitude of the rectangle */
- protected final double bottomLat;
- /** The left longitude */
- protected final double leftLon;
- /** The right longitude */
- protected final double rightLon;
- /** Cosine of the middle latitude */
- protected final double cosMiddleLat;
- /** Lower right hand corner point */
- protected final GeoPoint LRHC;
- /** Lower left hand corner point */
- protected final GeoPoint LLHC;
- /** Bottom edge plane */
- protected final SidedPlane bottomPlane;
- /** Left-side plane */
- protected final SidedPlane leftPlane;
- /** Right-side plane */
- protected final SidedPlane rightPlane;
- /** Bottom plane notable points */
- protected final GeoPoint[] bottomPlanePoints;
- /** Left plane notable points */
- protected final GeoPoint[] leftPlanePoints;
- /** Right plane notable points */
- protected final GeoPoint[] rightPlanePoints;
- /** Center point */
- protected final GeoPoint centerPoint;
- /** A point on the edge */
- protected final GeoPoint[] edgePoints;
-
- /**
- * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
- *@param planetModel is the planet model.
- *@param bottomLat is the bottom latitude.
- *@param leftLon is the left longitude.
- *@param rightLon is the right longitude.
- */
- public GeoNorthRectangle(final PlanetModel planetModel, final double bottomLat, final double leftLon, double rightLon) {
- super(planetModel);
- // Argument checking
- if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
- throw new IllegalArgumentException("Bottom latitude out of range");
- if (leftLon < -Math.PI || leftLon > Math.PI)
- throw new IllegalArgumentException("Left longitude out of range");
- if (rightLon < -Math.PI || rightLon > Math.PI)
- throw new IllegalArgumentException("Right longitude out of range");
- double extent = rightLon - leftLon;
- if (extent < 0.0) {
- extent += 2.0 * Math.PI;
- }
- if (extent > Math.PI)
- throw new IllegalArgumentException("Width of rectangle too great");
-
- this.bottomLat = bottomLat;
- this.leftLon = leftLon;
- this.rightLon = rightLon;
-
- final double sinBottomLat = Math.sin(bottomLat);
- final double cosBottomLat = Math.cos(bottomLat);
- final double sinLeftLon = Math.sin(leftLon);
- final double cosLeftLon = Math.cos(leftLon);
- final double sinRightLon = Math.sin(rightLon);
- final double cosRightLon = Math.cos(rightLon);
-
- // Now build the points
- this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
- this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
-
- final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
- final double sinMiddleLat = Math.sin(middleLat);
- this.cosMiddleLat = Math.cos(middleLat);
- // Normalize
- while (leftLon > rightLon) {
- rightLon += Math.PI * 2.0;
- }
- final double middleLon = (leftLon + rightLon) * 0.5;
- final double sinMiddleLon = Math.sin(middleLon);
- final double cosMiddleLon = Math.cos(middleLon);
-
- this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
-
- this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
- this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
- this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
-
- this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
- this.leftPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LLHC};
- this.rightPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LRHC};
-
- this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
- }
-
- @Override
- public GeoBBox expand(final double angle) {
- final double newTopLat = Math.PI * 0.5;
- final double newBottomLat = bottomLat - angle;
- // Figuring out when we escalate to a special case requires some prefiguring
- double currentLonSpan = rightLon - leftLon;
- if (currentLonSpan < 0.0)
- currentLonSpan += Math.PI * 2.0;
- double newLeftLon = leftLon - angle;
- double newRightLon = rightLon + angle;
- if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
- newLeftLon = -Math.PI;
- newRightLon = Math.PI;
- }
- return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return
- bottomPlane.isWithin(x, y, z) &&
- leftPlane.isWithin(x, y, z) &&
- rightPlane.isWithin(x, y, z);
- }
-
- @Override
- public double getRadius() {
- // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
- // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
- // the distance to the right or left edge from the center.
- final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
- final double bottomAngle = centerPoint.arcDistance(LLHC);
- return Math.max(centerAngle, bottomAngle);
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- /**
- * Returns the center of a circle into which the area will be inscribed.
- *
- * @return the center.
- */
- @Override
- public GeoPoint getCenter() {
- return centerPoint;
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- return
- p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, leftPlane, rightPlane) ||
- p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, bottomPlane) ||
- p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, bottomPlane);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- super.getBounds(bounds);
- bounds
- .addHorizontalPlane(planetModel, bottomLat, bottomPlane, leftPlane, rightPlane)
- .addVerticalPlane(planetModel, leftLon, leftPlane, bottomPlane, rightPlane)
- .addVerticalPlane(planetModel, rightLon, rightPlane, bottomPlane, leftPlane)
- .addPoint(LLHC).addPoint(LRHC).addPoint(planetModel.NORTH_POLE);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideBBox(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
-
- if (insideRectangle == ALL_INSIDE && insideShape) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (
- path.intersects(bottomPlane, bottomPlanePoints, leftPlane, rightPlane) ||
- path.intersects(leftPlane, leftPlanePoints, bottomPlane, rightPlane) ||
- path.intersects(rightPlane, rightPlanePoints, leftPlane, bottomPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, leftPlane, rightPlane);
- final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, bottomPlane);
- final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, bottomPlane);
-
- final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
- final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
-
- return
- Math.min(
- bottomDistance,
- Math.min(
- Math.min(leftDistance, rightDistance),
- Math.min(LRHCDistance, LLHCDistance)));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoNorthRectangle))
- return false;
- GeoNorthRectangle other = (GeoNorthRectangle) o;
- return super.equals(other) && other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + LLHC.hashCode();
- result = 31 * result + LRHC.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "GeoNorthRectangle: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoOutsideDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoOutsideDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoOutsideDistance.java
deleted file mode 100644
index c1d784d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoOutsideDistance.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Implemented by Geo3D shapes that can compute the distance from a point to the closest outside edge.
- *
- * @lucene.experimental
- */
-public interface GeoOutsideDistance extends Membership {
-
- // The following methods compute distances from the shape to a point
- // expected to be OUTSIDE the shape. Typically a value of 0.0
- // is returned for points that happen to be within the shape.
-
- /**
- * Compute this shape's distance to the GeoPoint.
- * A return value of 0.0 should be returned for
- * points inside of the shape.
- * @param distanceStyle is the distance style.
- * @param point is the point to compute the distance to.
- * @return the distance.
- */
- public default double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
- return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
- }
-
- /**
- * Compute this shape's distance to the GeoPoint.
- * A return value of 0.0 should be returned for
- * points inside of the shape.
- * @param distanceStyle is the distance style.
- * @param x is the point's unit x coordinate (using U.S. convention).
- * @param y is the point's unit y coordinate (using U.S. convention).
- * @param z is the point's unit z coordinate (using U.S. convention).
- * @return the distance.
- */
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
-
-}
-
[45/50] [abbrv] lucene-solr git commit: SOLR-8799: Update CHANGES.txt
Posted by no...@apache.org.
SOLR-8799: Update CHANGES.txt
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/02523d5b
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/02523d5b
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/02523d5b
Branch: refs/heads/apiv2
Commit: 02523d5b6d7a4416265c4a36289b3dcb497ed6a6
Parents: 56ad6e5
Author: jbernste <jb...@apache.org>
Authored: Tue Mar 8 15:25:52 2016 -0500
Committer: jbernste <jb...@apache.org>
Committed: Tue Mar 8 15:25:52 2016 -0500
----------------------------------------------------------------------
solr/CHANGES.txt | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/02523d5b/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d094b58..dc7c45f 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -408,6 +408,8 @@ Other Changes
* SOLR-8766: Remove deprecated <admin> tag in solrconfig.xml and support for admin/gettableFiles
(noble, Jason Gerlowski, Varun Thacker)
+* SOLR-8799: Improve error message when tuple can't be read by SolrJ JDBC (Kevin Risden, Joel Bernstein)
+
================== 5.5.1 ==================
Bug Fixes
[18/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PlanetModel.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PlanetModel.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PlanetModel.java
deleted file mode 100644
index 395fa15..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PlanetModel.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Holds mathematical constants associated with the model of a planet.
- * @lucene.experimental
- */
-public class PlanetModel {
-
- /** Planet model corresponding to sphere. */
- public static final PlanetModel SPHERE = new PlanetModel(1.0,1.0);
-
- /** Mean radius */
- public static final double WGS84_MEAN = 6371009.0;
- /** Polar radius */
- public static final double WGS84_POLAR = 6356752.314245;
- /** Equatorial radius */
- public static final double WGS84_EQUATORIAL = 6378137.0;
- /** Planet model corresponding to WGS84 */
- public static final PlanetModel WGS84 = new PlanetModel(WGS84_EQUATORIAL/WGS84_MEAN,
- WGS84_POLAR/WGS84_MEAN);
-
- // Surface of the planet:
- // x^2/a^2 + y^2/b^2 + z^2/c^2 = 1.0
- // Scaling factors are a,b,c. geo3d can only support models where a==b, so use ab instead.
-
- /** The x/y scaling factor */
- public final double ab;
- /** The z scaling factor */
- public final double c;
- /** The inverse of ab */
- public final double inverseAb;
- /** The inverse of c */
- public final double inverseC;
- /** The square of the inverse of ab */
- public final double inverseAbSquared;
- /** The square of the inverse of c */
- public final double inverseCSquared;
- /** The flattening value */
- public final double flattening;
- /** The square ratio */
- public final double squareRatio;
-
- // We do NOT include radius, because all computations in geo3d are in radians, not meters.
-
- // Compute north and south pole for planet model, since these are commonly used.
-
- /** North pole */
- public final GeoPoint NORTH_POLE;
- /** South pole */
- public final GeoPoint SOUTH_POLE;
- /** Min X pole */
- public final GeoPoint MIN_X_POLE;
- /** Max X pole */
- public final GeoPoint MAX_X_POLE;
- /** Min Y pole */
- public final GeoPoint MIN_Y_POLE;
- /** Max Y pole */
- public final GeoPoint MAX_Y_POLE;
-
- /** Constructor.
- * @param ab is the x/y scaling factor.
- * @param c is the z scaling factor.
- */
- public PlanetModel(final double ab, final double c) {
- this.ab = ab;
- this.c = c;
- this.inverseAb = 1.0 / ab;
- this.inverseC = 1.0 / c;
- this.flattening = (ab - c) * inverseAb;
- this.squareRatio = (ab * ab - c * c) / (c * c);
- this.inverseAbSquared = inverseAb * inverseAb;
- this.inverseCSquared = inverseC * inverseC;
- this.NORTH_POLE = new GeoPoint(c, 0.0, 0.0, 1.0, Math.PI * 0.5, 0.0);
- this.SOUTH_POLE = new GeoPoint(c, 0.0, 0.0, -1.0, -Math.PI * 0.5, 0.0);
- this.MIN_X_POLE = new GeoPoint(ab, -1.0, 0.0, 0.0, 0.0, -Math.PI);
- this.MAX_X_POLE = new GeoPoint(ab, 1.0, 0.0, 0.0, 0.0, 0.0);
- this.MIN_Y_POLE = new GeoPoint(ab, 0.0, -1.0, 0.0, 0.0, -Math.PI * 0.5);
- this.MAX_Y_POLE = new GeoPoint(ab, 0.0, 1.0, 0.0, 0.0, Math.PI * 0.5);
- }
-
- /** Find the minimum magnitude of all points on the ellipsoid.
- * @return the minimum magnitude for the planet.
- */
- public double getMinimumMagnitude() {
- return Math.min(this.ab, this.c);
- }
-
- /** Find the maximum magnitude of all points on the ellipsoid.
- * @return the maximum magnitude for the planet.
- */
- public double getMaximumMagnitude() {
- return Math.max(this.ab, this.c);
- }
-
- /** Find the minimum x value.
- *@return the minimum X value.
- */
- public double getMinimumXValue() {
- return -this.ab;
- }
-
- /** Find the maximum x value.
- *@return the maximum X value.
- */
- public double getMaximumXValue() {
- return this.ab;
- }
-
- /** Find the minimum y value.
- *@return the minimum Y value.
- */
- public double getMinimumYValue() {
- return -this.ab;
- }
-
- /** Find the maximum y value.
- *@return the maximum Y value.
- */
- public double getMaximumYValue() {
- return this.ab;
- }
-
- /** Find the minimum z value.
- *@return the minimum Z value.
- */
- public double getMinimumZValue() {
- return -this.c;
- }
-
- /** Find the maximum z value.
- *@return the maximum Z value.
- */
- public double getMaximumZValue() {
- return this.c;
- }
-
- /** Check if point is on surface.
- * @param v is the point to check.
- * @return true if the point is on the planet surface.
- */
- public boolean pointOnSurface(final Vector v) {
- return pointOnSurface(v.x, v.y, v.z);
- }
-
- /** Check if point is on surface.
- * @param x is the x coord.
- * @param y is the y coord.
- * @param z is the z coord.
- */
- public boolean pointOnSurface(final double x, final double y, final double z) {
- // Equation of planet surface is:
- // x^2 / a^2 + y^2 / b^2 + z^2 / c^2 - 1 = 0
- return Math.abs(x * x * inverseAb * inverseAb + y * y * inverseAb * inverseAb + z * z * inverseC * inverseC - 1.0) < Vector.MINIMUM_RESOLUTION;
- }
-
- /** Check if point is outside surface.
- * @param v is the point to check.
- * @return true if the point is outside the planet surface.
- */
- public boolean pointOutside(final Vector v) {
- return pointOutside(v.x, v.y, v.z);
- }
-
- /** Check if point is outside surface.
- * @param x is the x coord.
- * @param y is the y coord.
- * @param z is the z coord.
- */
- public boolean pointOutside(final double x, final double y, final double z) {
- // Equation of planet surface is:
- // x^2 / a^2 + y^2 / b^2 + z^2 / c^2 - 1 = 0
- return (x * x + y * y) * inverseAb * inverseAb + z * z * inverseC * inverseC - 1.0 > Vector.MINIMUM_RESOLUTION;
- }
-
- /** Compute surface distance between two points.
- * @param p1 is the first point.
- * @param p2 is the second point.
- * @return the adjusted angle, when multiplied by the mean earth radius, yields a surface distance. This will differ
- * from GeoPoint.arcDistance() only when the planet model is not a sphere. @see {@link org.apache.lucene.geo3d.GeoPoint#arcDistance(GeoPoint)}
- */
- public double surfaceDistance(final GeoPoint p1, final GeoPoint p2) {
- final double latA = p1.getLatitude();
- final double lonA = p1.getLongitude();
- final double latB = p2.getLatitude();
- final double lonB = p2.getLongitude();
-
- final double L = lonB - lonA;
- final double oF = 1.0 - this.flattening;
- final double U1 = Math.atan(oF * Math.tan(latA));
- final double U2 = Math.atan(oF * Math.tan(latB));
- final double sU1 = Math.sin(U1);
- final double cU1 = Math.cos(U1);
- final double sU2 = Math.sin(U2);
- final double cU2 = Math.cos(U2);
-
- double sigma, sinSigma, cosSigma;
- double cos2Alpha, cos2SigmaM;
-
- double lambda = L;
- double iters = 100;
-
- do {
- final double sinLambda = Math.sin(lambda);
- final double cosLambda = Math.cos(lambda);
- sinSigma = Math.sqrt((cU2 * sinLambda) * (cU2 * sinLambda) + (cU1 * sU2 - sU1 * cU2 * cosLambda)
- * (cU1 * sU2 - sU1 * cU2 * cosLambda));
- if (Math.abs(sinSigma) < Vector.MINIMUM_RESOLUTION)
- return 0.0;
-
- cosSigma = sU1 * sU2 + cU1 * cU2 * cosLambda;
- sigma = Math.atan2(sinSigma, cosSigma);
- final double sinAlpha = cU1 * cU2 * sinLambda / sinSigma;
- cos2Alpha = 1.0 - sinAlpha * sinAlpha;
- cos2SigmaM = cosSigma - 2.0 * sU1 * sU2 / cos2Alpha;
-
- final double c = this.flattening * 0.625 * cos2Alpha * (4.0 + this.flattening * (4.0 - 3.0 * cos2Alpha));
- final double lambdaP = lambda;
- lambda = L + (1.0 - c) * this.flattening * sinAlpha * (sigma + c * sinSigma * (cos2SigmaM + c * cosSigma *
- (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM)));
- if (Math.abs(lambda - lambdaP) < Vector.MINIMUM_RESOLUTION)
- break;
- } while (--iters > 0);
-
- if (iters == 0)
- return 0.0;
-
- final double uSq = cos2Alpha * this.squareRatio;
- final double A = 1.0 + uSq * 0.00006103515625 * (4096.0 + uSq * (-768.0 + uSq * (320.0 - 175.0 * uSq)));
- final double B = uSq * 0.0009765625 * (256.0 + uSq * (-128.0 + uSq * (74.0 - 47.0 * uSq)));
- final double deltaSigma = B * sinSigma * (cos2SigmaM + B * 0.25 * (cosSigma * (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM) - B * 0.16666666666666666666667 * cos2SigmaM
- * (-3.0 + 4.0 * sinSigma * sinSigma) * (-3.0 + 4.0 * cos2SigmaM * cos2SigmaM)));
-
- return this.c * A * (sigma - deltaSigma);
- }
-
- @Override
- public boolean equals(final Object o) {
- if (!(o instanceof PlanetModel))
- return false;
- final PlanetModel other = (PlanetModel)o;
- return ab == other.ab && c == other.c;
- }
-
- @Override
- public int hashCode() {
- return Double.hashCode(ab) + Double.hashCode(c);
- }
-
- @Override
- public String toString() {
- if (this.equals(SPHERE)) {
- return "PlanetModel.SPHERE";
- } else if (this.equals(WGS84)) {
- return "PlanetModel.WGS84";
- } else {
- return "PlanetModel(ab="+ab+" c="+c+")";
- }
- }
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java
deleted file mode 100644
index 9e2132d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/PointInGeo3DShapeQuery.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.io.IOException;
-
-import org.apache.lucene.index.PointValues.IntersectVisitor;
-import org.apache.lucene.index.PointValues;
-import org.apache.lucene.index.PointValues.Relation;
-import org.apache.lucene.index.LeafReader;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.ConstantScoreScorer;
-import org.apache.lucene.search.ConstantScoreWeight;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Weight;
-import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.NumericUtils;
-
-/** Finds all previously indexed points that fall within the specified polygon.
- *
- * <p>The field must be indexed using {@link Geo3DPoint}.
- *
- * @lucene.experimental */
-
-class PointInGeo3DShapeQuery extends Query {
- final String field;
- final GeoShape shape;
-
- /** The lats/lons must be clockwise or counter-clockwise. */
- public PointInGeo3DShapeQuery(String field, GeoShape shape) {
- this.field = field;
- this.shape = shape;
-
- if (shape instanceof BasePlanetObject) {
- BasePlanetObject planetObject = (BasePlanetObject) shape;
- if (planetObject.getPlanetModel().equals(PlanetModel.WGS84) == false) {
- throw new IllegalArgumentException("this qurey requires PlanetModel.WGS84, but got: " + planetObject.getPlanetModel());
- }
- }
- }
-
- @Override
- public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-
- // I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
- // used in the first pass:
-
- return new ConstantScoreWeight(this) {
-
- @Override
- public Scorer scorer(LeafReaderContext context) throws IOException {
- LeafReader reader = context.reader();
- PointValues values = reader.getPointValues();
- if (values == null) {
- return null;
- }
-
- /*
- XYZBounds bounds = new XYZBounds();
- shape.getBounds(bounds);
-
- final double planetMax = planetModel.getMaximumMagnitude();
- if (planetMax != treeDV.planetMax) {
- throw new IllegalStateException(planetModel + " is not the same one used during indexing: planetMax=" + planetMax + " vs indexing planetMax=" + treeDV.planetMax);
- }
- */
-
- /*
- GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(planetModel,
- bounds.getMinimumX(),
- bounds.getMaximumX(),
- bounds.getMinimumY(),
- bounds.getMaximumY(),
- bounds.getMinimumZ(),
- bounds.getMaximumZ());
-
- assert xyzSolid.getRelationship(shape) == GeoArea.WITHIN || xyzSolid.getRelationship(shape) == GeoArea.OVERLAPS: "expected WITHIN (1) or OVERLAPS (2) but got " + xyzSolid.getRelationship(shape) + "; shape="+shape+"; XYZSolid="+xyzSolid;
- */
-
- double planetMax = PlanetModel.WGS84.getMaximumMagnitude();
-
- DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc());
-
- values.intersect(field,
- new IntersectVisitor() {
-
- @Override
- public void visit(int docID) {
- result.add(docID);
- }
-
- @Override
- public void visit(int docID, byte[] packedValue) {
- assert packedValue.length == 12;
- double x = Geo3DPoint.decodeDimension(packedValue, 0);
- double y = Geo3DPoint.decodeDimension(packedValue, Integer.BYTES);
- double z = Geo3DPoint.decodeDimension(packedValue, 2 * Integer.BYTES);
- if (shape.isWithin(x, y, z)) {
- result.add(docID);
- }
- }
-
- @Override
- public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
- // Because the dimensional format operates in quantized (64 bit -> 32 bit) space, and the cell bounds
- // here are inclusive, we need to extend the bounds to the largest un-quantized values that
- // could quantize into these bounds. The encoding (Geo3DUtil.encodeValue) does
- // a Math.round from double to long, so e.g. 1.4 -> 1, and -1.4 -> -1:
- double xMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 0));
- double xMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 0));
- double yMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 1 * Integer.BYTES));
- double yMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 1 * Integer.BYTES));
- double zMin = Geo3DUtil.decodeValueMin(planetMax, NumericUtils.sortableBytesToInt(minPackedValue, 2 * Integer.BYTES));
- double zMax = Geo3DUtil.decodeValueMax(planetMax, NumericUtils.sortableBytesToInt(maxPackedValue, 2 * Integer.BYTES));
-
- //System.out.println(" compare: x=" + cellXMin + "-" + cellXMax + " y=" + cellYMin + "-" + cellYMax + " z=" + cellZMin + "-" + cellZMax);
- assert xMin <= xMax;
- assert yMin <= yMax;
- assert zMin <= zMax;
-
- GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, xMin, xMax, yMin, yMax, zMin, zMax);
-
- switch(xyzSolid.getRelationship(shape)) {
- case GeoArea.CONTAINS:
- // Shape fully contains the cell
- //System.out.println(" inside");
- return Relation.CELL_INSIDE_QUERY;
- case GeoArea.OVERLAPS:
- // They do overlap but neither contains the other:
- //System.out.println(" crosses1");
- return Relation.CELL_CROSSES_QUERY;
- case GeoArea.WITHIN:
- // Cell fully contains the shape:
- //System.out.println(" crosses2");
- // return Relation.SHAPE_INSIDE_CELL;
- return Relation.CELL_CROSSES_QUERY;
- case GeoArea.DISJOINT:
- // They do not overlap at all
- //System.out.println(" outside");
- return Relation.CELL_OUTSIDE_QUERY;
- default:
- assert false;
- return Relation.CELL_CROSSES_QUERY;
- }
- }
- });
-
- return new ConstantScoreScorer(this, score(), result.build().iterator());
- }
- };
- }
-
- public String getField() {
- return field;
- }
-
- public GeoShape getShape() {
- return shape;
- }
-
- @Override
- @SuppressWarnings({"unchecked","rawtypes"})
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- if (!super.equals(o)) return false;
-
- PointInGeo3DShapeQuery that = (PointInGeo3DShapeQuery) o;
-
- return shape.equals(that.shape);
- }
-
- @Override
- public final int hashCode() {
- int result = super.hashCode();
- result = 31 * result + shape.hashCode();
- return result;
- }
-
- @Override
- public String toString(String field) {
- final StringBuilder sb = new StringBuilder();
- sb.append(getClass().getSimpleName());
- sb.append(':');
- if (this.field.equals(field) == false) {
- sb.append(" field=");
- sb.append(this.field);
- sb.append(':');
- }
- sb.append(" Shape: ");
- sb.append(shape);
- return sb.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/SidedPlane.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/SidedPlane.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/SidedPlane.java
deleted file mode 100755
index 7fc543d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/SidedPlane.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Combination of a plane, and a sign value indicating what evaluation values are on the correct
- * side of the plane.
- *
- * @lucene.experimental
- */
-public class SidedPlane extends Plane implements Membership {
- /** The sign value for evaluation of a point on the correct side of the plane */
- public final double sigNum;
-
- /**
- * Construct a SidedPlane identical to an existing one, but reversed.
- *
- * @param sidedPlane is the existing plane.
- */
- public SidedPlane(SidedPlane sidedPlane) {
- super(sidedPlane, sidedPlane.D);
- this.sigNum = -sidedPlane.sigNum;
- }
-
- /**
- * Construct a sided plane from a pair of vectors describing points, and including
- * origin, plus a point p which describes the side.
- *
- * @param p point to evaluate
- * @param A is the first in-plane point
- * @param B is the second in-plane point
- */
- public SidedPlane(Vector p, Vector A, Vector B) {
- super(A, B);
- sigNum = Math.signum(evaluate(p));
- if (sigNum == 0.0)
- throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
- }
-
- /**
- * Construct a sided plane from a point and a Z coordinate.
- *
- * @param p point to evaluate.
- * @param planetModel is the planet model.
- * @param sinLat is the sin of the latitude of the plane.
- */
- public SidedPlane(Vector p, final PlanetModel planetModel, double sinLat) {
- super(planetModel, sinLat);
- sigNum = Math.signum(evaluate(p));
- if (sigNum == 0.0)
- throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
- }
-
- /**
- * Construct a sided vertical plane from a point and specified x and y coordinates.
- *
- * @param p point to evaluate.
- * @param x is the specified x.
- * @param y is the specified y.
- */
- public SidedPlane(Vector p, double x, double y) {
- super(x, y);
- sigNum = Math.signum(evaluate(p));
- if (sigNum == 0.0)
- throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
- }
-
- /**
- * Construct a sided plane with a normal vector and offset.
- *
- * @param p point to evaluate.
- * @param v is the normal vector.
- * @param D is the origin offset for the plan.
- */
- public SidedPlane(Vector p, Vector v, double D) {
- super(v, D);
- sigNum = Math.signum(evaluate(p));
- if (sigNum == 0.0)
- throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
- }
-
- /**
- * Construct a sided plane with a normal vector and offset.
- *
- * @param pX X coord of point to evaluate.
- * @param pY Y coord of point to evaluate.
- * @param pZ Z coord of point to evaluate.
- * @param v is the normal vector.
- * @param D is the origin offset for the plan.
- */
- public SidedPlane(double pX, double pY, double pZ, Vector v, double D) {
- super(v, D);
- sigNum = Math.signum(evaluate(pX,pY,pZ));
- if (sigNum == 0.0)
- throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
- }
-
- /** Construct a sided plane from two points and a third normal vector.
- */
- public static SidedPlane constructNormalizedPerpendicularSidedPlane(final Vector insidePoint,
- final Vector normalVector, final Vector point1, final Vector point2) {
- final Vector pointsVector = new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z);
- final Vector newNormalVector = new Vector(normalVector, pointsVector);
- try {
- // To construct the plane, we now just need D, which is simply the negative of the evaluation of the circle normal vector at one of the points.
- return new SidedPlane(insidePoint, newNormalVector, -newNormalVector.dotProduct(point1));
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-
- /** Construct a sided plane from three points.
- */
- public static SidedPlane constructNormalizedThreePointSidedPlane(final Vector insidePoint,
- final Vector point1, final Vector point2, final Vector point3) {
- try {
- final Vector planeNormal = new Vector(
- new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z),
- new Vector(point2.x - point3.x, point2.y - point3.y, point2.z - point3.z));
- return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-
- @Override
- public boolean isWithin(double x, double y, double z) {
- double evalResult = evaluate(x, y, z);
- if (Math.abs(evalResult) < MINIMUM_RESOLUTION)
- return true;
- double sigNum = Math.signum(evalResult);
- return sigNum == this.sigNum;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof SidedPlane)) return false;
- if (!super.equals(o)) return false;
-
- SidedPlane that = (SidedPlane) o;
-
- return Double.compare(that.sigNum, sigNum) == 0;
-
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp;
- temp = Double.doubleToLongBits(sigNum);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "[A=" + x + ", B=" + y + ", C=" + z + ", D=" + D + ", side=" + sigNum + "]";
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/StandardXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/StandardXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/StandardXYZSolid.java
deleted file mode 100644
index cd54225..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/StandardXYZSolid.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits
- *
- * @lucene.internal
- */
-public class StandardXYZSolid extends BaseXYZSolid {
-
- /** Whole world? */
- protected final boolean isWholeWorld;
- /** Min-X plane */
- protected final SidedPlane minXPlane;
- /** Max-X plane */
- protected final SidedPlane maxXPlane;
- /** Min-Y plane */
- protected final SidedPlane minYPlane;
- /** Max-Y plane */
- protected final SidedPlane maxYPlane;
- /** Min-Z plane */
- protected final SidedPlane minZPlane;
- /** Max-Z plane */
- protected final SidedPlane maxZPlane;
-
- /** These are the edge points of the shape, which are defined to be at least one point on
- * each surface area boundary. In the case of a solid, this includes points which represent
- * the intersection of XYZ bounding planes and the planet, as well as points representing
- * the intersection of single bounding planes with the planet itself.
- */
- protected final GeoPoint[] edgePoints;
-
- /** Notable points for minXPlane */
- protected final GeoPoint[] notableMinXPoints;
- /** Notable points for maxXPlane */
- protected final GeoPoint[] notableMaxXPoints;
- /** Notable points for minYPlane */
- protected final GeoPoint[] notableMinYPoints;
- /** Notable points for maxYPlane */
- protected final GeoPoint[] notableMaxYPoints;
- /** Notable points for minZPlane */
- protected final GeoPoint[] notableMinZPoints;
- /** Notable points for maxZPlane */
- protected final GeoPoint[] notableMaxZPoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param minX is the minimum X value.
- *@param maxX is the maximum X value.
- *@param minY is the minimum Y value.
- *@param maxY is the maximum Y value.
- *@param minZ is the minimum Z value.
- *@param maxZ is the maximum Z value.
- */
- public StandardXYZSolid(final PlanetModel planetModel,
- final double minX,
- final double maxX,
- final double minY,
- final double maxY,
- final double minZ,
- final double maxZ) {
- super(planetModel);
- // Argument checking
- if (maxX - minX < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("X values in wrong order or identical");
- if (maxY - minY < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Y values in wrong order or identical");
- if (maxZ - minZ < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Z values in wrong order or identical");
-
- final double worldMinX = planetModel.getMinimumXValue();
- final double worldMaxX = planetModel.getMaximumXValue();
- final double worldMinY = planetModel.getMinimumYValue();
- final double worldMaxY = planetModel.getMaximumYValue();
- final double worldMinZ = planetModel.getMinimumZValue();
- final double worldMaxZ = planetModel.getMaximumZValue();
-
- // We must distinguish between the case where the solid represents the entire world,
- // and when the solid has no overlap with any part of the surface. In both cases,
- // there will be no edgepoints.
- isWholeWorld =
- (minX - worldMinX < -Vector.MINIMUM_RESOLUTION) &&
- (maxX - worldMaxX > Vector.MINIMUM_RESOLUTION) &&
- (minY - worldMinY < -Vector.MINIMUM_RESOLUTION) &&
- (maxY - worldMaxY > Vector.MINIMUM_RESOLUTION) &&
- (minZ - worldMinZ < -Vector.MINIMUM_RESOLUTION) &&
- (maxZ - worldMaxZ > Vector.MINIMUM_RESOLUTION);
-
- if (isWholeWorld) {
- minXPlane = null;
- maxXPlane = null;
- minYPlane = null;
- maxYPlane = null;
- minZPlane = null;
- maxZPlane = null;
- notableMinXPoints = null;
- notableMaxXPoints = null;
- notableMinYPoints = null;
- notableMaxYPoints = null;
- notableMinZPoints = null;
- notableMaxZPoints = null;
- edgePoints = null;
- } else {
- // Construct the planes
- minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
- maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
- minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
- maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
- minZPlane = new SidedPlane(0.0,0.0,maxZ,zUnitVector,-minZ);
- maxZPlane = new SidedPlane(0.0,0.0,minZ,zUnitVector,-maxZ);
-
- // We need at least one point on the planet surface for each manifestation of the shape.
- // There can be up to 2 (on opposite sides of the world). But we have to go through
- // 12 combinations of adjacent planes in order to find out if any have 2 intersection solution.
- // Typically, this requires 12 square root operations.
- final GeoPoint[] minXminY = minXPlane.findIntersections(planetModel,minYPlane,maxXPlane,maxYPlane,minZPlane,maxZPlane);
- final GeoPoint[] minXmaxY = minXPlane.findIntersections(planetModel,maxYPlane,maxXPlane,minYPlane,minZPlane,maxZPlane);
- final GeoPoint[] minXminZ = minXPlane.findIntersections(planetModel,minZPlane,maxXPlane,maxZPlane,minYPlane,maxYPlane);
- final GeoPoint[] minXmaxZ = minXPlane.findIntersections(planetModel,maxZPlane,maxXPlane,minZPlane,minYPlane,maxYPlane);
-
- final GeoPoint[] maxXminY = maxXPlane.findIntersections(planetModel,minYPlane,minXPlane,maxYPlane,minZPlane,maxZPlane);
- final GeoPoint[] maxXmaxY = maxXPlane.findIntersections(planetModel,maxYPlane,minXPlane,minYPlane,minZPlane,maxZPlane);
- final GeoPoint[] maxXminZ = maxXPlane.findIntersections(planetModel,minZPlane,minXPlane,maxZPlane,minYPlane,maxYPlane);
- final GeoPoint[] maxXmaxZ = maxXPlane.findIntersections(planetModel,maxZPlane,minXPlane,minZPlane,minYPlane,maxYPlane);
-
- final GeoPoint[] minYminZ = minYPlane.findIntersections(planetModel,minZPlane,maxYPlane,maxZPlane,minXPlane,maxXPlane);
- final GeoPoint[] minYmaxZ = minYPlane.findIntersections(planetModel,maxZPlane,maxYPlane,minZPlane,minXPlane,maxXPlane);
- final GeoPoint[] maxYminZ = maxYPlane.findIntersections(planetModel,minZPlane,minYPlane,maxZPlane,minXPlane,maxXPlane);
- final GeoPoint[] maxYmaxZ = maxYPlane.findIntersections(planetModel,maxZPlane,minYPlane,minZPlane,minXPlane,maxXPlane);
-
- notableMinXPoints = glueTogether(minXminY, minXmaxY, minXminZ, minXmaxZ);
- notableMaxXPoints = glueTogether(maxXminY, maxXmaxY, maxXminZ, maxXmaxZ);
- notableMinYPoints = glueTogether(minXminY, maxXminY, minYminZ, minYmaxZ);
- notableMaxYPoints = glueTogether(minXmaxY, maxXmaxY, maxYminZ, maxYmaxZ);
- notableMinZPoints = glueTogether(minXminZ, maxXminZ, minYminZ, maxYminZ);
- notableMaxZPoints = glueTogether(minXmaxZ, maxXmaxZ, minYmaxZ, maxYmaxZ);
-
- // Now, compute the edge points.
- // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
- // we'll start there.
- // There can be a number of shapes, each of which needs an edgepoint. Each side by itself might contribute
- // an edgepoint, for instance, if the plane describing that side intercepts the planet in such a way that the ellipse
- // of interception does not meet any other planes. Plane intersections can each contribute 0, 1, or 2 edgepoints.
- //
- // All of this makes for a lot of potential edgepoints, but I believe these can be pruned back with careful analysis.
- // I haven't yet done that analysis, however, so I will treat them all as individual edgepoints.
-
- // The cases we are looking for are when the four corner points for any given
- // plane are all outside of the world, AND that plane intersects the world.
- // There are eight corner points all told; we must evaluate these WRT the planet surface.
- final boolean minXminYminZ = planetModel.pointOutside(minX, minY, minZ);
- final boolean minXminYmaxZ = planetModel.pointOutside(minX, minY, maxZ);
- final boolean minXmaxYminZ = planetModel.pointOutside(minX, maxY, minZ);
- final boolean minXmaxYmaxZ = planetModel.pointOutside(minX, maxY, maxZ);
- final boolean maxXminYminZ = planetModel.pointOutside(maxX, minY, minZ);
- final boolean maxXminYmaxZ = planetModel.pointOutside(maxX, minY, maxZ);
- final boolean maxXmaxYminZ = planetModel.pointOutside(maxX, maxY, minZ);
- final boolean maxXmaxYmaxZ = planetModel.pointOutside(maxX, maxY, maxZ);
-
- // Look at single-plane/world intersections.
- // We detect these by looking at the world model and noting its x, y, and z bounds.
-
- final GeoPoint[] minXEdges;
- if (minX - worldMinX >= -Vector.MINIMUM_RESOLUTION && minX - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
- minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
- minXminYminZ && minXminYmaxZ && minXmaxYminZ && minXmaxYmaxZ) {
- // Find any point on the minX plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = minXPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
- if (intPoint != null) {
- minXEdges = new GeoPoint[]{intPoint};
- } else {
- // No intersection found?
- minXEdges = EMPTY_POINTS;
- }
- } else {
- minXEdges = EMPTY_POINTS;
- }
-
- final GeoPoint[] maxXEdges;
- if (maxX - worldMinX >= -Vector.MINIMUM_RESOLUTION && maxX - worldMaxX <= Vector.MINIMUM_RESOLUTION &&
- minY < 0.0 && maxY > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
- maxXminYminZ && maxXminYmaxZ && maxXmaxYminZ && maxXmaxYmaxZ) {
- // Find any point on the maxX plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = maxXPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
- if (intPoint != null) {
- maxXEdges = new GeoPoint[]{intPoint};
- } else {
- maxXEdges = EMPTY_POINTS;
- }
- } else {
- maxXEdges = EMPTY_POINTS;
- }
-
- final GeoPoint[] minYEdges;
- if (minY - worldMinY >= -Vector.MINIMUM_RESOLUTION && minY - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
- minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
- minXminYminZ && minXminYmaxZ && maxXminYminZ && maxXminYmaxZ) {
- // Find any point on the minY plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = minYPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
- if (intPoint != null) {
- minYEdges = new GeoPoint[]{intPoint};
- } else {
- minYEdges = EMPTY_POINTS;
- }
- } else {
- minYEdges = EMPTY_POINTS;
- }
-
- final GeoPoint[] maxYEdges;
- if (maxY - worldMinY >= -Vector.MINIMUM_RESOLUTION && maxY - worldMaxY <= Vector.MINIMUM_RESOLUTION &&
- minX < 0.0 && maxX > 0.0 && minZ < 0.0 && maxZ > 0.0 &&
- minXmaxYminZ && minXmaxYmaxZ && maxXmaxYminZ && maxXmaxYmaxZ) {
- // Find any point on the maxY plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (0,1,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = maxYPlane.getSampleIntersectionPoint(planetModel, yVerticalPlane);
- if (intPoint != null) {
- maxYEdges = new GeoPoint[]{intPoint};
- } else {
- maxYEdges = EMPTY_POINTS;
- }
- } else {
- maxYEdges = EMPTY_POINTS;
- }
-
- final GeoPoint[] minZEdges;
- if (minZ - worldMinZ >= -Vector.MINIMUM_RESOLUTION && minZ - worldMaxZ <= Vector.MINIMUM_RESOLUTION &&
- minX < 0.0 && maxX > 0.0 && minY < 0.0 && maxY > 0.0 &&
- minXminYminZ && minXmaxYminZ && maxXminYminZ && maxXmaxYminZ) {
- // Find any point on the minZ plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = minZPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
- if (intPoint != null) {
- minZEdges = new GeoPoint[]{intPoint};
- } else {
- minZEdges = EMPTY_POINTS;
- }
- } else {
- minZEdges = EMPTY_POINTS;
- }
-
- final GeoPoint[] maxZEdges;
- if (maxZ - worldMinZ >= -Vector.MINIMUM_RESOLUTION && maxZ - worldMaxZ <= Vector.MINIMUM_RESOLUTION &&
- minX < 0.0 && maxX > 0.0 && minY < 0.0 && maxY > 0.0 &&
- minXminYmaxZ && minXmaxYmaxZ && maxXminYmaxZ && maxXmaxYmaxZ) {
- // Find any point on the maxZ plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (1,0,0) (that is, its orientation doesn't matter)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = maxZPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
- if (intPoint != null) {
- maxZEdges = new GeoPoint[]{intPoint};
- } else {
- maxZEdges = EMPTY_POINTS;
- }
- } else {
- maxZEdges = EMPTY_POINTS;
- }
-
- // Glue everything together. This is not a minimal set of edgepoints, as of now, but it does completely describe all shapes on the
- // planet.
- this.edgePoints = glueTogether(minXminY, minXmaxY, minXminZ, minXmaxZ,
- maxXminY, maxXmaxY, maxXminZ, maxXmaxZ,
- minYminZ, minYmaxZ, maxYminZ, maxYmaxZ,
- minXEdges, maxXEdges, minYEdges, maxYEdges, minZEdges, maxZEdges);
- }
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- if (isWholeWorld) {
- return true;
- }
- return minXPlane.isWithin(x, y, z) &&
- maxXPlane.isWithin(x, y, z) &&
- minYPlane.isWithin(x, y, z) &&
- maxYPlane.isWithin(x, y, z) &&
- minZPlane.isWithin(x, y, z) &&
- maxZPlane.isWithin(x, y, z);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
- if (isWholeWorld) {
- if (path.getEdgePoints().length > 0)
- return WITHIN;
- return OVERLAPS;
- }
-
- /*
- for (GeoPoint p : getEdgePoints()) {
- System.err.println(" Edge point "+p+" path.isWithin()? "+path.isWithin(p));
- }
-
- for (GeoPoint p : path.getEdgePoints()) {
- System.err.println(" path edge point "+p+" isWithin()? "+isWithin(p)+" minx="+minXPlane.evaluate(p)+" maxx="+maxXPlane.evaluate(p)+" miny="+minYPlane.evaluate(p)+" maxy="+maxYPlane.evaluate(p)+" minz="+minZPlane.evaluate(p)+" maxz="+maxZPlane.evaluate(p));
- }
- */
-
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some shape points inside area");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- //System.err.println(" some area points inside shape");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(minXPlane, notableMinXPoints, maxXPlane, minYPlane, maxYPlane, minZPlane, maxZPlane) ||
- path.intersects(maxXPlane, notableMaxXPoints, minXPlane, minYPlane, maxYPlane, minZPlane, maxZPlane) ||
- path.intersects(minYPlane, notableMinYPoints, maxYPlane, minXPlane, maxXPlane, minZPlane, maxZPlane) ||
- path.intersects(maxYPlane, notableMaxYPoints, minYPlane, minXPlane, maxXPlane, minZPlane, maxZPlane) ||
- path.intersects(minZPlane, notableMinZPoints, maxZPlane, minXPlane, maxXPlane, minYPlane, maxYPlane) ||
- path.intersects(maxZPlane, notableMaxZPoints, minZPlane, minXPlane, maxXPlane, minYPlane, maxYPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" all shape points inside area");
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" all area points inside shape");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof StandardXYZSolid))
- return false;
- StandardXYZSolid other = (StandardXYZSolid) o;
- if (!super.equals(other) ||
- other.isWholeWorld != isWholeWorld) {
- return false;
- }
- if (!isWholeWorld) {
- return other.minXPlane.equals(minXPlane) &&
- other.maxXPlane.equals(maxXPlane) &&
- other.minYPlane.equals(minYPlane) &&
- other.maxYPlane.equals(maxYPlane) &&
- other.minZPlane.equals(minZPlane) &&
- other.maxZPlane.equals(maxZPlane);
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (isWholeWorld?1:0);
- if (!isWholeWorld) {
- result = 31 * result + minXPlane.hashCode();
- result = 31 * result + maxXPlane.hashCode();
- result = 31 * result + minYPlane.hashCode();
- result = 31 * result + maxYPlane.hashCode();
- result = 31 * result + minZPlane.hashCode();
- result = 31 * result + maxZPlane.hashCode();
- }
- return result;
- }
-
- @Override
- public String toString() {
- return "StandardXYZSolid: {planetmodel="+planetModel+", isWholeWorld="+isWholeWorld+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", minZplane="+minZPlane+", maxZplane="+maxZPlane+"}";
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Tools.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Tools.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Tools.java
deleted file mode 100755
index 89d37aa..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Tools.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Static methods globally useful for 3d geometric work.
- *
- * @lucene.experimental
- */
-public class Tools {
- private Tools() {
- }
-
- /**
- * Java acos yields a NAN if you take an arc-cos of an
- * angle that's just a tiny bit greater than 1.0, so
- * here's a more resilient version.
- */
- public static double safeAcos(double value) {
- if (value > 1.0)
- value = 1.0;
- else if (value < -1.0)
- value = -1.0;
- return Math.acos(value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Vector.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Vector.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Vector.java
deleted file mode 100755
index 1a3972d..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Vector.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * A 3d vector in space, not necessarily
- * going through the origin.
- *
- * @lucene.experimental
- */
-public class Vector {
- /**
- * Values that are all considered to be essentially zero have a magnitude
- * less than this.
- */
- public static final double MINIMUM_RESOLUTION = 1.0e-12;
- /**
- * For squared quantities, the bound is squared too.
- */
- public static final double MINIMUM_RESOLUTION_SQUARED = MINIMUM_RESOLUTION * MINIMUM_RESOLUTION;
- /**
- * For cubed quantities, cube the bound.
- */
- public static final double MINIMUM_RESOLUTION_CUBED = MINIMUM_RESOLUTION_SQUARED * MINIMUM_RESOLUTION;
-
- /** The x value */
- public final double x;
- /** The y value */
- public final double y;
- /** The z value */
- public final double z;
-
- /**
- * Construct from (U.S.) x,y,z coordinates.
- *@param x is the x value.
- *@param y is the y value.
- *@param z is the z value.
- */
- public Vector(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- /**
- * Construct a vector that is perpendicular to
- * two other (non-zero) vectors. If the vectors are parallel,
- * IllegalArgumentException will be thrown.
- * Produces a normalized final vector.
- *
- * @param A is the first vector
- * @param B is the second
- */
- public Vector(final Vector A, final Vector B) {
- // x = u2v3 - u3v2
- // y = u3v1 - u1v3
- // z = u1v2 - u2v1
- final double thisX = A.y * B.z - A.z * B.y;
- final double thisY = A.z * B.x - A.x * B.z;
- final double thisZ = A.x * B.y - A.y * B.x;
- final double magnitude = magnitude(thisX, thisY, thisZ);
- if (Math.abs(magnitude) < MINIMUM_RESOLUTION) {
- throw new IllegalArgumentException("Degenerate/parallel vector constructed");
- }
- final double inverseMagnitude = 1.0 / magnitude;
- this.x = thisX * inverseMagnitude;
- this.y = thisY * inverseMagnitude;
- this.z = thisZ * inverseMagnitude;
- }
-
- /** Compute a magnitude of an x,y,z value.
- */
- public static double magnitude(final double x, final double y, final double z) {
- return Math.sqrt(x*x + y*y + z*z);
- }
-
- /**
- * Compute a normalized unit vector based on the current vector.
- *
- * @return the normalized vector, or null if the current vector has
- * a magnitude of zero.
- */
- public Vector normalize() {
- double denom = magnitude();
- if (denom < MINIMUM_RESOLUTION)
- // Degenerate, can't normalize
- return null;
- double normFactor = 1.0 / denom;
- return new Vector(x * normFactor, y * normFactor, z * normFactor);
- }
-
- /**
- * Do a dot product.
- *
- * @param v is the vector to multiply.
- * @return the result.
- */
- public double dotProduct(final Vector v) {
- return this.x * v.x + this.y * v.y + this.z * v.z;
- }
-
- /**
- * Do a dot product.
- *
- * @param x is the x value of the vector to multiply.
- * @param y is the y value of the vector to multiply.
- * @param z is the z value of the vector to multiply.
- * @return the result.
- */
- public double dotProduct(final double x, final double y, final double z) {
- return this.x * x + this.y * y + this.z * z;
- }
-
- /**
- * Determine if this vector, taken from the origin,
- * describes a point within a set of planes.
- *
- * @param bounds is the first part of the set of planes.
- * @param moreBounds is the second part of the set of planes.
- * @return true if the point is within the bounds.
- */
- public boolean isWithin(final Membership[] bounds, final Membership[] moreBounds) {
- // Return true if the point described is within all provided bounds
- //System.err.println(" checking if "+this+" is within bounds");
- for (Membership bound : bounds) {
- if (bound != null && !bound.isWithin(this)) {
- //System.err.println(" NOT within "+bound);
- return false;
- }
- }
- for (Membership bound : moreBounds) {
- if (bound != null && !bound.isWithin(this)) {
- //System.err.println(" NOT within "+bound);
- return false;
- }
- }
- //System.err.println(" is within");
- return true;
- }
-
- /**
- * Translate vector.
- */
- public Vector translate(final double xOffset, final double yOffset, final double zOffset) {
- return new Vector(x - xOffset, y - yOffset, z - zOffset);
- }
-
- /**
- * Rotate vector counter-clockwise in x-y by an angle.
- */
- public Vector rotateXY(final double angle) {
- return rotateXY(Math.sin(angle), Math.cos(angle));
- }
-
- /**
- * Rotate vector counter-clockwise in x-y by an angle, expressed as sin and cos.
- */
- public Vector rotateXY(final double sinAngle, final double cosAngle) {
- return new Vector(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z);
- }
-
- /**
- * Rotate vector counter-clockwise in x-z by an angle.
- */
- public Vector rotateXZ(final double angle) {
- return rotateXZ(Math.sin(angle), Math.cos(angle));
- }
-
- /**
- * Rotate vector counter-clockwise in x-z by an angle, expressed as sin and cos.
- */
- public Vector rotateXZ(final double sinAngle, final double cosAngle) {
- return new Vector(x * cosAngle - z * sinAngle, y, x * sinAngle + z * cosAngle);
- }
-
- /**
- * Rotate vector counter-clockwise in z-y by an angle.
- */
- public Vector rotateZY(final double angle) {
- return rotateZY(Math.sin(angle), Math.cos(angle));
- }
-
- /**
- * Rotate vector counter-clockwise in z-y by an angle, expressed as sin and cos.
- */
- public Vector rotateZY(final double sinAngle, final double cosAngle) {
- return new Vector(x, z * sinAngle + y * cosAngle, z * cosAngle - y * sinAngle);
- }
-
- /**
- * Compute the square of a straight-line distance to a point described by the
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI.
- *
- * @param v is the vector to compute a distance to.
- * @return the square of the linear distance.
- */
- public double linearDistanceSquared(final Vector v) {
- double deltaX = this.x - v.x;
- double deltaY = this.y - v.y;
- double deltaZ = this.z - v.z;
- return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
- }
-
- /**
- * Compute the square of a straight-line distance to a point described by the
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI.
- *
- * @param x is the x part of the vector to compute a distance to.
- * @param y is the y part of the vector to compute a distance to.
- * @param z is the z part of the vector to compute a distance to.
- * @return the square of the linear distance.
- */
- public double linearDistanceSquared(final double x, final double y, final double z) {
- double deltaX = this.x - x;
- double deltaY = this.y - y;
- double deltaZ = this.z - z;
- return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
- }
-
- /**
- * Compute the straight-line distance to a point described by the
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI.
- *
- * @param v is the vector to compute a distance to.
- * @return the linear distance.
- */
- public double linearDistance(final Vector v) {
- return Math.sqrt(linearDistanceSquared(v));
- }
-
- /**
- * Compute the straight-line distance to a point described by the
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI.
- *
- * @param x is the x part of the vector to compute a distance to.
- * @param y is the y part of the vector to compute a distance to.
- * @param z is the z part of the vector to compute a distance to.
- * @return the linear distance.
- */
- public double linearDistance(final double x, final double y, final double z) {
- return Math.sqrt(linearDistanceSquared(x, y, z));
- }
-
- /**
- * Compute the square of the normal distance to a vector described by a
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI/2.
- *
- * @param v is the vector to compute a distance to.
- * @return the square of the normal distance.
- */
- public double normalDistanceSquared(final Vector v) {
- double t = dotProduct(v);
- double deltaX = this.x * t - v.x;
- double deltaY = this.y * t - v.y;
- double deltaZ = this.z * t - v.z;
- return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
- }
-
- /**
- * Compute the square of the normal distance to a vector described by a
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI/2.
- *
- * @param x is the x part of the vector to compute a distance to.
- * @param y is the y part of the vector to compute a distance to.
- * @param z is the z part of the vector to compute a distance to.
- * @return the square of the normal distance.
- */
- public double normalDistanceSquared(final double x, final double y, final double z) {
- double t = dotProduct(x, y, z);
- double deltaX = this.x * t - x;
- double deltaY = this.y * t - y;
- double deltaZ = this.z * t - z;
- return deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
- }
-
- /**
- * Compute the normal (perpendicular) distance to a vector described by a
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI/2.
- *
- * @param v is the vector to compute a distance to.
- * @return the normal distance.
- */
- public double normalDistance(final Vector v) {
- return Math.sqrt(normalDistanceSquared(v));
- }
-
- /**
- * Compute the normal (perpendicular) distance to a vector described by a
- * vector taken from the origin.
- * Monotonically increasing for arc distances up to PI/2.
- *
- * @param x is the x part of the vector to compute a distance to.
- * @param y is the y part of the vector to compute a distance to.
- * @param z is the z part of the vector to compute a distance to.
- * @return the normal distance.
- */
- public double normalDistance(final double x, final double y, final double z) {
- return Math.sqrt(normalDistanceSquared(x, y, z));
- }
-
- /**
- * Compute the magnitude of this vector.
- *
- * @return the magnitude.
- */
- public double magnitude() {
- return magnitude(x,y,z);
- }
-
- /** 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 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 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 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))
- return false;
- Vector other = (Vector) o;
- return (other.x == x && other.y == y && other.z == z);
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- temp = Double.doubleToLongBits(x);
- result = (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(y);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(z);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "[X=" + x + ", Y=" + y + ", Z=" + z + "]";
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZBounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZBounds.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZBounds.java
deleted file mode 100644
index 22e324b..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZBounds.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * An object for accumulating XYZ bounds information.
- *
- * @lucene.experimental
- */
-public class XYZBounds implements Bounds {
-
- /** A 'fudge factor', which is added to maximums and subtracted from minimums,
- * in order to compensate for potential error deltas. This would not be necessary
- * except that our 'bounds' is defined as always equaling or exceeding the boundary
- * of the shape, and we cannot guarantee that without making MINIMUM_RESOLUTION
- * unacceptably large.
- */
- protected static final double FUDGE_FACTOR = Vector.MINIMUM_RESOLUTION * 2.0;
-
- /** Minimum x */
- protected Double minX = null;
- /** Maximum x */
- protected Double maxX = null;
- /** Minimum y */
- protected Double minY = null;
- /** Maximum y */
- protected Double maxY = null;
- /** Minimum z */
- protected Double minZ = null;
- /** Maximum z */
- protected Double maxZ = null;
-
- /** Set to true if no longitude bounds can be stated */
- protected boolean noLongitudeBound = false;
- /** Set to true if no top latitude bound can be stated */
- protected boolean noTopLatitudeBound = false;
- /** Set to true if no bottom latitude bound can be stated */
- protected boolean noBottomLatitudeBound = false;
-
- /** Construct an empty bounds object */
- public XYZBounds() {
- }
-
- // Accessor methods
-
- /** Return the minimum X value.
- *@return minimum X value.
- */
- public Double getMinimumX() {
- return minX;
- }
-
- /** Return the maximum X value.
- *@return maximum X value.
- */
- public Double getMaximumX() {
- return maxX;
- }
-
- /** Return the minimum Y value.
- *@return minimum Y value.
- */
- public Double getMinimumY() {
- return minY;
- }
-
- /** Return the maximum Y value.
- *@return maximum Y value.
- */
- public Double getMaximumY() {
- return maxY;
- }
-
- /** Return the minimum Z value.
- *@return minimum Z value.
- */
- public Double getMinimumZ() {
- return minZ;
- }
-
- /** Return the maximum Z value.
- *@return maximum Z value.
- */
- public Double getMaximumZ() {
- return maxZ;
- }
-
- /** Return true if minX is as small as the planet model allows.
- *@return true if minX has reached its bound.
- */
- public boolean isSmallestMinX(final PlanetModel planetModel) {
- if (minX == null)
- return false;
- return minX - planetModel.getMinimumXValue() < Vector.MINIMUM_RESOLUTION;
- }
-
- /** Return true if maxX is as large as the planet model allows.
- *@return true if maxX has reached its bound.
- */
- public boolean isLargestMaxX(final PlanetModel planetModel) {
- if (maxX == null)
- return false;
- return planetModel.getMaximumXValue() - maxX < Vector.MINIMUM_RESOLUTION;
- }
-
- /** Return true if minY is as small as the planet model allows.
- *@return true if minY has reached its bound.
- */
- public boolean isSmallestMinY(final PlanetModel planetModel) {
- if (minY == null)
- return false;
- return minY - planetModel.getMinimumYValue() < Vector.MINIMUM_RESOLUTION;
- }
-
- /** Return true if maxY is as large as the planet model allows.
- *@return true if maxY has reached its bound.
- */
- public boolean isLargestMaxY(final PlanetModel planetModel) {
- if (maxY == null)
- return false;
- return planetModel.getMaximumYValue() - maxY < Vector.MINIMUM_RESOLUTION;
- }
-
- /** Return true if minZ is as small as the planet model allows.
- *@return true if minZ has reached its bound.
- */
- public boolean isSmallestMinZ(final PlanetModel planetModel) {
- if (minZ == null)
- return false;
- return minZ - planetModel.getMinimumZValue() < Vector.MINIMUM_RESOLUTION;
- }
-
- /** Return true if maxZ is as large as the planet model allows.
- *@return true if maxZ has reached its bound.
- */
- public boolean isLargestMaxZ(final PlanetModel planetModel) {
- if (maxZ == null)
- return false;
- return planetModel.getMaximumZValue() - maxZ < Vector.MINIMUM_RESOLUTION;
- }
-
- // Modification methods
-
- @Override
- public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds) {
- plane.recordBounds(planetModel, this, bounds);
- return this;
- }
-
- /** Add a horizontal plane to the bounds description.
- * This method should EITHER use the supplied latitude, OR use the supplied
- * plane, depending on what is most efficient.
- *@param planetModel is the planet model.
- *@param latitude is the latitude.
- *@param horizontalPlane is the plane.
- *@param bounds are the constraints on the plane.
- *@return updated Bounds object.
- */
- public Bounds addHorizontalPlane(final PlanetModel planetModel,
- final double latitude,
- final Plane horizontalPlane,
- final Membership... bounds) {
- return addPlane(planetModel, horizontalPlane, bounds);
- }
-
- /** Add a vertical plane to the bounds description.
- * This method should EITHER use the supplied longitude, OR use the supplied
- * plane, depending on what is most efficient.
- *@param planetModel is the planet model.
- *@param longitude is the longitude.
- *@param verticalPlane is the plane.
- *@param bounds are the constraints on the plane.
- *@return updated Bounds object.
- */
- public Bounds addVerticalPlane(final PlanetModel planetModel,
- final double longitude,
- final Plane verticalPlane,
- final Membership... bounds) {
- return addPlane(planetModel, verticalPlane, bounds);
- }
-
- @Override
- public Bounds addXValue(final GeoPoint point) {
- final double x = point.x;
- final double small = x - FUDGE_FACTOR;
- if (minX == null || minX > small) {
- minX = new Double(small);
- }
- final double large = x + FUDGE_FACTOR;
- if (maxX == null || maxX < large) {
- maxX = new Double(large);
- }
- return this;
- }
-
- @Override
- public Bounds addYValue(final GeoPoint point) {
- final double y = point.y;
- final double small = y - FUDGE_FACTOR;
- if (minY == null || minY > small) {
- minY = new Double(small);
- }
- final double large = y + FUDGE_FACTOR;
- if (maxY == null || maxY < large) {
- maxY = new Double(large);
- }
- return this;
- }
-
- @Override
- public Bounds addZValue(final GeoPoint point) {
- final double z = point.z;
- final double small = z - FUDGE_FACTOR;
- if (minZ == null || minZ > small) {
- minZ = new Double(small);
- }
- final double large = z + FUDGE_FACTOR;
- if (maxZ == null || maxZ < large) {
- maxZ = new Double(large);
- }
- return this;
- }
-
- @Override
- public Bounds addPoint(final GeoPoint point) {
- return addXValue(point).addYValue(point).addZValue(point);
- }
-
- @Override
- public Bounds isWide() {
- // No specific thing we need to do.
- return this;
- }
-
- @Override
- public Bounds noLongitudeBound() {
- // No specific thing we need to do.
- return this;
- }
-
- @Override
- public Bounds noTopLatitudeBound() {
- // No specific thing we need to do.
- return this;
- }
-
- @Override
- public Bounds noBottomLatitudeBound() {
- // No specific thing we need to do.
- return this;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolid.java
deleted file mode 100644
index ab46402..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolid.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Interface for a family of 3D rectangles, bounded on six sides by X,Y,Z limits
- *
- * @lucene.internal
- */
-public interface XYZSolid extends GeoArea {
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolidFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolidFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolidFactory.java
deleted file mode 100644
index 409ba86..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYZSolidFactory.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Factory for {@link org.apache.lucene.geo3d.XYZSolid}.
- *
- * @lucene.experimental
- */
-public class XYZSolidFactory {
- private XYZSolidFactory() {
- }
-
- /**
- * Create a XYZSolid of the right kind given (x,y,z) bounds.
- * @param planetModel is the planet model
- * @param minX is the min X boundary
- * @param maxX is the max X boundary
- * @param minY is the min Y boundary
- * @param maxY is the max Y boundary
- * @param minZ is the min Z boundary
- * @param maxZ is the max Z boundary
- */
- public static XYZSolid makeXYZSolid(final PlanetModel planetModel, final double minX, final double maxX, final double minY, final double maxY, final double minZ, final double maxZ) {
- if (Math.abs(maxX - minX) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(maxY - minY) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
- return new dXdYdZSolid(planetModel, (minX+maxX) * 0.5, (minY+maxY) * 0.5, minZ);
- } else {
- return new dXdYZSolid(planetModel, (minX+maxX) * 0.5, (minY+maxY) * 0.5, minZ, maxZ);
- }
- } else {
- if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
- return new dXYdZSolid(planetModel, (minX+maxX) * 0.5, minY, maxY, (minZ+maxZ) * 0.5);
- } else {
- return new dXYZSolid(planetModel, (minX+maxX) * 0.5, minY, maxY, minZ, maxZ);
- }
- }
- }
- if (Math.abs(maxY - minY) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
- return new XdYdZSolid(planetModel, minX, maxX, (minY+maxY) * 0.5, (minZ+maxZ) * 0.5);
- } else {
- return new XdYZSolid(planetModel, minX, maxX, (minY+maxY) * 0.5, minZ, maxZ);
- }
- }
- if (Math.abs(maxZ - minZ) < Vector.MINIMUM_RESOLUTION) {
- return new XYdZSolid(planetModel, minX, maxX, minY, maxY, (minZ+maxZ) * 0.5);
- }
- return new StandardXYZSolid(planetModel, minX, maxX, minY, maxY, minZ, maxZ);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYdZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYdZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYdZSolid.java
deleted file mode 100644
index e7cbe25..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/XYdZSolid.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * 3D rectangle, bounded on six sides by X,Y,Z limits, degenerate in Z
- *
- * @lucene.internal
- */
-public class XYdZSolid extends BaseXYZSolid {
-
- /** Min-X plane */
- protected final SidedPlane minXPlane;
- /** Max-X plane */
- protected final SidedPlane maxXPlane;
- /** Min-Y plane */
- protected final SidedPlane minYPlane;
- /** Max-Y plane */
- protected final SidedPlane maxYPlane;
- /** Z plane */
- protected final Plane zPlane;
-
- /** These are the edge points of the shape, which are defined to be at least one point on
- * each surface area boundary. In the case of a solid, this includes points which represent
- * the intersection of XYZ bounding planes and the planet, as well as points representing
- * the intersection of single bounding planes with the planet itself.
- */
- protected final GeoPoint[] edgePoints;
-
- /** Notable points for ZPlane */
- protected final GeoPoint[] notableZPoints;
-
- /**
- * Sole constructor
- *
- *@param planetModel is the planet model.
- *@param minX is the minimum X value.
- *@param maxX is the maximum X value.
- *@param minY is the minimum Y value.
- *@param maxY is the maximum Y value.
- *@param Z is the Z value.
- */
- public XYdZSolid(final PlanetModel planetModel,
- final double minX,
- final double maxX,
- final double minY,
- final double maxY,
- final double Z) {
- super(planetModel);
- // Argument checking
- if (maxX - minX < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("X values in wrong order or identical");
- if (maxY - minY < Vector.MINIMUM_RESOLUTION)
- throw new IllegalArgumentException("Y values in wrong order or identical");
-
- final double worldMinZ = planetModel.getMinimumZValue();
- final double worldMaxZ = planetModel.getMaximumZValue();
-
- // Construct the planes
- minXPlane = new SidedPlane(maxX,0.0,0.0,xUnitVector,-minX);
- maxXPlane = new SidedPlane(minX,0.0,0.0,xUnitVector,-maxX);
- minYPlane = new SidedPlane(0.0,maxY,0.0,yUnitVector,-minY);
- maxYPlane = new SidedPlane(0.0,minY,0.0,yUnitVector,-maxY);
- zPlane = new Plane(zUnitVector,-Z);
-
- // We need at least one point on the planet surface for each manifestation of the shape.
- // There can be up to 2 (on opposite sides of the world). But we have to go through
- // 4 combinations of adjacent planes in order to find out if any have 2 intersection solution.
- // Typically, this requires 4 square root operations.
- final GeoPoint[] minXZ = minXPlane.findIntersections(planetModel,zPlane,maxXPlane,minYPlane,maxYPlane);
- final GeoPoint[] maxXZ = maxXPlane.findIntersections(planetModel,zPlane,minXPlane,minYPlane,maxYPlane);
- final GeoPoint[] minYZ = minYPlane.findIntersections(planetModel,zPlane,maxYPlane,minXPlane,maxXPlane);
- final GeoPoint[] maxYZ = maxYPlane.findIntersections(planetModel,zPlane,minYPlane,minXPlane,maxXPlane);
-
- notableZPoints = glueTogether(minXZ, maxXZ, minYZ, maxYZ);
-
- // Now, compute the edge points.
- // This is the trickiest part of setting up an XYZSolid. We've computed intersections already, so
- // we'll start there. We know that at most there will be two disconnected shapes on the planet surface.
- // But there's also a case where exactly one plane slices through the world, and none of the bounding plane
- // intersections do. Thus, if we don't find any of the edge intersection cases, we have to look for that last case.
-
- // If we still haven't encountered anything, we need to look at single-plane/world intersections.
- // We detect these by looking at the world model and noting its x, y, and z bounds.
- // The cases we are looking for are when the four corner points for any given
- // plane are all outside of the world, AND that plane intersects the world.
- // There are four corner points all told; we must evaluate these WRT the planet surface.
- final boolean minXminYZ = planetModel.pointOutside(minX, minY, Z);
- final boolean minXmaxYZ = planetModel.pointOutside(minX, maxY, Z);
- final boolean maxXminYZ = planetModel.pointOutside(maxX, minY, Z);
- final boolean maxXmaxYZ = planetModel.pointOutside(maxX, maxY, Z);
-
- final GeoPoint[] zEdges;
- if (Z - worldMinZ >= -Vector.MINIMUM_RESOLUTION && Z - worldMaxZ <= Vector.MINIMUM_RESOLUTION &&
- minX < 0.0 && maxX > 0.0 && minY < 0.0 && maxY > 0.0 &&
- minXminYZ && minXmaxYZ && maxXminYZ && maxXmaxYZ) {
- // Find any point on the minZ plane that intersects the world
- // First construct a perpendicular plane that will allow us to find a sample point.
- // This plane is vertical and goes through the points (0,0,0) and (1,0,0)
- // Then use it to compute a sample point.
- final GeoPoint intPoint = zPlane.getSampleIntersectionPoint(planetModel, xVerticalPlane);
- if (intPoint != null) {
- zEdges = new GeoPoint[]{intPoint};
- } else {
- zEdges = EMPTY_POINTS;
- }
- } else {
- zEdges= EMPTY_POINTS;
- }
-
- this.edgePoints = glueTogether(minXZ, maxXZ, minYZ, maxYZ, zEdges);
- }
-
- @Override
- protected GeoPoint[] getEdgePoints() {
- return edgePoints;
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- return minXPlane.isWithin(x, y, z) &&
- maxXPlane.isWithin(x, y, z) &&
- minYPlane.isWithin(x, y, z) &&
- maxYPlane.isWithin(x, y, z) &&
- zPlane.evaluateIsZero(x, y, z);
- }
-
- @Override
- public int getRelationship(final GeoShape path) {
-
- //System.err.println(this+" getrelationship with "+path);
- final int insideRectangle = isShapeInsideArea(path);
- if (insideRectangle == SOME_INSIDE) {
- //System.err.println(" some inside");
- return OVERLAPS;
- }
-
- // Figure out if the entire XYZArea is contained by the shape.
- final int insideShape = isAreaInsideShape(path);
- if (insideShape == SOME_INSIDE) {
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE && insideShape == ALL_INSIDE) {
- //System.err.println(" inside of each other");
- return OVERLAPS;
- }
-
- if (path.intersects(zPlane, notableZPoints, minXPlane, maxXPlane, minYPlane, maxYPlane)) {
- //System.err.println(" edges intersect");
- return OVERLAPS;
- }
-
- if (insideRectangle == ALL_INSIDE) {
- //System.err.println(" shape inside rectangle");
- return WITHIN;
- }
-
- if (insideShape == ALL_INSIDE) {
- //System.err.println(" shape contains rectangle");
- return CONTAINS;
- }
- //System.err.println(" disjoint");
- return DISJOINT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof XYdZSolid))
- return false;
- XYdZSolid other = (XYdZSolid) o;
- if (!super.equals(other)) {
- return false;
- }
- return other.minXPlane.equals(minXPlane) &&
- other.maxXPlane.equals(maxXPlane) &&
- other.minYPlane.equals(minYPlane) &&
- other.maxYPlane.equals(maxYPlane) &&
- other.zPlane.equals(zPlane);
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + minXPlane.hashCode();
- result = 31 * result + maxXPlane.hashCode();
- result = 31 * result + minYPlane.hashCode();
- result = 31 * result + maxYPlane.hashCode();
- result = 31 * result + zPlane.hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "XYdZSolid: {planetmodel="+planetModel+", minXplane="+minXPlane+", maxXplane="+maxXPlane+", minYplane="+minYPlane+", maxYplane="+maxYPlane+", zplane="+zPlane+"}";
- }
-
-}
-
[12/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
new file mode 100755
index 0000000..1f2c054
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
@@ -0,0 +1,1657 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * We know about three kinds of planes. First kind: general plain through two points and origin
+ * Second kind: horizontal plane at specified height. Third kind: vertical plane with specified x and y value, through origin.
+ *
+ * @lucene.experimental
+ */
+public class Plane extends Vector {
+ /** An array with no points in it */
+ protected final static GeoPoint[] NO_POINTS = new GeoPoint[0];
+ /** An array with no bounds in it */
+ protected final static Membership[] NO_BOUNDS = new Membership[0];
+ /** A vertical plane normal to the Y axis */
+ protected final static Plane normalYPlane = new Plane(0.0,1.0,0.0,0.0);
+ /** A vertical plane normal to the X axis */
+ protected final static Plane normalXPlane = new Plane(1.0,0.0,0.0,0.0);
+ /** A vertical plane normal to the Z axis */
+ protected final static Plane normalZPlane = new Plane(0.0,0.0,1.0,0.0);
+
+ /** Ax + By + Cz + D = 0 */
+ public final double D;
+
+ /**
+ * Construct a plane with all four coefficients defined.
+ *@param A is A
+ *@param B is B
+ *@param C is C
+ *@param D is D
+ */
+ public Plane(final double A, final double B, final double C, final double D) {
+ super(A, B, C);
+ this.D = D;
+ }
+
+ /**
+ * Construct a plane through two points and origin.
+ *
+ * @param A is the first point (origin based).
+ * @param B is the second point (origin based).
+ */
+ public Plane(final Vector A, final Vector B) {
+ super(A, B);
+ D = 0.0;
+ }
+
+ /**
+ * Construct a horizontal plane at a specified Z.
+ *
+ * @param planetModel is the planet model.
+ * @param sinLat is the sin(latitude).
+ */
+ public Plane(final PlanetModel planetModel, final double sinLat) {
+ super(0.0, 0.0, 1.0);
+ D = -sinLat * computeDesiredEllipsoidMagnitude(planetModel, sinLat);
+ }
+
+ /**
+ * Construct a vertical plane through a specified
+ * x, y and origin.
+ *
+ * @param x is the specified x value.
+ * @param y is the specified y value.
+ */
+ public Plane(final double x, final double y) {
+ super(y, -x, 0.0);
+ D = 0.0;
+ }
+
+ /**
+ * Construct a plane with a specific vector, and D offset
+ * from origin.
+ * @param v is the normal vector.
+ * @param D is the D offset from the origin.
+ */
+ public Plane(final Vector v, final double D) {
+ super(v.x, v.y, v.z);
+ this.D = D;
+ }
+
+ /** Construct the most accurate normalized plane through an x-y point and including the Z axis.
+ * If none of the points can determine the plane, return null.
+ * @param planePoints is a set of points to choose from. The best one for constructing the most precise plane is picked.
+ * @return the plane
+ */
+ public static Plane constructNormalizedZPlane(final Vector... planePoints) {
+ // Pick the best one (with the greatest x-y distance)
+ double bestDistance = 0.0;
+ Vector bestPoint = null;
+ for (final Vector point : planePoints) {
+ final double pointDist = point.x * point.x + point.y * point.y;
+ if (pointDist > bestDistance) {
+ bestDistance = pointDist;
+ bestPoint = point;
+ }
+ }
+ return constructNormalizedZPlane(bestPoint.x, bestPoint.y);
+ }
+
+ /** Construct the most accurate normalized plane through an x-z point and including the Y axis.
+ * If none of the points can determine the plane, return null.
+ * @param planePoints is a set of points to choose from. The best one for constructing the most precise plane is picked.
+ * @return the plane
+ */
+ public static Plane constructNormalizedYPlane(final Vector... planePoints) {
+ // Pick the best one (with the greatest x-z distance)
+ double bestDistance = 0.0;
+ Vector bestPoint = null;
+ for (final Vector point : planePoints) {
+ final double pointDist = point.x * point.x + point.z * point.z;
+ if (pointDist > bestDistance) {
+ bestDistance = pointDist;
+ bestPoint = point;
+ }
+ }
+ return constructNormalizedYPlane(bestPoint.x, bestPoint.z, 0.0);
+ }
+
+ /** Construct the most accurate normalized plane through an y-z point and including the X axis.
+ * If none of the points can determine the plane, return null.
+ * @param planePoints is a set of points to choose from. The best one for constructing the most precise plane is picked.
+ * @return the plane
+ */
+ public static Plane constructNormalizedXPlane(final Vector... planePoints) {
+ // Pick the best one (with the greatest y-z distance)
+ double bestDistance = 0.0;
+ Vector bestPoint = null;
+ for (final Vector point : planePoints) {
+ final double pointDist = point.y * point.y + point.z * point.z;
+ if (pointDist > bestDistance) {
+ bestDistance = pointDist;
+ bestPoint = point;
+ }
+ }
+ return constructNormalizedXPlane(bestPoint.y, bestPoint.z, 0.0);
+ }
+
+ /** Construct a normalized plane through an x-y point and including the Z axis.
+ * If the x-y point is at (0,0), return null.
+ * @param x is the x value.
+ * @param y is the y value.
+ * @return a plane passing through the Z axis and (x,y,0).
+ */
+ public static Plane constructNormalizedZPlane(final double x, final double y) {
+ if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(y) < MINIMUM_RESOLUTION)
+ return null;
+ final double denom = 1.0 / Math.sqrt(x*x + y*y);
+ return new Plane(y * denom, -x * denom, 0.0, 0.0);
+ }
+
+ /** Construct a normalized plane through an x-z point and parallel to the Y axis.
+ * If the x-z point is at (0,0), return null.
+ * @param x is the x value.
+ * @param z is the z value.
+ * @param DValue is the offset from the origin for the plane.
+ * @return a plane parallel to the Y axis and perpendicular to the x and z values given.
+ */
+ public static Plane constructNormalizedYPlane(final double x, final double z, final double DValue) {
+ if (Math.abs(x) < MINIMUM_RESOLUTION && Math.abs(z) < MINIMUM_RESOLUTION)
+ return null;
+ final double denom = 1.0 / Math.sqrt(x*x + z*z);
+ return new Plane(z * denom, 0.0, -x * denom, DValue);
+ }
+
+ /** Construct a normalized plane through a y-z point and parallel to the X axis.
+ * If the y-z point is at (0,0), return null.
+ * @param y is the y value.
+ * @param z is the z value.
+ * @param DValue is the offset from the origin for the plane.
+ * @return a plane parallel to the X axis and perpendicular to the y and z values given.
+ */
+ public static Plane constructNormalizedXPlane(final double y, final double z, final double DValue) {
+ if (Math.abs(y) < MINIMUM_RESOLUTION && Math.abs(z) < MINIMUM_RESOLUTION)
+ return null;
+ final double denom = 1.0 / Math.sqrt(y*y + z*z);
+ return new Plane(0.0, z * denom, -y * denom, DValue);
+ }
+
+ /**
+ * Evaluate the plane equation for a given point, as represented
+ * by a vector.
+ *
+ * @param v is the vector.
+ * @return the result of the evaluation.
+ */
+ public double evaluate(final Vector v) {
+ return dotProduct(v) + D;
+ }
+
+ /**
+ * Evaluate the plane equation for a given point, as represented
+ * by a vector.
+ * @param x is the x value.
+ * @param y is the y value.
+ * @param z is the z value.
+ * @return the result of the evaluation.
+ */
+ public double evaluate(final double x, final double y, final double z) {
+ return dotProduct(x, y, z) + D;
+ }
+
+ /**
+ * Evaluate the plane equation for a given point, as represented
+ * by a vector.
+ *
+ * @param v is the vector.
+ * @return true if the result is on the plane.
+ */
+ public boolean evaluateIsZero(final Vector v) {
+ return Math.abs(evaluate(v)) < MINIMUM_RESOLUTION;
+ }
+
+ /**
+ * Evaluate the plane equation for a given point, as represented
+ * by a vector.
+ *
+ * @param x is the x value.
+ * @param y is the y value.
+ * @param z is the z value.
+ * @return true if the result is on the plane.
+ */
+ public boolean evaluateIsZero(final double x, final double y, final double z) {
+ return Math.abs(evaluate(x, y, z)) < MINIMUM_RESOLUTION;
+ }
+
+ /**
+ * Build a normalized plane, so that the vector is normalized.
+ *
+ * @return the normalized plane object, or null if the plane is indeterminate.
+ */
+ public Plane normalize() {
+ Vector normVect = super.normalize();
+ if (normVect == null)
+ return null;
+ return new Plane(normVect, this.D);
+ }
+
+ /** Compute arc distance from plane to a vector expressed with a {@link GeoPoint}.
+ * @see #arcDistance(PlanetModel, double, double, double, Membership...) */
+ public double arcDistance(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
+ return arcDistance(planetModel, v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute arc distance from plane to a vector.
+ * @param planetModel is the planet model.
+ * @param x is the x vector value.
+ * @param y is the y vector value.
+ * @param z is the z vector value.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the arc distance.
+ */
+ public double arcDistance(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
+
+ if (evaluateIsZero(x,y,z)) {
+ if (meetsAllBounds(x,y,z, bounds))
+ return 0.0;
+ return Double.MAX_VALUE;
+ }
+
+ // First, compute the perpendicular plane.
+ final Plane perpPlane = new Plane(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x, 0.0);
+
+ // We need to compute the intersection of two planes on the geo surface: this one, and its perpendicular.
+ // Then, we need to choose which of the two points we want to compute the distance to. We pick the
+ // shorter distance always.
+
+ final GeoPoint[] intersectionPoints = findIntersections(planetModel, perpPlane);
+
+ // For each point, compute a linear distance, and take the minimum of them
+ double minDistance = Double.MAX_VALUE;
+
+ for (final GeoPoint intersectionPoint : intersectionPoints) {
+ if (meetsAllBounds(intersectionPoint, bounds)) {
+ final double theDistance = intersectionPoint.arcDistance(x,y,z);
+ if (theDistance < minDistance) {
+ minDistance = theDistance;
+ }
+ }
+ }
+ return minDistance;
+
+ }
+
+ /**
+ * Compute normal distance from plane to a vector.
+ * @param v is the vector.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the normal distance.
+ */
+ public double normalDistance(final Vector v, final Membership... bounds) {
+ return normalDistance(v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute normal distance from plane to a vector.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the normal distance.
+ */
+ public double normalDistance(final double x, final double y, final double z, final Membership... bounds) {
+
+ final double dist = evaluate(x,y,z);
+ final double perpX = x - dist * this.x;
+ final double perpY = y - dist * this.y;
+ final double perpZ = z - dist * this.z;
+
+ if (!meetsAllBounds(perpX, perpY, perpZ, bounds)) {
+ return Double.MAX_VALUE;
+ }
+
+ return Math.abs(dist);
+ }
+
+ /**
+ * Compute normal distance squared from plane to a vector.
+ * @param v is the vector.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the normal distance squared.
+ */
+ public double normalDistanceSquared(final Vector v, final Membership... bounds) {
+ return normalDistanceSquared(v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute normal distance squared from plane to a vector.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the normal distance squared.
+ */
+ public double normalDistanceSquared(final double x, final double y, final double z, final Membership... bounds) {
+ final double normal = normalDistance(x,y,z,bounds);
+ if (normal == Double.MAX_VALUE)
+ return normal;
+ return normal * normal;
+ }
+
+ /**
+ * Compute linear distance from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param planetModel is the planet model.
+ * @param v is the point.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the linear distance.
+ */
+ public double linearDistance(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
+ return linearDistance(planetModel, v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute linear distance from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param planetModel is the planet model.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the linear distance.
+ */
+ public double linearDistance(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
+ if (evaluateIsZero(x,y,z)) {
+ if (meetsAllBounds(x,y,z, bounds))
+ return 0.0;
+ return Double.MAX_VALUE;
+ }
+
+ // First, compute the perpendicular plane.
+ final Plane perpPlane = new Plane(this.y * z - this.z * y, this.z * x - this.x * z, this.x * y - this.y * x, 0.0);
+
+ // We need to compute the intersection of two planes on the geo surface: this one, and its perpendicular.
+ // Then, we need to choose which of the two points we want to compute the distance to. We pick the
+ // shorter distance always.
+
+ final GeoPoint[] intersectionPoints = findIntersections(planetModel, perpPlane);
+
+ // For each point, compute a linear distance, and take the minimum of them
+ double minDistance = Double.MAX_VALUE;
+
+ for (final GeoPoint intersectionPoint : intersectionPoints) {
+ if (meetsAllBounds(intersectionPoint, bounds)) {
+ final double theDistance = intersectionPoint.linearDistance(x,y,z);
+ if (theDistance < minDistance) {
+ minDistance = theDistance;
+ }
+ }
+ }
+ return minDistance;
+ }
+
+ /**
+ * Compute linear distance squared from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param planetModel is the planet model.
+ * @param v is the point.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the linear distance squared.
+ */
+ public double linearDistanceSquared(final PlanetModel planetModel, final GeoPoint v, final Membership... bounds) {
+ return linearDistanceSquared(planetModel, v.x, v.y, v.z, bounds);
+ }
+
+ /**
+ * Compute linear distance squared from plane to a vector. This is defined
+ * as the distance from the given point to the nearest intersection of
+ * this plane with the planet surface.
+ * @param planetModel is the planet model.
+ * @param x is the vector x.
+ * @param y is the vector y.
+ * @param z is the vector z.
+ * @param bounds are the bounds which constrain the intersection point.
+ * @return the linear distance squared.
+ */
+ public double linearDistanceSquared(final PlanetModel planetModel, final double x, final double y, final double z, final Membership... bounds) {
+ final double linearDistance = linearDistance(planetModel, x, y, z, bounds);
+ return linearDistance * linearDistance;
+ }
+
+ /**
+ * Find points on the boundary of the intersection of a plane and the unit sphere,
+ * given a starting point, and ending point, and a list of proportions of the arc (e.g. 0.25, 0.5, 0.75).
+ * The angle between the starting point and ending point is assumed to be less than pi.
+ * @param start is the start point.
+ * @param end is the end point.
+ * @param proportions is an array of fractional proportions measured between start and end.
+ * @return an array of points corresponding to the proportions passed in.
+ */
+ public GeoPoint[] interpolate(final GeoPoint start, final GeoPoint end, final double[] proportions) {
+ // Steps:
+ // (1) Translate (x0,y0,z0) of endpoints into origin-centered place:
+ // x1 = x0 + D*A
+ // y1 = y0 + D*B
+ // z1 = z0 + D*C
+ // (2) Rotate counterclockwise in x-y:
+ // ra = -atan2(B,A)
+ // x2 = x1 cos ra - y1 sin ra
+ // y2 = x1 sin ra + y1 cos ra
+ // z2 = z1
+ // Faster:
+ // cos ra = A/sqrt(A^2+B^2+C^2)
+ // sin ra = -B/sqrt(A^2+B^2+C^2)
+ // cos (-ra) = A/sqrt(A^2+B^2+C^2)
+ // sin (-ra) = B/sqrt(A^2+B^2+C^2)
+ // (3) Rotate clockwise in x-z:
+ // ha = pi/2 - asin(C/sqrt(A^2+B^2+C^2))
+ // x3 = x2 cos ha - z2 sin ha
+ // y3 = y2
+ // z3 = x2 sin ha + z2 cos ha
+ // At this point, z3 should be zero.
+ // Faster:
+ // sin(ha) = cos(asin(C/sqrt(A^2+B^2+C^2))) = sqrt(1 - C^2/(A^2+B^2+C^2)) = sqrt(A^2+B^2)/sqrt(A^2+B^2+C^2)
+ // cos(ha) = sin(asin(C/sqrt(A^2+B^2+C^2))) = C/sqrt(A^2+B^2+C^2)
+ // (4) Compute interpolations by getting longitudes of original points
+ // la = atan2(y3,x3)
+ // (5) Rotate new points (xN0, yN0, zN0) counter-clockwise in x-z:
+ // ha = -(pi - asin(C/sqrt(A^2+B^2+C^2)))
+ // xN1 = xN0 cos ha - zN0 sin ha
+ // yN1 = yN0
+ // zN1 = xN0 sin ha + zN0 cos ha
+ // (6) Rotate new points clockwise in x-y:
+ // ra = atan2(B,A)
+ // xN2 = xN1 cos ra - yN1 sin ra
+ // yN2 = xN1 sin ra + yN1 cos ra
+ // zN2 = zN1
+ // (7) Translate new points:
+ // xN3 = xN2 - D*A
+ // yN3 = yN2 - D*B
+ // zN3 = zN2 - D*C
+
+ // First, calculate the angles and their sin/cos values
+ double A = x;
+ double B = y;
+ double C = z;
+
+ // Translation amounts
+ final double transX = -D * A;
+ final double transY = -D * B;
+ final double transZ = -D * C;
+
+ double cosRA;
+ double sinRA;
+ double cosHA;
+ double sinHA;
+
+ double magnitude = magnitude();
+ if (magnitude >= MINIMUM_RESOLUTION) {
+ final double denom = 1.0 / magnitude;
+ A *= denom;
+ B *= denom;
+ C *= denom;
+
+ // cos ra = A/sqrt(A^2+B^2+C^2)
+ // sin ra = -B/sqrt(A^2+B^2+C^2)
+ // cos (-ra) = A/sqrt(A^2+B^2+C^2)
+ // sin (-ra) = B/sqrt(A^2+B^2+C^2)
+ final double xyMagnitude = Math.sqrt(A * A + B * B);
+ if (xyMagnitude >= MINIMUM_RESOLUTION) {
+ final double xyDenom = 1.0 / xyMagnitude;
+ cosRA = A * xyDenom;
+ sinRA = -B * xyDenom;
+ } else {
+ cosRA = 1.0;
+ sinRA = 0.0;
+ }
+
+ // sin(ha) = cos(asin(C/sqrt(A^2+B^2+C^2))) = sqrt(1 - C^2/(A^2+B^2+C^2)) = sqrt(A^2+B^2)/sqrt(A^2+B^2+C^2)
+ // cos(ha) = sin(asin(C/sqrt(A^2+B^2+C^2))) = C/sqrt(A^2+B^2+C^2)
+ sinHA = xyMagnitude;
+ cosHA = C;
+ } else {
+ cosRA = 1.0;
+ sinRA = 0.0;
+ cosHA = 1.0;
+ sinHA = 0.0;
+ }
+
+ // Forward-translate the start and end points
+ final Vector modifiedStart = modify(start, transX, transY, transZ, sinRA, cosRA, sinHA, cosHA);
+ final Vector modifiedEnd = modify(end, transX, transY, transZ, sinRA, cosRA, sinHA, cosHA);
+ if (Math.abs(modifiedStart.z) >= MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Start point was not on plane: " + modifiedStart.z);
+ if (Math.abs(modifiedEnd.z) >= MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("End point was not on plane: " + modifiedEnd.z);
+
+ // Compute the angular distance between start and end point
+ final double startAngle = Math.atan2(modifiedStart.y, modifiedStart.x);
+ final double endAngle = Math.atan2(modifiedEnd.y, modifiedEnd.x);
+
+ final double startMagnitude = Math.sqrt(modifiedStart.x * modifiedStart.x + modifiedStart.y * modifiedStart.y);
+ double delta;
+
+ double newEndAngle = endAngle;
+ while (newEndAngle < startAngle) {
+ newEndAngle += Math.PI * 2.0;
+ }
+
+ if (newEndAngle - startAngle <= Math.PI) {
+ delta = newEndAngle - startAngle;
+ } else {
+ double newStartAngle = startAngle;
+ while (newStartAngle < endAngle) {
+ newStartAngle += Math.PI * 2.0;
+ }
+ delta = newStartAngle - endAngle;
+ }
+
+ final GeoPoint[] returnValues = new GeoPoint[proportions.length];
+ for (int i = 0; i < returnValues.length; i++) {
+ final double newAngle = startAngle + proportions[i] * delta;
+ final double sinNewAngle = Math.sin(newAngle);
+ final double cosNewAngle = Math.cos(newAngle);
+ final Vector newVector = new Vector(cosNewAngle * startMagnitude, sinNewAngle * startMagnitude, 0.0);
+ returnValues[i] = reverseModify(newVector, transX, transY, transZ, sinRA, cosRA, sinHA, cosHA);
+ }
+
+ return returnValues;
+ }
+
+ /**
+ * Modify a point to produce a vector in translated/rotated space.
+ * @param start is the start point.
+ * @param transX is the translation x value.
+ * @param transY is the translation y value.
+ * @param transZ is the translation z value.
+ * @param sinRA is the sine of the ascension angle.
+ * @param cosRA is the cosine of the ascension angle.
+ * @param sinHA is the sine of the height angle.
+ * @param cosHA is the cosine of the height angle.
+ * @return the modified point.
+ */
+ protected static Vector modify(final GeoPoint start, final double transX, final double transY, final double transZ,
+ final double sinRA, final double cosRA, final double sinHA, final double cosHA) {
+ return start.translate(transX, transY, transZ).rotateXY(sinRA, cosRA).rotateXZ(sinHA, cosHA);
+ }
+
+ /**
+ * Reverse modify a point to produce a GeoPoint in normal space.
+ * @param point is the translated point.
+ * @param transX is the translation x value.
+ * @param transY is the translation y value.
+ * @param transZ is the translation z value.
+ * @param sinRA is the sine of the ascension angle.
+ * @param cosRA is the cosine of the ascension angle.
+ * @param sinHA is the sine of the height angle.
+ * @param cosHA is the cosine of the height angle.
+ * @return the original point.
+ */
+ protected static GeoPoint reverseModify(final Vector point, final double transX, final double transY, final double transZ,
+ final double sinRA, final double cosRA, final double sinHA, final double cosHA) {
+ final Vector result = point.rotateXZ(-sinHA, cosHA).rotateXY(-sinRA, cosRA).translate(-transX, -transY, -transZ);
+ return new GeoPoint(result.x, result.y, result.z);
+ }
+
+ /**
+ * Public version of findIntersections.
+ * @param planetModel is the planet model.
+ * @param q is the plane to intersect with.
+ * @param bounds are the bounds to consider to determine legal intersection points.
+ * @return the set of legal intersection points.
+ */
+ public GeoPoint[] findIntersections(final PlanetModel planetModel, final Plane q, final Membership... bounds) {
+ if (isNumericallyIdentical(q)) {
+ return null;
+ }
+ return findIntersections(planetModel, q, bounds, NO_BOUNDS);
+ }
+
+ /**
+ * Find the intersection points between two planes, given a set of bounds.
+ *
+ * @param planetModel is the planet model to use in finding points.
+ * @param q is the plane to intersect with.
+ * @param bounds is the set of bounds.
+ * @param moreBounds is another set of bounds.
+ * @return the intersection point(s) on the unit sphere, if there are any.
+ */
+ protected GeoPoint[] findIntersections(final PlanetModel planetModel, final Plane q, final Membership[] bounds, final Membership[] moreBounds) {
+ //System.err.println("Looking for intersection between plane "+this+" and plane "+q+" within bounds");
+ // Unnormalized, unchecked...
+ final Vector lineVector = new Vector(y * q.z - z * q.y, z * q.x - x * q.z, x * q.y - y * q.x);
+ if (Math.abs(lineVector.x) < MINIMUM_RESOLUTION && Math.abs(lineVector.y) < MINIMUM_RESOLUTION && Math.abs(lineVector.z) < MINIMUM_RESOLUTION) {
+ // Degenerate case: parallel planes
+ //System.err.println(" planes are parallel - no intersection");
+ return NO_POINTS;
+ }
+
+ // The line will have the equation: A t + A0 = x, B t + B0 = y, C t + C0 = z.
+ // We have A, B, and C. In order to come up with A0, B0, and C0, we need to find a point that is on both planes.
+ // To do this, we find the largest vector value (either x, y, or z), and look for a point that solves both plane equations
+ // simultaneous. For example, let's say that the vector is (0.5,0.5,1), and the two plane equations are:
+ // 0.7 x + 0.3 y + 0.1 z + 0.0 = 0
+ // and
+ // 0.9 x - 0.1 y + 0.2 z + 4.0 = 0
+ // Then we'd pick z = 0, so the equations to solve for x and y would be:
+ // 0.7 x + 0.3y = 0.0
+ // 0.9 x - 0.1y = -4.0
+ // ... which can readily be solved using standard linear algebra. Generally:
+ // Q0 x + R0 y = S0
+ // Q1 x + R1 y = S1
+ // ... can be solved by Cramer's rule:
+ // x = det(S0 R0 / S1 R1) / det(Q0 R0 / Q1 R1)
+ // y = det(Q0 S0 / Q1 S1) / det(Q0 R0 / Q1 R1)
+ // ... where det( a b / c d ) = ad - bc, so:
+ // x = (S0 * R1 - R0 * S1) / (Q0 * R1 - R0 * Q1)
+ // y = (Q0 * S1 - S0 * Q1) / (Q0 * R1 - R0 * Q1)
+ double x0;
+ double y0;
+ double z0;
+ // We try to maximize the determinant in the denominator
+ final double denomYZ = this.y * q.z - this.z * q.y;
+ final double denomXZ = this.x * q.z - this.z * q.x;
+ final double denomXY = this.x * q.y - this.y * q.x;
+ if (Math.abs(denomYZ) >= Math.abs(denomXZ) && Math.abs(denomYZ) >= Math.abs(denomXY)) {
+ // X is the biggest, so our point will have x0 = 0.0
+ if (Math.abs(denomYZ) < MINIMUM_RESOLUTION_SQUARED) {
+ //System.err.println(" Denominator is zero: no intersection");
+ return NO_POINTS;
+ }
+ final double denom = 1.0 / denomYZ;
+ x0 = 0.0;
+ y0 = (-this.D * q.z - this.z * -q.D) * denom;
+ z0 = (this.y * -q.D + this.D * q.y) * denom;
+ } else if (Math.abs(denomXZ) >= Math.abs(denomXY) && Math.abs(denomXZ) >= Math.abs(denomYZ)) {
+ // Y is the biggest, so y0 = 0.0
+ if (Math.abs(denomXZ) < MINIMUM_RESOLUTION_SQUARED) {
+ //System.err.println(" Denominator is zero: no intersection");
+ return NO_POINTS;
+ }
+ final double denom = 1.0 / denomXZ;
+ x0 = (-this.D * q.z - this.z * -q.D) * denom;
+ y0 = 0.0;
+ z0 = (this.x * -q.D + this.D * q.x) * denom;
+ } else {
+ // Z is the biggest, so Z0 = 0.0
+ if (Math.abs(denomXY) < MINIMUM_RESOLUTION_SQUARED) {
+ //System.err.println(" Denominator is zero: no intersection");
+ return NO_POINTS;
+ }
+ final double denom = 1.0 / denomXY;
+ x0 = (-this.D * q.y - this.y * -q.D) * denom;
+ y0 = (this.x * -q.D + this.D * q.x) * denom;
+ z0 = 0.0;
+ }
+
+ // Once an intersecting line is determined, the next step is to intersect that line with the ellipsoid, which
+ // will yield zero, one, or two points.
+ // The ellipsoid equation: 1,0 = x^2/a^2 + y^2/b^2 + z^2/c^2
+ // 1.0 = (At+A0)^2/a^2 + (Bt+B0)^2/b^2 + (Ct+C0)^2/c^2
+ // A^2 t^2 / a^2 + 2AA0t / a^2 + A0^2 / a^2 + B^2 t^2 / b^2 + 2BB0t / b^2 + B0^2 / b^2 + C^2 t^2 / c^2 + 2CC0t / c^2 + C0^2 / c^2 - 1,0 = 0.0
+ // [A^2 / a^2 + B^2 / b^2 + C^2 / c^2] t^2 + [2AA0 / a^2 + 2BB0 / b^2 + 2CC0 / c^2] t + [A0^2 / a^2 + B0^2 / b^2 + C0^2 / c^2 - 1,0] = 0.0
+ // Use the quadratic formula to determine t values and candidate point(s)
+ final double A = lineVector.x * lineVector.x * planetModel.inverseAbSquared +
+ lineVector.y * lineVector.y * planetModel.inverseAbSquared +
+ lineVector.z * lineVector.z * planetModel.inverseCSquared;
+ final double B = 2.0 * (lineVector.x * x0 * planetModel.inverseAbSquared + lineVector.y * y0 * planetModel.inverseAbSquared + lineVector.z * z0 * planetModel.inverseCSquared);
+ final double C = x0 * x0 * planetModel.inverseAbSquared + y0 * y0 * planetModel.inverseAbSquared + z0 * z0 * planetModel.inverseCSquared - 1.0;
+
+ final double BsquaredMinus = B * B - 4.0 * A * C;
+ if (Math.abs(BsquaredMinus) < MINIMUM_RESOLUTION_SQUARED) {
+ //System.err.println(" One point of intersection");
+ final double inverse2A = 1.0 / (2.0 * A);
+ // One solution only
+ final double t = -B * inverse2A;
+ GeoPoint point = new GeoPoint(lineVector.x * t + x0, lineVector.y * t + y0, lineVector.z * t + z0);
+ //System.err.println(" point: "+point);
+ //verifyPoint(planetModel, point, q);
+ if (point.isWithin(bounds, moreBounds))
+ return new GeoPoint[]{point};
+ return NO_POINTS;
+ } else if (BsquaredMinus > 0.0) {
+ //System.err.println(" Two points of intersection");
+ final double inverse2A = 1.0 / (2.0 * A);
+ // Two solutions
+ final double sqrtTerm = Math.sqrt(BsquaredMinus);
+ final double t1 = (-B + sqrtTerm) * inverse2A;
+ final double t2 = (-B - sqrtTerm) * inverse2A;
+ GeoPoint point1 = new GeoPoint(lineVector.x * t1 + x0, lineVector.y * t1 + y0, lineVector.z * t1 + z0);
+ GeoPoint point2 = new GeoPoint(lineVector.x * t2 + x0, lineVector.y * t2 + y0, lineVector.z * t2 + z0);
+ //verifyPoint(planetModel, point1, q);
+ //verifyPoint(planetModel, point2, q);
+ //System.err.println(" "+point1+" and "+point2);
+ if (point1.isWithin(bounds, moreBounds)) {
+ if (point2.isWithin(bounds, moreBounds))
+ return new GeoPoint[]{point1, point2};
+ return new GeoPoint[]{point1};
+ }
+ if (point2.isWithin(bounds, moreBounds))
+ return new GeoPoint[]{point2};
+ return NO_POINTS;
+ } else {
+ //System.err.println(" no solutions - no intersection");
+ return NO_POINTS;
+ }
+ }
+
+ /*
+ protected void verifyPoint(final PlanetModel planetModel, final GeoPoint point, final Plane q) {
+ if (!evaluateIsZero(point))
+ throw new RuntimeException("Intersection point not on original plane; point="+point+", plane="+this);
+ if (!q.evaluateIsZero(point))
+ throw new RuntimeException("Intersection point not on intersected plane; point="+point+", plane="+q);
+ if (Math.abs(point.x * point.x * planetModel.inverseASquared + point.y * point.y * planetModel.inverseBSquared + point.z * point.z * planetModel.inverseCSquared - 1.0) >= MINIMUM_RESOLUTION)
+ throw new RuntimeException("Intersection point not on ellipsoid; point="+point);
+ }
+ */
+
+ /**
+ * Accumulate (x,y,z) bounds information for this plane, intersected with the unit sphere.
+ * Updates min/max information, using max/min points found
+ * within the specified bounds.
+ *
+ * @param planetModel is the planet model to use in determining bounds.
+ * @param boundsInfo is the xyz info to update with additional bounding information.
+ * @param bounds are the surfaces delineating what's inside the shape.
+ */
+ public void recordBounds(final PlanetModel planetModel, final XYZBounds boundsInfo, final Membership... bounds) {
+ // Basic plan is to do three intersections of the plane and the planet.
+ // For min/max x, we intersect a vertical plane such that y = 0.
+ // For min/max y, we intersect a vertical plane such that x = 0.
+ // For min/max z, we intersect a vertical plane that is chosen to go through the high point of the arc.
+ // For clarity, load local variables with good names
+ final double A = this.x;
+ final double B = this.y;
+ final double C = this.z;
+
+ // Do Z. This can be done simply because it is symmetrical.
+ if (!boundsInfo.isSmallestMinZ(planetModel) || !boundsInfo.isLargestMaxZ(planetModel)) {
+ //System.err.println(" computing Z bound");
+ // Compute Z bounds for this arc
+ // With ellipsoids, we really have only one viable way to do this computation.
+ // Specifically, we compute an appropriate vertical plane, based on the current plane's x-y orientation, and
+ // then intersect it with this one and with the ellipsoid. This gives us zero, one, or two points to use
+ // as bounds.
+ // There is one special case: horizontal circles. These require TWO vertical planes: one for the x, and one for
+ // the y, and we use all four resulting points in the bounds computation.
+ if ((Math.abs(A) >= MINIMUM_RESOLUTION || Math.abs(B) >= MINIMUM_RESOLUTION)) {
+ // NOT a degenerate case
+ //System.err.println(" not degenerate");
+ final Plane normalizedZPlane = constructNormalizedZPlane(A,B);
+ final GeoPoint[] points = findIntersections(planetModel, normalizedZPlane, bounds, NO_BOUNDS);
+ for (final GeoPoint point : points) {
+ assert planetModel.pointOnSurface(point);
+ //System.err.println(" Point = "+point+"; this.evaluate(point)="+this.evaluate(point)+"; normalizedZPlane.evaluate(point)="+normalizedZPlane.evaluate(point));
+ addPoint(boundsInfo, bounds, point);
+ }
+ } else {
+ // Since a==b==0, any plane including the Z axis suffices.
+ //System.err.println(" Perpendicular to z");
+ final GeoPoint[] points = findIntersections(planetModel, normalYPlane, NO_BOUNDS, NO_BOUNDS);
+ boundsInfo.addZValue(points[0]);
+ }
+ }
+
+ // First, compute common subexpressions
+ final double k = 1.0 / ((x*x + y*y)*planetModel.ab*planetModel.ab + z*z*planetModel.c*planetModel.c);
+ final double abSquared = planetModel.ab * planetModel.ab;
+ final double cSquared = planetModel.c * planetModel.c;
+ final double ASquared = A * A;
+ final double BSquared = B * B;
+ final double CSquared = C * C;
+
+ final double r = 2.0*D*k;
+ final double rSquared = r * r;
+
+ if (!boundsInfo.isSmallestMinX(planetModel) || !boundsInfo.isLargestMaxX(planetModel)) {
+ // For min/max x, we need to use lagrange multipliers.
+ //
+ // For this, we need grad(F(x,y,z)) = (dF/dx, dF/dy, dF/dz).
+ //
+ // Minimize and maximize f(x,y,z) = x, with respect to g(x,y,z) = Ax + By + Cz - D and h(x,y,z) = x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1
+ //
+ // grad(f(x,y,z)) = (1,0,0)
+ // grad(g(x,y,z)) = (A,B,C)
+ // grad(h(x,y,z)) = (2x/ab^2,2y/ab^2,2z/c^2)
+ //
+ // Equations we need to simultaneously solve:
+ //
+ // grad(f(x,y,z)) = l * grad(g(x,y,z)) + m * grad(h(x,y,z))
+ // g(x,y,z) = 0
+ // h(x,y,z) = 0
+ //
+ // Equations:
+ // 1 = l*A + m*2x/ab^2
+ // 0 = l*B + m*2y/ab^2
+ // 0 = l*C + m*2z/c^2
+ // Ax + By + Cz + D = 0
+ // x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1 = 0
+ //
+ // Solve for x,y,z in terms of (l, m):
+ //
+ // x = ((1 - l*A) * ab^2 ) / (2 * m)
+ // y = (-l*B * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ //
+ // Two equations, two unknowns:
+ //
+ // A * (((1 - l*A) * ab^2 ) / (2 * m)) + B * ((-l*B * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
+ //
+ // and
+ //
+ // (((1 - l*A) * ab^2 ) / (2 * m))^2/ab^2 + ((-l*B * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
+ //
+ // Simple: solve for l and m, then find x from it.
+ //
+ // (a) Use first equation to find l in terms of m.
+ //
+ // A * (((1 - l*A) * ab^2 ) / (2 * m)) + B * ((-l*B * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
+ // A * ((1 - l*A) * ab^2 ) + B * (-l*B * ab^2) + C * (-l*C * c^2) + D * 2 * m = 0
+ // A * ab^2 - l*A^2* ab^2 - B^2 * l * ab^2 - C^2 * l * c^2 + D * 2 * m = 0
+ // - l *(A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + (A * ab^2 + D * 2 * m) = 0
+ // l = (A * ab^2 + D * 2 * m) / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
+ // l = A * ab^2 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + m * 2 * D / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
+ //
+ // For convenience:
+ //
+ // k = 1.0 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
+ //
+ // Then:
+ //
+ // l = A * ab^2 * k + m * 2 * D * k
+ // l = k * (A*ab^2 + m*2*D)
+ //
+ // For further convenience:
+ //
+ // q = A*ab^2*k
+ // r = 2*D*k
+ //
+ // l = (r*m + q)
+ // l^2 = (r^2 * m^2 + 2*r*m*q + q^2)
+ //
+ // (b) Simplify the second equation before substitution
+ //
+ // (((1 - l*A) * ab^2 ) / (2 * m))^2/ab^2 + ((-l*B * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
+ // ((1 - l*A) * ab^2 )^2/ab^2 + (-l*B * ab^2)^2/ab^2 + (-l*C * c^2)^2/c^2 = 4 * m^2
+ // (1 - l*A)^2 * ab^2 + (-l*B)^2 * ab^2 + (-l*C)^2 * c^2 = 4 * m^2
+ // (1 - 2*l*A + l^2*A^2) * ab^2 + l^2*B^2 * ab^2 + l^2*C^2 * c^2 = 4 * m^2
+ // ab^2 - 2*A*ab^2*l + A^2*ab^2*l^2 + B^2*ab^2*l^2 + C^2*c^2*l^2 - 4*m^2 = 0
+ //
+ // (c) Substitute for l, l^2
+ //
+ // ab^2 - 2*A*ab^2*(r*m + q) + A^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + B^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + C^2*c^2*(r^2 * m^2 + 2*r*m*q + q^2) - 4*m^2 = 0
+ // ab^2 - 2*A*ab^2*r*m - 2*A*ab^2*q + A^2*ab^2*r^2*m^2 + 2*A^2*ab^2*r*q*m +
+ // A^2*ab^2*q^2 + B^2*ab^2*r^2*m^2 + 2*B^2*ab^2*r*q*m + B^2*ab^2*q^2 + C^2*c^2*r^2*m^2 + 2*C^2*c^2*r*q*m + C^2*c^2*q^2 - 4*m^2 = 0
+ //
+ // (d) Group
+ //
+ // m^2 * [A^2*ab^2*r^2 + B^2*ab^2*r^2 + C^2*c^2*r^2 - 4] +
+ // m * [- 2*A*ab^2*r + 2*A^2*ab^2*r*q + 2*B^2*ab^2*r*q + 2*C^2*c^2*r*q] +
+ // [ab^2 - 2*A*ab^2*q + A^2*ab^2*q^2 + B^2*ab^2*q^2 + C^2*c^2*q^2] = 0
+
+ //System.err.println(" computing X bound");
+
+ // Useful subexpressions for this bound
+ final double q = A*abSquared*k;
+ final double qSquared = q * q;
+
+ // Quadratic equation
+ final double a = ASquared*abSquared*rSquared + BSquared*abSquared*rSquared + CSquared*cSquared*rSquared - 4.0;
+ final double b = - 2.0*A*abSquared*r + 2.0*ASquared*abSquared*r*q + 2.0*BSquared*abSquared*r*q + 2.0*CSquared*cSquared*r*q;
+ final double c = abSquared - 2.0*A*abSquared*q + ASquared*abSquared*qSquared + BSquared*abSquared*qSquared + CSquared*cSquared*qSquared;
+
+ if (Math.abs(a) >= MINIMUM_RESOLUTION_SQUARED) {
+ final double sqrtTerm = b*b - 4.0*a*c;
+ if (Math.abs(sqrtTerm) < MINIMUM_RESOLUTION_SQUARED) {
+ // One solution
+ final double m = -b / (2.0 * a);
+ final double l = r * m + q;
+ // x = ((1 - l*A) * ab^2 ) / (2 * m)
+ // y = (-l*B * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ final double denom0 = 0.5 / m;
+ final GeoPoint thePoint = new GeoPoint((1.0-l*A) * abSquared * denom0, -l*B * abSquared * denom0, -l*C * cSquared * denom0);
+ //Math is not quite accurate enough for this
+ //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
+ //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
+ addPoint(boundsInfo, bounds, thePoint);
+ } else if (sqrtTerm > 0.0) {
+ // Two solutions
+ final double sqrtResult = Math.sqrt(sqrtTerm);
+ final double commonDenom = 0.5/a;
+ final double m1 = (-b + sqrtResult) * commonDenom;
+ assert Math.abs(a * m1 * m1 + b * m1 + c) < MINIMUM_RESOLUTION;
+ final double m2 = (-b - sqrtResult) * commonDenom;
+ assert Math.abs(a * m2 * m2 + b * m2 + c) < MINIMUM_RESOLUTION;
+ final double l1 = r * m1 + q;
+ final double l2 = r * m2 + q;
+ // x = ((1 - l*A) * ab^2 ) / (2 * m)
+ // y = (-l*B * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ final double denom1 = 0.5 / m1;
+ final double denom2 = 0.5 / m2;
+ final GeoPoint thePoint1 = new GeoPoint((1.0-l1*A) * abSquared * denom1, -l1*B * abSquared * denom1, -l1*C * cSquared * denom1);
+ final GeoPoint thePoint2 = new GeoPoint((1.0-l2*A) * abSquared * denom2, -l2*B * abSquared * denom2, -l2*C * cSquared * denom2);
+ //Math is not quite accurate enough for this
+ //assert planetModel.pointOnSurface(thePoint1): "Point1: "+thePoint1+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint1.x*thePoint1.x*planetModel.inverseAb*planetModel.inverseAb + thePoint1.y*thePoint1.y*planetModel.inverseAb*planetModel.inverseAb + thePoint1.z*thePoint1.z*planetModel.inverseC*planetModel.inverseC);
+ //assert planetModel.pointOnSurface(thePoint2): "Point1: "+thePoint2+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint2.x*thePoint2.x*planetModel.inverseAb*planetModel.inverseAb + thePoint2.y*thePoint2.y*planetModel.inverseAb*planetModel.inverseAb + thePoint2.z*thePoint2.z*planetModel.inverseC*planetModel.inverseC);
+ //assert evaluateIsZero(thePoint1): "Evaluation of point1: "+evaluate(thePoint1);
+ //assert evaluateIsZero(thePoint2): "Evaluation of point2: "+evaluate(thePoint2);
+ addPoint(boundsInfo, bounds, thePoint1);
+ addPoint(boundsInfo, bounds, thePoint2);
+ } else {
+ // No solutions
+ }
+ } else if (Math.abs(b) > MINIMUM_RESOLUTION_SQUARED) {
+ //System.err.println("Not x quadratic");
+ // a = 0, so m = - c / b
+ final double m = -c / b;
+ final double l = r * m + q;
+ // x = ((1 - l*A) * ab^2 ) / (2 * m)
+ // y = (-l*B * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ final double denom0 = 0.5 / m;
+ final GeoPoint thePoint = new GeoPoint((1.0-l*A) * abSquared * denom0, -l*B * abSquared * denom0, -l*C * cSquared * denom0);
+ //Math is not quite accurate enough for this
+ //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
+ //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
+ addPoint(boundsInfo, bounds, thePoint);
+ } else {
+ // Something went very wrong; a = b = 0
+ }
+ }
+
+ // Do Y
+ if (!boundsInfo.isSmallestMinY(planetModel) || !boundsInfo.isLargestMaxY(planetModel)) {
+ // For min/max x, we need to use lagrange multipliers.
+ //
+ // For this, we need grad(F(x,y,z)) = (dF/dx, dF/dy, dF/dz).
+ //
+ // Minimize and maximize f(x,y,z) = y, with respect to g(x,y,z) = Ax + By + Cz - D and h(x,y,z) = x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1
+ //
+ // grad(f(x,y,z)) = (0,1,0)
+ // grad(g(x,y,z)) = (A,B,C)
+ // grad(h(x,y,z)) = (2x/ab^2,2y/ab^2,2z/c^2)
+ //
+ // Equations we need to simultaneously solve:
+ //
+ // grad(f(x,y,z)) = l * grad(g(x,y,z)) + m * grad(h(x,y,z))
+ // g(x,y,z) = 0
+ // h(x,y,z) = 0
+ //
+ // Equations:
+ // 0 = l*A + m*2x/ab^2
+ // 1 = l*B + m*2y/ab^2
+ // 0 = l*C + m*2z/c^2
+ // Ax + By + Cz + D = 0
+ // x^2/ab^2 + y^2/ab^2 + z^2/c^2 - 1 = 0
+ //
+ // Solve for x,y,z in terms of (l, m):
+ //
+ // x = (-l*A * ab^2 ) / (2 * m)
+ // y = ((1 - l*B) * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ //
+ // Two equations, two unknowns:
+ //
+ // A * ((-l*A * ab^2 ) / (2 * m)) + B * (((1 - l*B) * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
+ //
+ // and
+ //
+ // ((-l*A * ab^2 ) / (2 * m))^2/ab^2 + (((1 - l*B) * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
+ //
+ // Simple: solve for l and m, then find y from it.
+ //
+ // (a) Use first equation to find l in terms of m.
+ //
+ // A * ((-l*A * ab^2 ) / (2 * m)) + B * (((1 - l*B) * ab^2) / ( 2 * m)) + C * ((-l*C * c^2)/ (2 * m)) + D = 0
+ // A * (-l*A * ab^2 ) + B * ((1-l*B) * ab^2) + C * (-l*C * c^2) + D * 2 * m = 0
+ // -A^2*l*ab^2 + B*ab^2 - l*B^2*ab^2 - C^2*l*c^2 + D*2*m = 0
+ // - l *(A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + (B * ab^2 + D * 2 * m) = 0
+ // l = (B * ab^2 + D * 2 * m) / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
+ // l = B * ab^2 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2) + m * 2 * D / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
+ //
+ // For convenience:
+ //
+ // k = 1.0 / (A^2* ab^2 + B^2 * ab^2 + C^2 * c^2)
+ //
+ // Then:
+ //
+ // l = B * ab^2 * k + m * 2 * D * k
+ // l = k * (B*ab^2 + m*2*D)
+ //
+ // For further convenience:
+ //
+ // q = B*ab^2*k
+ // r = 2*D*k
+ //
+ // l = (r*m + q)
+ // l^2 = (r^2 * m^2 + 2*r*m*q + q^2)
+ //
+ // (b) Simplify the second equation before substitution
+ //
+ // ((-l*A * ab^2 ) / (2 * m))^2/ab^2 + (((1 - l*B) * ab^2) / ( 2 * m))^2/ab^2 + ((-l*C * c^2)/ (2 * m))^2/c^2 - 1 = 0
+ // (-l*A * ab^2 )^2/ab^2 + ((1 - l*B) * ab^2)^2/ab^2 + (-l*C * c^2)^2/c^2 = 4 * m^2
+ // (-l*A)^2 * ab^2 + (1 - l*B)^2 * ab^2 + (-l*C)^2 * c^2 = 4 * m^2
+ // l^2*A^2 * ab^2 + (1 - 2*l*B + l^2*B^2) * ab^2 + l^2*C^2 * c^2 = 4 * m^2
+ // A^2*ab^2*l^2 + ab^2 - 2*B*ab^2*l + B^2*ab^2*l^2 + C^2*c^2*l^2 - 4*m^2 = 0
+ //
+ // (c) Substitute for l, l^2
+ //
+ // A^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + ab^2 - 2*B*ab^2*(r*m + q) + B^2*ab^2*(r^2 * m^2 + 2*r*m*q + q^2) + C^2*c^2*(r^2 * m^2 + 2*r*m*q + q^2) - 4*m^2 = 0
+ // A^2*ab^2*r^2*m^2 + 2*A^2*ab^2*r*q*m + A^2*ab^2*q^2 + ab^2 - 2*B*ab^2*r*m - 2*B*ab^2*q + B^2*ab^2*r^2*m^2 +
+ // 2*B^2*ab^2*r*q*m + B^2*ab^2*q^2 + C^2*c^2*r^2*m^2 + 2*C^2*c^2*r*q*m + C^2*c^2*q^2 - 4*m^2 = 0
+ //
+ // (d) Group
+ //
+ // m^2 * [A^2*ab^2*r^2 + B^2*ab^2*r^2 + C^2*c^2*r^2 - 4] +
+ // m * [2*A^2*ab^2*r*q - 2*B*ab^2*r + 2*B^2*ab^2*r*q + 2*C^2*c^2*r*q] +
+ // [A^2*ab^2*q^2 + ab^2 - 2*B*ab^2*q + B^2*ab^2*q^2 + C^2*c^2*q^2] = 0
+
+ //System.err.println(" computing Y bound");
+
+ // Useful subexpressions for this bound
+ final double q = B*abSquared*k;
+ final double qSquared = q * q;
+
+ // Quadratic equation
+ final double a = ASquared*abSquared*rSquared + BSquared*abSquared*rSquared + CSquared*cSquared*rSquared - 4.0;
+ final double b = 2.0*ASquared*abSquared*r*q - 2.0*B*abSquared*r + 2.0*BSquared*abSquared*r*q + 2.0*CSquared*cSquared*r*q;
+ final double c = ASquared*abSquared*qSquared + abSquared - 2.0*B*abSquared*q + BSquared*abSquared*qSquared + CSquared*cSquared*qSquared;
+
+ if (Math.abs(a) >= MINIMUM_RESOLUTION_SQUARED) {
+ final double sqrtTerm = b*b - 4.0*a*c;
+ if (Math.abs(sqrtTerm) < MINIMUM_RESOLUTION_SQUARED) {
+ // One solution
+ final double m = -b / (2.0 * a);
+ final double l = r * m + q;
+ // x = (-l*A * ab^2 ) / (2 * m)
+ // y = ((1.0-l*B) * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ final double denom0 = 0.5 / m;
+ final GeoPoint thePoint = new GeoPoint(-l*A * abSquared * denom0, (1.0-l*B) * abSquared * denom0, -l*C * cSquared * denom0);
+ //Math is not quite accurate enough for this
+ //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint1.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
+ //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
+ addPoint(boundsInfo, bounds, thePoint);
+ } else if (sqrtTerm > 0.0) {
+ // Two solutions
+ final double sqrtResult = Math.sqrt(sqrtTerm);
+ final double commonDenom = 0.5/a;
+ final double m1 = (-b + sqrtResult) * commonDenom;
+ assert Math.abs(a * m1 * m1 + b * m1 + c) < MINIMUM_RESOLUTION;
+ final double m2 = (-b - sqrtResult) * commonDenom;
+ assert Math.abs(a * m2 * m2 + b * m2 + c) < MINIMUM_RESOLUTION;
+ final double l1 = r * m1 + q;
+ final double l2 = r * m2 + q;
+ // x = (-l*A * ab^2 ) / (2 * m)
+ // y = ((1.0-l*B) * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ final double denom1 = 0.5 / m1;
+ final double denom2 = 0.5 / m2;
+ final GeoPoint thePoint1 = new GeoPoint(-l1*A * abSquared * denom1, (1.0-l1*B) * abSquared * denom1, -l1*C * cSquared * denom1);
+ final GeoPoint thePoint2 = new GeoPoint(-l2*A * abSquared * denom2, (1.0-l2*B) * abSquared * denom2, -l2*C * cSquared * denom2);
+ //Math is not quite accurate enough for this
+ //assert planetModel.pointOnSurface(thePoint1): "Point1: "+thePoint1+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint1.x*thePoint1.x*planetModel.inverseAb*planetModel.inverseAb + thePoint1.y*thePoint1.y*planetModel.inverseAb*planetModel.inverseAb + thePoint1.z*thePoint1.z*planetModel.inverseC*planetModel.inverseC);
+ //assert planetModel.pointOnSurface(thePoint2): "Point2: "+thePoint2+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint2.x*thePoint2.x*planetModel.inverseAb*planetModel.inverseAb + thePoint2.y*thePoint2.y*planetModel.inverseAb*planetModel.inverseAb + thePoint2.z*thePoint2.z*planetModel.inverseC*planetModel.inverseC);
+ //assert evaluateIsZero(thePoint1): "Evaluation of point1: "+evaluate(thePoint1);
+ //assert evaluateIsZero(thePoint2): "Evaluation of point2: "+evaluate(thePoint2);
+ addPoint(boundsInfo, bounds, thePoint1);
+ addPoint(boundsInfo, bounds, thePoint2);
+ } else {
+ // No solutions
+ }
+ } else if (Math.abs(b) > MINIMUM_RESOLUTION_SQUARED) {
+ // a = 0, so m = - c / b
+ final double m = -c / b;
+ final double l = r * m + q;
+ // x = ( -l*A * ab^2 ) / (2 * m)
+ // y = ((1-l*B) * ab^2) / ( 2 * m)
+ // z = (-l*C * c^2)/ (2 * m)
+ final double denom0 = 0.5 / m;
+ final GeoPoint thePoint = new GeoPoint(-l*A * abSquared * denom0, (1.0-l*B) * abSquared * denom0, -l*C * cSquared * denom0);
+ //Math is not quite accurate enough for this
+ //assert planetModel.pointOnSurface(thePoint): "Point: "+thePoint+"; Planetmodel="+planetModel+"; A="+A+" B="+B+" C="+C+" D="+D+" planetfcn="+
+ // (thePoint.x*thePoint.x*planetModel.inverseAb*planetModel.inverseAb + thePoint.y*thePoint.y*planetModel.inverseAb*planetModel.inverseAb + thePoint.z*thePoint.z*planetModel.inverseC*planetModel.inverseC);
+ //assert evaluateIsZero(thePoint): "Evaluation of point: "+evaluate(thePoint);
+ addPoint(boundsInfo, bounds, thePoint);
+ } else {
+ // Something went very wrong; a = b = 0
+ }
+ }
+ }
+
+ /**
+ * Accumulate bounds information for this plane, intersected with the unit sphere.
+ * Updates both latitude and longitude information, using max/min points found
+ * within the specified bounds.
+ *
+ * @param planetModel is the planet model to use in determining bounds.
+ * @param boundsInfo is the lat/lon info to update with additional bounding information.
+ * @param bounds are the surfaces delineating what's inside the shape.
+ */
+ public void recordBounds(final PlanetModel planetModel, final LatLonBounds boundsInfo, final Membership... bounds) {
+ // For clarity, load local variables with good names
+ final double A = this.x;
+ final double B = this.y;
+ final double C = this.z;
+
+ // Now compute latitude min/max points
+ if (!boundsInfo.checkNoTopLatitudeBound() || !boundsInfo.checkNoBottomLatitudeBound()) {
+ //System.err.println("Looking at latitude for plane "+this);
+ // With ellipsoids, we really have only one viable way to do this computation.
+ // Specifically, we compute an appropriate vertical plane, based on the current plane's x-y orientation, and
+ // then intersect it with this one and with the ellipsoid. This gives us zero, one, or two points to use
+ // as bounds.
+ // There is one special case: horizontal circles. These require TWO vertical planes: one for the x, and one for
+ // the y, and we use all four resulting points in the bounds computation.
+ if ((Math.abs(A) >= MINIMUM_RESOLUTION || Math.abs(B) >= MINIMUM_RESOLUTION)) {
+ // NOT a horizontal circle!
+ //System.err.println(" Not a horizontal circle");
+ final Plane verticalPlane = constructNormalizedZPlane(A,B);
+ final GeoPoint[] points = findIntersections(planetModel, verticalPlane, bounds, NO_BOUNDS);
+ for (final GeoPoint point : points) {
+ addPoint(boundsInfo, bounds, point);
+ }
+ } else {
+ // Horizontal circle. Since a==b, any vertical plane suffices.
+ final GeoPoint[] points = findIntersections(planetModel, normalXPlane, NO_BOUNDS, NO_BOUNDS);
+ boundsInfo.addZValue(points[0]);
+ }
+ //System.err.println("Done latitude bounds");
+ }
+
+ // First, figure out our longitude bounds, unless we no longer need to consider that
+ if (!boundsInfo.checkNoLongitudeBound()) {
+ //System.err.println("Computing longitude bounds for "+this);
+ //System.out.println("A = "+A+" B = "+B+" C = "+C+" D = "+D);
+ // Compute longitude bounds
+
+ double a;
+ double b;
+ double c;
+
+ if (Math.abs(C) < MINIMUM_RESOLUTION) {
+ // Degenerate; the equation describes a line
+ //System.out.println("It's a zero-width ellipse");
+ // Ax + By + D = 0
+ if (Math.abs(D) >= MINIMUM_RESOLUTION) {
+ if (Math.abs(A) > Math.abs(B)) {
+ // Use equation suitable for A != 0
+ // We need to find the endpoints of the zero-width ellipse.
+ // Geometrically, we have a line segment in x-y space. We need to locate the endpoints
+ // of that line. But luckily, we know some things: specifically, since it is a
+ // degenerate situation in projection, the C value had to have been 0. That
+ // means that our line's endpoints will coincide with the projected ellipse. All we
+ // need to do then is to find the intersection of the projected ellipse and the line
+ // equation:
+ //
+ // A x + B y + D = 0
+ //
+ // Since A != 0:
+ // x = (-By - D)/A
+ //
+ // The projected ellipse:
+ // x^2/a^2 + y^2/b^2 - 1 = 0
+ // Substitute:
+ // [(-By-D)/A]^2/a^2 + y^2/b^2 -1 = 0
+ // Multiply through by A^2:
+ // [-By - D]^2/a^2 + A^2*y^2/b^2 - A^2 = 0
+ // Multiply out:
+ // B^2*y^2/a^2 + 2BDy/a^2 + D^2/a^2 + A^2*y^2/b^2 - A^2 = 0
+ // Group:
+ // y^2 * [B^2/a^2 + A^2/b^2] + y [2BD/a^2] + [D^2/a^2-A^2] = 0
+
+ a = B * B * planetModel.inverseAbSquared + A * A * planetModel.inverseAbSquared;
+ b = 2.0 * B * D * planetModel.inverseAbSquared;
+ c = D * D * planetModel.inverseAbSquared - A * A;
+
+ double sqrtClause = b * b - 4.0 * a * c;
+
+ if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_SQUARED) {
+ double y0 = -b / (2.0 * a);
+ double x0 = (-D - B * y0) / A;
+ double z0 = 0.0;
+ addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
+ } else if (sqrtClause > 0.0) {
+ double sqrtResult = Math.sqrt(sqrtClause);
+ double denom = 1.0 / (2.0 * a);
+ double Hdenom = 1.0 / A;
+
+ double y0a = (-b + sqrtResult) * denom;
+ double y0b = (-b - sqrtResult) * denom;
+
+ double x0a = (-D - B * y0a) * Hdenom;
+ double x0b = (-D - B * y0b) * Hdenom;
+
+ double z0a = 0.0;
+ double z0b = 0.0;
+
+ addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
+ addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
+ }
+
+ } else {
+ // Use equation suitable for B != 0
+ // Since I != 0, we rewrite:
+ // y = (-Ax - D)/B
+ a = B * B * planetModel.inverseAbSquared + A * A * planetModel.inverseAbSquared;
+ b = 2.0 * A * D * planetModel.inverseAbSquared;
+ c = D * D * planetModel.inverseAbSquared - B * B;
+
+ double sqrtClause = b * b - 4.0 * a * c;
+
+ if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_SQUARED) {
+ double x0 = -b / (2.0 * a);
+ double y0 = (-D - A * x0) / B;
+ double z0 = 0.0;
+ addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
+ } else if (sqrtClause > 0.0) {
+ double sqrtResult = Math.sqrt(sqrtClause);
+ double denom = 1.0 / (2.0 * a);
+ double Idenom = 1.0 / B;
+
+ double x0a = (-b + sqrtResult) * denom;
+ double x0b = (-b - sqrtResult) * denom;
+ double y0a = (-D - A * x0a) * Idenom;
+ double y0b = (-D - A * x0b) * Idenom;
+ double z0a = 0.0;
+ double z0b = 0.0;
+
+ addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
+ addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
+ }
+ }
+ }
+
+ } else {
+ //System.err.println("General longitude bounds...");
+
+ // NOTE WELL: The x,y,z values generated here are NOT on the unit sphere.
+ // They are for lat/lon calculation purposes only. x-y is meant to be used for longitude determination,
+ // and z for latitude, and that's all the values are good for.
+
+ // (1) Intersect the plane and the ellipsoid, and project the results into the x-y plane:
+ // From plane:
+ // z = (-Ax - By - D) / C
+ // From ellipsoid:
+ // x^2/a^2 + y^2/b^2 + [(-Ax - By - D) / C]^2/c^2 = 1
+ // Simplify/expand:
+ // C^2*x^2/a^2 + C^2*y^2/b^2 + (-Ax - By - D)^2/c^2 = C^2
+ //
+ // x^2 * C^2/a^2 + y^2 * C^2/b^2 + x^2 * A^2/c^2 + ABxy/c^2 + ADx/c^2 + ABxy/c^2 + y^2 * B^2/c^2 + BDy/c^2 + ADx/c^2 + BDy/c^2 + D^2/c^2 = C^2
+ // Group:
+ // [A^2/c^2 + C^2/a^2] x^2 + [B^2/c^2 + C^2/b^2] y^2 + [2AB/c^2]xy + [2AD/c^2]x + [2BD/c^2]y + [D^2/c^2-C^2] = 0
+ // For convenience, introduce post-projection coefficient variables to make life easier.
+ // E x^2 + F y^2 + G xy + H x + I y + J = 0
+ double E = A * A * planetModel.inverseCSquared + C * C * planetModel.inverseAbSquared;
+ double F = B * B * planetModel.inverseCSquared + C * C * planetModel.inverseAbSquared;
+ double G = 2.0 * A * B * planetModel.inverseCSquared;
+ double H = 2.0 * A * D * planetModel.inverseCSquared;
+ double I = 2.0 * B * D * planetModel.inverseCSquared;
+ double J = D * D * planetModel.inverseCSquared - C * C;
+
+ //System.err.println("E = " + E + " F = " + F + " G = " + G + " H = "+ H + " I = " + I + " J = " + J);
+
+ // Check if the origin is within, by substituting x = 0, y = 0 and seeing if less than zero
+ if (Math.abs(J) >= MINIMUM_RESOLUTION && J > 0.0) {
+ // The derivative of the curve above is:
+ // 2Exdx + 2Fydy + G(xdy+ydx) + Hdx + Idy = 0
+ // (2Ex + Gy + H)dx + (2Fy + Gx + I)dy = 0
+ // dy/dx = - (2Ex + Gy + H) / (2Fy + Gx + I)
+ //
+ // The equation of a line going through the origin with the slope dy/dx is:
+ // y = dy/dx x
+ // y = - (2Ex + Gy + H) / (2Fy + Gx + I) x
+ // Rearrange:
+ // (2Fy + Gx + I) y + (2Ex + Gy + H) x = 0
+ // 2Fy^2 + Gxy + Iy + 2Ex^2 + Gxy + Hx = 0
+ // 2Ex^2 + 2Fy^2 + 2Gxy + Hx + Iy = 0
+ //
+ // Multiply the original equation by 2:
+ // 2E x^2 + 2F y^2 + 2G xy + 2H x + 2I y + 2J = 0
+ // Subtract one from the other, to remove the high-order terms:
+ // Hx + Iy + 2J = 0
+ // Now, we can substitute either x = or y = into the derivative equation, or into the original equation.
+ // But we will need to base this on which coefficient is non-zero
+
+ if (Math.abs(H) > Math.abs(I)) {
+ //System.err.println(" Using the y quadratic");
+ // x = (-2J - Iy)/H
+
+ // Plug into the original equation:
+ // E [(-2J - Iy)/H]^2 + F y^2 + G [(-2J - Iy)/H]y + H [(-2J - Iy)/H] + I y + J = 0
+ // E [(-2J - Iy)/H]^2 + F y^2 + G [(-2J - Iy)/H]y - J = 0
+ // Same equation as derivative equation, except for a factor of 2! So it doesn't matter which we pick.
+
+ // Plug into derivative equation:
+ // 2E[(-2J - Iy)/H]^2 + 2Fy^2 + 2G[(-2J - Iy)/H]y + H[(-2J - Iy)/H] + Iy = 0
+ // 2E[(-2J - Iy)/H]^2 + 2Fy^2 + 2G[(-2J - Iy)/H]y - 2J = 0
+ // E[(-2J - Iy)/H]^2 + Fy^2 + G[(-2J - Iy)/H]y - J = 0
+
+ // Multiply by H^2 to make manipulation easier
+ // E[(-2J - Iy)]^2 + F*H^2*y^2 + GH[(-2J - Iy)]y - J*H^2 = 0
+ // Do the square
+ // E[4J^2 + 4IJy + I^2*y^2] + F*H^2*y^2 + GH(-2Jy - I*y^2) - J*H^2 = 0
+
+ // Multiply it out
+ // 4E*J^2 + 4EIJy + E*I^2*y^2 + H^2*Fy^2 - 2GHJy - GH*I*y^2 - J*H^2 = 0
+ // Group:
+ // y^2 [E*I^2 - GH*I + F*H^2] + y [4EIJ - 2GHJ] + [4E*J^2 - J*H^2] = 0
+
+ a = E * I * I - G * H * I + F * H * H;
+ b = 4.0 * E * I * J - 2.0 * G * H * J;
+ c = 4.0 * E * J * J - J * H * H;
+
+ //System.out.println("a="+a+" b="+b+" c="+c);
+ double sqrtClause = b * b - 4.0 * a * c;
+ //System.out.println("sqrtClause="+sqrtClause);
+
+ if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_CUBED) {
+ //System.err.println(" One solution");
+ double y0 = -b / (2.0 * a);
+ double x0 = (-2.0 * J - I * y0) / H;
+ double z0 = (-A * x0 - B * y0 - D) / C;
+
+ addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
+ } else if (sqrtClause > 0.0) {
+ //System.err.println(" Two solutions");
+ double sqrtResult = Math.sqrt(sqrtClause);
+ double denom = 1.0 / (2.0 * a);
+ double Hdenom = 1.0 / H;
+ double Cdenom = 1.0 / C;
+
+ double y0a = (-b + sqrtResult) * denom;
+ double y0b = (-b - sqrtResult) * denom;
+ double x0a = (-2.0 * J - I * y0a) * Hdenom;
+ double x0b = (-2.0 * J - I * y0b) * Hdenom;
+ double z0a = (-A * x0a - B * y0a - D) * Cdenom;
+ double z0b = (-A * x0b - B * y0b - D) * Cdenom;
+
+ addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
+ addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
+ }
+
+ } else {
+ //System.err.println(" Using the x quadratic");
+ // y = (-2J - Hx)/I
+
+ // Plug into the original equation:
+ // E x^2 + F [(-2J - Hx)/I]^2 + G x[(-2J - Hx)/I] - J = 0
+
+ // Multiply by I^2 to make manipulation easier
+ // E * I^2 * x^2 + F [(-2J - Hx)]^2 + GIx[(-2J - Hx)] - J * I^2 = 0
+ // Do the square
+ // E * I^2 * x^2 + F [ 4J^2 + 4JHx + H^2*x^2] + GI[(-2Jx - H*x^2)] - J * I^2 = 0
+
+ // Multiply it out
+ // E * I^2 * x^2 + 4FJ^2 + 4FJHx + F*H^2*x^2 - 2GIJx - HGI*x^2 - J * I^2 = 0
+ // Group:
+ // x^2 [E*I^2 - GHI + F*H^2] + x [4FJH - 2GIJ] + [4FJ^2 - J*I^2] = 0
+
+ // E x^2 + F y^2 + G xy + H x + I y + J = 0
+
+ a = E * I * I - G * H * I + F * H * H;
+ b = 4.0 * F * H * J - 2.0 * G * I * J;
+ c = 4.0 * F * J * J - J * I * I;
+
+ //System.out.println("a="+a+" b="+b+" c="+c);
+ double sqrtClause = b * b - 4.0 * a * c;
+ //System.out.println("sqrtClause="+sqrtClause);
+ if (Math.abs(sqrtClause) < MINIMUM_RESOLUTION_CUBED) {
+ //System.err.println(" One solution; sqrt clause was "+sqrtClause);
+ double x0 = -b / (2.0 * a);
+ double y0 = (-2.0 * J - H * x0) / I;
+ double z0 = (-A * x0 - B * y0 - D) / C;
+ // Verify that x&y fulfill the equation
+ // 2Ex^2 + 2Fy^2 + 2Gxy + Hx + Iy = 0
+ addPoint(boundsInfo, bounds, new GeoPoint(x0, y0, z0));
+ } else if (sqrtClause > 0.0) {
+ //System.err.println(" Two solutions");
+ double sqrtResult = Math.sqrt(sqrtClause);
+ double denom = 1.0 / (2.0 * a);
+ double Idenom = 1.0 / I;
+ double Cdenom = 1.0 / C;
+
+ double x0a = (-b + sqrtResult) * denom;
+ double x0b = (-b - sqrtResult) * denom;
+ double y0a = (-2.0 * J - H * x0a) * Idenom;
+ double y0b = (-2.0 * J - H * x0b) * Idenom;
+ double z0a = (-A * x0a - B * y0a - D) * Cdenom;
+ double z0b = (-A * x0b - B * y0b - D) * Cdenom;
+
+ addPoint(boundsInfo, bounds, new GeoPoint(x0a, y0a, z0a));
+ addPoint(boundsInfo, bounds, new GeoPoint(x0b, y0b, z0b));
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /** Add a point to boundsInfo if within a specifically bounded area.
+ * @param boundsInfo is the object to be modified.
+ * @param bounds is the area that the point must be within.
+ * @param point is the point.
+ */
+ protected static void addPoint(final Bounds boundsInfo, final Membership[] bounds, final GeoPoint point) {
+ // Make sure the discovered point is within the bounds
+ for (Membership bound : bounds) {
+ if (!bound.isWithin(point))
+ return;
+ }
+ // Add the point
+ boundsInfo.addPoint(point);
+ }
+
+ /** Add a point to boundsInfo if within a specifically bounded area.
+ * @param boundsInfo is the object to be modified.
+ * @param bounds is the area that the point must be within.
+ * @param x is the x value.
+ * @param y is the y value.
+ * @param z is the z value.
+ */
+ /*
+ protected static void addPoint(final Bounds boundsInfo, final Membership[] bounds, final double x, final double y, final double z) {
+ //System.err.println(" Want to add point x="+x+" y="+y+" z="+z);
+ // Make sure the discovered point is within the bounds
+ for (Membership bound : bounds) {
+ if (!bound.isWithin(x, y, z))
+ return;
+ }
+ // Add the point
+ //System.err.println(" point added");
+ //System.out.println("Adding point x="+x+" y="+y+" z="+z);
+ boundsInfo.addPoint(x, y, z);
+ }
+ */
+
+ /**
+ * Determine whether the plane intersects another plane within the
+ * bounds provided.
+ *
+ * @param planetModel is the planet model to use in determining intersection.
+ * @param q is the other plane.
+ * @param notablePoints are points to look at to disambiguate cases when the two planes are identical.
+ * @param moreNotablePoints are additional points to look at to disambiguate cases when the two planes are identical.
+ * @param bounds is one part of the bounds.
+ * @param moreBounds are more bounds.
+ * @return true if there's an intersection.
+ */
+ public boolean intersects(final PlanetModel planetModel, final Plane q, final GeoPoint[] notablePoints, final GeoPoint[] moreNotablePoints, final Membership[] bounds, final Membership... moreBounds) {
+ //System.err.println("Does plane "+this+" intersect with plane "+q);
+ // If the two planes are identical, then the math will find no points of intersection.
+ // So a special case of this is to check for plane equality. But that is not enough, because
+ // what we really need at that point is to determine whether overlap occurs between the two parts of the intersection
+ // of plane and circle. That is, are there *any* points on the plane that are within the bounds described?
+ if (isNumericallyIdentical(q)) {
+ //System.err.println(" Identical plane");
+ // The only way to efficiently figure this out will be to have a list of trial points available to evaluate.
+ // We look for any point that fulfills all the bounds.
+ for (GeoPoint p : notablePoints) {
+ if (meetsAllBounds(p, bounds, moreBounds)) {
+ //System.err.println(" found a notable point in bounds, so intersects");
+ return true;
+ }
+ }
+ for (GeoPoint p : moreNotablePoints) {
+ if (meetsAllBounds(p, bounds, moreBounds)) {
+ //System.err.println(" found a notable point in bounds, so intersects");
+ return true;
+ }
+ }
+ //System.err.println(" no notable points inside found; no intersection");
+ return false;
+ }
+ return findIntersections(planetModel, q, bounds, moreBounds).length > 0;
+ }
+
+ /**
+ * Returns true if this plane and the other plane are identical within the margin of error.
+ * @param p is the plane to compare against.
+ * @return true if the planes are numerically identical.
+ */
+ protected boolean isNumericallyIdentical(final Plane p) {
+ // We can get the correlation by just doing a parallel plane check. If that passes, then compute a point on the plane
+ // (using D) and see if it also on the other plane.
+ if (Math.abs(this.y * p.z - this.z * p.y) >= MINIMUM_RESOLUTION)
+ return false;
+ if (Math.abs(this.z * p.x - this.x * p.z) >= MINIMUM_RESOLUTION)
+ return false;
+ if (Math.abs(this.x * p.y - this.y * p.x) >= MINIMUM_RESOLUTION)
+ return false;
+
+ // Now, see whether the parallel planes are in fact on top of one another.
+ // The math:
+ // We need a single point that fulfills:
+ // Ax + By + Cz + D = 0
+ // Pick:
+ // x0 = -(A * D) / (A^2 + B^2 + C^2)
+ // y0 = -(B * D) / (A^2 + B^2 + C^2)
+ // z0 = -(C * D) / (A^2 + B^2 + C^2)
+ // Check:
+ // A (x0) + B (y0) + C (z0) + D =? 0
+ // A (-(A * D) / (A^2 + B^2 + C^2)) + B (-(B * D) / (A^2 + B^2 + C^2)) + C (-(C * D) / (A^2 + B^2 + C^2)) + D ?= 0
+ // -D [ A^2 / (A^2 + B^2 + C^2) + B^2 / (A^2 + B^2 + C^2) + C^2 / (A^2 + B^2 + C^2)] + D ?= 0
+ // Yes.
+ final double denom = 1.0 / (p.x * p.x + p.y * p.y + p.z * p.z);
+ return evaluateIsZero(-p.x * p.D * denom, -p.y * p.D * denom, -p.z * p.D * denom);
+ }
+
+ /**
+ * Check if a vector meets the provided bounds.
+ * @param p is the vector.
+ * @param bounds are the bounds.
+ * @return true if the vector describes a point within the bounds.
+ */
+ protected static boolean meetsAllBounds(final Vector p, final Membership[] bounds) {
+ return meetsAllBounds(p.x, p.y, p.z, bounds);
+ }
+
+ /**
+ * Check if a vector meets the provided bounds.
+ * @param x is the x value.
+ * @param y is the y value.
+ * @param z is the z value.
+ * @param bounds are the bounds.
+ * @return true if the vector describes a point within the bounds.
+ */
+ protected static boolean meetsAllBounds(final double x, final double y, final double z, final Membership[] bounds) {
+ for (final Membership bound : bounds) {
+ if (!bound.isWithin(x,y,z))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if a vector meets the provided bounds.
+ * @param p is the vector.
+ * @param bounds are the bounds.
+ * @param moreBounds are an additional set of bounds.
+ * @return true if the vector describes a point within the bounds.
+ */
+ protected static boolean meetsAllBounds(final Vector p, final Membership[] bounds, final Membership[] moreBounds) {
+ return meetsAllBounds(p.x, p.y, p.z, bounds, moreBounds);
+ }
+
+ /**
+ * Check if a vector meets the provided bounds.
+ * @param x is the x value.
+ * @param y is the y value.
+ * @param z is the z value.
+ * @param bounds are the bounds.
+ * @param moreBounds are an additional set of bounds.
+ * @return true if the vector describes a point within the bounds.
+ */
+ protected static boolean meetsAllBounds(final double x, final double y, final double z, final Membership[] bounds,
+ final Membership[] moreBounds) {
+ return meetsAllBounds(x,y,z, bounds) && meetsAllBounds(x,y,z, moreBounds);
+ }
+
+ /**
+ * Find a sample point on the intersection between two planes and the world.
+ * @param planetModel is the planet model.
+ * @param q is the second plane to consider.
+ * @return a sample point that is on the intersection between the two planes and the world.
+ */
+ public GeoPoint getSampleIntersectionPoint(final PlanetModel planetModel, final Plane q) {
+ final GeoPoint[] intersections = findIntersections(planetModel, q, NO_BOUNDS, NO_BOUNDS);
+ if (intersections.length == 0)
+ return null;
+ return intersections[0];
+ }
+
+ @Override
+ public String toString() {
+ return "[A=" + x + ", B=" + y + "; C=" + z + "; D=" + D + "]";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!super.equals(o))
+ return false;
+ if (!(o instanceof Plane))
+ return false;
+ Plane other = (Plane) o;
+ return other.D == D;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp;
+ temp = Double.doubleToLongBits(D);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/PlanetModel.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/PlanetModel.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/PlanetModel.java
new file mode 100644
index 0000000..d45d776
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/PlanetModel.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Holds mathematical constants associated with the model of a planet.
+ * @lucene.experimental
+ */
+public class PlanetModel {
+
+ /** Planet model corresponding to sphere. */
+ public static final PlanetModel SPHERE = new PlanetModel(1.0,1.0);
+
+ /** Mean radius */
+ public static final double WGS84_MEAN = 6371009.0;
+ /** Polar radius */
+ public static final double WGS84_POLAR = 6356752.314245;
+ /** Equatorial radius */
+ public static final double WGS84_EQUATORIAL = 6378137.0;
+ /** Planet model corresponding to WGS84 */
+ public static final PlanetModel WGS84 = new PlanetModel(WGS84_EQUATORIAL/WGS84_MEAN,
+ WGS84_POLAR/WGS84_MEAN);
+
+ // Surface of the planet:
+ // x^2/a^2 + y^2/b^2 + z^2/c^2 = 1.0
+ // Scaling factors are a,b,c. geo3d can only support models where a==b, so use ab instead.
+
+ /** The x/y scaling factor */
+ public final double ab;
+ /** The z scaling factor */
+ public final double c;
+ /** The inverse of ab */
+ public final double inverseAb;
+ /** The inverse of c */
+ public final double inverseC;
+ /** The square of the inverse of ab */
+ public final double inverseAbSquared;
+ /** The square of the inverse of c */
+ public final double inverseCSquared;
+ /** The flattening value */
+ public final double flattening;
+ /** The square ratio */
+ public final double squareRatio;
+
+ // We do NOT include radius, because all computations in geo3d are in radians, not meters.
+
+ // Compute north and south pole for planet model, since these are commonly used.
+
+ /** North pole */
+ public final GeoPoint NORTH_POLE;
+ /** South pole */
+ public final GeoPoint SOUTH_POLE;
+ /** Min X pole */
+ public final GeoPoint MIN_X_POLE;
+ /** Max X pole */
+ public final GeoPoint MAX_X_POLE;
+ /** Min Y pole */
+ public final GeoPoint MIN_Y_POLE;
+ /** Max Y pole */
+ public final GeoPoint MAX_Y_POLE;
+
+ /** Constructor.
+ * @param ab is the x/y scaling factor.
+ * @param c is the z scaling factor.
+ */
+ public PlanetModel(final double ab, final double c) {
+ this.ab = ab;
+ this.c = c;
+ this.inverseAb = 1.0 / ab;
+ this.inverseC = 1.0 / c;
+ this.flattening = (ab - c) * inverseAb;
+ this.squareRatio = (ab * ab - c * c) / (c * c);
+ this.inverseAbSquared = inverseAb * inverseAb;
+ this.inverseCSquared = inverseC * inverseC;
+ this.NORTH_POLE = new GeoPoint(c, 0.0, 0.0, 1.0, Math.PI * 0.5, 0.0);
+ this.SOUTH_POLE = new GeoPoint(c, 0.0, 0.0, -1.0, -Math.PI * 0.5, 0.0);
+ this.MIN_X_POLE = new GeoPoint(ab, -1.0, 0.0, 0.0, 0.0, -Math.PI);
+ this.MAX_X_POLE = new GeoPoint(ab, 1.0, 0.0, 0.0, 0.0, 0.0);
+ this.MIN_Y_POLE = new GeoPoint(ab, 0.0, -1.0, 0.0, 0.0, -Math.PI * 0.5);
+ this.MAX_Y_POLE = new GeoPoint(ab, 0.0, 1.0, 0.0, 0.0, Math.PI * 0.5);
+ }
+
+ /** Find the minimum magnitude of all points on the ellipsoid.
+ * @return the minimum magnitude for the planet.
+ */
+ public double getMinimumMagnitude() {
+ return Math.min(this.ab, this.c);
+ }
+
+ /** Find the maximum magnitude of all points on the ellipsoid.
+ * @return the maximum magnitude for the planet.
+ */
+ public double getMaximumMagnitude() {
+ return Math.max(this.ab, this.c);
+ }
+
+ /** Find the minimum x value.
+ *@return the minimum X value.
+ */
+ public double getMinimumXValue() {
+ return -this.ab;
+ }
+
+ /** Find the maximum x value.
+ *@return the maximum X value.
+ */
+ public double getMaximumXValue() {
+ return this.ab;
+ }
+
+ /** Find the minimum y value.
+ *@return the minimum Y value.
+ */
+ public double getMinimumYValue() {
+ return -this.ab;
+ }
+
+ /** Find the maximum y value.
+ *@return the maximum Y value.
+ */
+ public double getMaximumYValue() {
+ return this.ab;
+ }
+
+ /** Find the minimum z value.
+ *@return the minimum Z value.
+ */
+ public double getMinimumZValue() {
+ return -this.c;
+ }
+
+ /** Find the maximum z value.
+ *@return the maximum Z value.
+ */
+ public double getMaximumZValue() {
+ return this.c;
+ }
+
+ /** Check if point is on surface.
+ * @param v is the point to check.
+ * @return true if the point is on the planet surface.
+ */
+ public boolean pointOnSurface(final Vector v) {
+ return pointOnSurface(v.x, v.y, v.z);
+ }
+
+ /** Check if point is on surface.
+ * @param x is the x coord.
+ * @param y is the y coord.
+ * @param z is the z coord.
+ */
+ public boolean pointOnSurface(final double x, final double y, final double z) {
+ // Equation of planet surface is:
+ // x^2 / a^2 + y^2 / b^2 + z^2 / c^2 - 1 = 0
+ return Math.abs(x * x * inverseAb * inverseAb + y * y * inverseAb * inverseAb + z * z * inverseC * inverseC - 1.0) < Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Check if point is outside surface.
+ * @param v is the point to check.
+ * @return true if the point is outside the planet surface.
+ */
+ public boolean pointOutside(final Vector v) {
+ return pointOutside(v.x, v.y, v.z);
+ }
+
+ /** Check if point is outside surface.
+ * @param x is the x coord.
+ * @param y is the y coord.
+ * @param z is the z coord.
+ */
+ public boolean pointOutside(final double x, final double y, final double z) {
+ // Equation of planet surface is:
+ // x^2 / a^2 + y^2 / b^2 + z^2 / c^2 - 1 = 0
+ return (x * x + y * y) * inverseAb * inverseAb + z * z * inverseC * inverseC - 1.0 > Vector.MINIMUM_RESOLUTION;
+ }
+
+ /** Compute surface distance between two points.
+ * @param p1 is the first point.
+ * @param p2 is the second point.
+ * @return the adjusted angle, when multiplied by the mean earth radius, yields a surface distance. This will differ
+ * from GeoPoint.arcDistance() only when the planet model is not a sphere. @see {@link GeoPoint#arcDistance(GeoPoint)}
+ */
+ public double surfaceDistance(final GeoPoint p1, final GeoPoint p2) {
+ final double latA = p1.getLatitude();
+ final double lonA = p1.getLongitude();
+ final double latB = p2.getLatitude();
+ final double lonB = p2.getLongitude();
+
+ final double L = lonB - lonA;
+ final double oF = 1.0 - this.flattening;
+ final double U1 = Math.atan(oF * Math.tan(latA));
+ final double U2 = Math.atan(oF * Math.tan(latB));
+ final double sU1 = Math.sin(U1);
+ final double cU1 = Math.cos(U1);
+ final double sU2 = Math.sin(U2);
+ final double cU2 = Math.cos(U2);
+
+ double sigma, sinSigma, cosSigma;
+ double cos2Alpha, cos2SigmaM;
+
+ double lambda = L;
+ double iters = 100;
+
+ do {
+ final double sinLambda = Math.sin(lambda);
+ final double cosLambda = Math.cos(lambda);
+ sinSigma = Math.sqrt((cU2 * sinLambda) * (cU2 * sinLambda) + (cU1 * sU2 - sU1 * cU2 * cosLambda)
+ * (cU1 * sU2 - sU1 * cU2 * cosLambda));
+ if (Math.abs(sinSigma) < Vector.MINIMUM_RESOLUTION)
+ return 0.0;
+
+ cosSigma = sU1 * sU2 + cU1 * cU2 * cosLambda;
+ sigma = Math.atan2(sinSigma, cosSigma);
+ final double sinAlpha = cU1 * cU2 * sinLambda / sinSigma;
+ cos2Alpha = 1.0 - sinAlpha * sinAlpha;
+ cos2SigmaM = cosSigma - 2.0 * sU1 * sU2 / cos2Alpha;
+
+ final double c = this.flattening * 0.625 * cos2Alpha * (4.0 + this.flattening * (4.0 - 3.0 * cos2Alpha));
+ final double lambdaP = lambda;
+ lambda = L + (1.0 - c) * this.flattening * sinAlpha * (sigma + c * sinSigma * (cos2SigmaM + c * cosSigma *
+ (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM)));
+ if (Math.abs(lambda - lambdaP) < Vector.MINIMUM_RESOLUTION)
+ break;
+ } while (--iters > 0);
+
+ if (iters == 0)
+ return 0.0;
+
+ final double uSq = cos2Alpha * this.squareRatio;
+ final double A = 1.0 + uSq * 0.00006103515625 * (4096.0 + uSq * (-768.0 + uSq * (320.0 - 175.0 * uSq)));
+ final double B = uSq * 0.0009765625 * (256.0 + uSq * (-128.0 + uSq * (74.0 - 47.0 * uSq)));
+ final double deltaSigma = B * sinSigma * (cos2SigmaM + B * 0.25 * (cosSigma * (-1.0 + 2.0 * cos2SigmaM * cos2SigmaM) - B * 0.16666666666666666666667 * cos2SigmaM
+ * (-3.0 + 4.0 * sinSigma * sinSigma) * (-3.0 + 4.0 * cos2SigmaM * cos2SigmaM)));
+
+ return this.c * A * (sigma - deltaSigma);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof PlanetModel))
+ return false;
+ final PlanetModel other = (PlanetModel)o;
+ return ab == other.ab && c == other.c;
+ }
+
+ @Override
+ public int hashCode() {
+ return Double.hashCode(ab) + Double.hashCode(c);
+ }
+
+ @Override
+ public String toString() {
+ if (this.equals(SPHERE)) {
+ return "PlanetModel.SPHERE";
+ } else if (this.equals(WGS84)) {
+ return "PlanetModel.WGS84";
+ } else {
+ return "PlanetModel(ab="+ab+" c="+c+")";
+ }
+ }
+}
+
+
[27/50] [abbrv] lucene-solr git commit: LUCENE-7076: Improve
MIGRATE.txt/Point javadocs
Posted by no...@apache.org.
LUCENE-7076: Improve MIGRATE.txt/Point javadocs
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/5bb072d4
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/5bb072d4
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/5bb072d4
Branch: refs/heads/apiv2
Commit: 5bb072d4b91b1324cae4ec08a6f24b63078c37af
Parents: 406a163
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 8 06:20:25 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 8 06:21:07 2016 -0500
----------------------------------------------------------------------
lucene/MIGRATE.txt | 14 ++---
.../org/apache/lucene/document/BinaryPoint.java | 2 +
.../org/apache/lucene/document/DoublePoint.java | 2 +
.../org/apache/lucene/document/FloatPoint.java | 2 +
.../org/apache/lucene/document/IntPoint.java | 2 +
.../org/apache/lucene/document/LongPoint.java | 2 +
.../org/apache/lucene/index/PointValues.java | 54 ++++++++++++++++++--
.../apache/lucene/search/PointInSetQuery.java | 13 +----
.../apache/lucene/search/PointRangeQuery.java | 11 +---
.../apache/lucene/document/BigIntegerPoint.java | 2 +
.../lucene/document/InetAddressPoint.java | 2 +
.../org/apache/lucene/document/LatLonPoint.java | 2 +
.../org/apache/lucene/spatial3d/Geo3DPoint.java | 3 +-
13 files changed, 79 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/MIGRATE.txt
----------------------------------------------------------------------
diff --git a/lucene/MIGRATE.txt b/lucene/MIGRATE.txt
index b8d12ac..f931aea 100644
--- a/lucene/MIGRATE.txt
+++ b/lucene/MIGRATE.txt
@@ -74,10 +74,12 @@ would be equivalent to the following code with the old setBoost API:
float boost = ...;
q.setBoost(q.getBoost() * boost);
-## DimensionalValues replaces NumericField (LUCENE-6917)
+# PointValues replaces NumericField (LUCENE-6917)
-DimensionalValues provides faster indexing and searching, a smaller
-index size, and less heap used at search time. The numeric fields
-(IntField, FloatField, LongField, DoubleField) and NumericRangeQuery
-have been moved to the backward-codecs module and prefixed with
-Legacy.
+PointValues provides faster indexing and searching, a smaller
+index size, and less heap used at search time. See org.apache.lucene.index.PointValues
+for an introduction.
+
+Legacy numeric encodings from previous versions of Lucene are
+deprecated as LegacyIntField, LegacyFloatField, LegacyLongField, and LegacyDoubleField,
+and can be searched with LegacyNumericRangeQuery.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
index e139a87..4e27d81 100644
--- a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
@@ -19,6 +19,7 @@ package org.apache.lucene.document;
import java.util.Arrays;
import java.util.Comparator;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
@@ -40,6 +41,7 @@ import org.apache.lucene.util.StringHelper;
* <li>{@link #newRangeQuery(String, byte[], byte[])} for matching a 1D range.
* <li>{@link #newRangeQuery(String, byte[][], byte[][])} for matching points/ranges in n-dimensional space.
* </ul>
+ * @see PointValues
*/
public final class BinaryPoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java b/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
index 52b039f..26ac0ce 100644
--- a/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
@@ -18,6 +18,7 @@ package org.apache.lucene.document;
import java.util.Arrays;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
@@ -38,6 +39,7 @@ import org.apache.lucene.util.NumericUtils;
* <li>{@link #newRangeQuery(String, double, double)} for matching a 1D range.
* <li>{@link #newRangeQuery(String, double[], double[])} for matching points/ranges in n-dimensional space.
* </ul>
+ * @see PointValues
*/
public final class DoublePoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java b/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
index cad666c..c58881e 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
@@ -18,6 +18,7 @@ package org.apache.lucene.document;
import java.util.Arrays;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
@@ -38,6 +39,7 @@ import org.apache.lucene.util.NumericUtils;
* <li>{@link #newRangeQuery(String, float, float)} for matching a 1D range.
* <li>{@link #newRangeQuery(String, float[], float[])} for matching points/ranges in n-dimensional space.
* </ul>
+ * @see PointValues
*/
public final class FloatPoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/document/IntPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/IntPoint.java b/lucene/core/src/java/org/apache/lucene/document/IntPoint.java
index b6f5ae7..cb8315f 100644
--- a/lucene/core/src/java/org/apache/lucene/document/IntPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/IntPoint.java
@@ -18,6 +18,7 @@ package org.apache.lucene.document;
import java.util.Arrays;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
@@ -38,6 +39,7 @@ import org.apache.lucene.util.NumericUtils;
* <li>{@link #newRangeQuery(String, int, int)} for matching a 1D range.
* <li>{@link #newRangeQuery(String, int[], int[])} for matching points/ranges in n-dimensional space.
* </ul>
+ * @see PointValues
*/
public final class IntPoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongPoint.java b/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
index c0672ae..ff78132 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
@@ -18,6 +18,7 @@ package org.apache.lucene.document;
import java.util.Arrays;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
@@ -38,6 +39,7 @@ import org.apache.lucene.util.NumericUtils;
* <li>{@link #newRangeQuery(String, long, long)} for matching a 1D range.
* <li>{@link #newRangeQuery(String, long[], long[])} for matching points/ranges in n-dimensional space.
* </ul>
+ * @see PointValues
*/
public final class LongPoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/index/PointValues.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/index/PointValues.java b/lucene/core/src/java/org/apache/lucene/index/PointValues.java
index 230a14f..1fb2654 100644
--- a/lucene/core/src/java/org/apache/lucene/index/PointValues.java
+++ b/lucene/core/src/java/org/apache/lucene/index/PointValues.java
@@ -17,17 +17,65 @@
package org.apache.lucene.index;
import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
import org.apache.lucene.document.BinaryPoint;
import org.apache.lucene.document.DoublePoint;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.util.bkd.BKDWriter;
-/** Allows recursively visiting point values indexed with {@link IntPoint},
- * {@link FloatPoint}, {@link LongPoint}, {@link DoublePoint}
- * or {@link BinaryPoint}.
+/**
+ * Access to indexed numeric values.
+ * <p>
+ * Points represent numeric values and are indexed differently than ordinary text. Instead of an inverted index,
+ * points are indexed with datastructures such as <a href="https://en.wikipedia.org/wiki/K-d_tree">KD-trees</a>.
+ * These structures are optimized for operations such as <i>range</i>, <i>distance</i>, <i>nearest-neighbor</i>,
+ * and <i>point-in-polygon</i> queries.
+ * <h1>Basic Point Types</h1>
+ * <table summary="Basic point types in Java and Lucene">
+ * <tr><th>Java type</th><th>Lucene class</th></tr>
+ * <tr><td>{@code int}</td><td>{@link IntPoint}</td></tr>
+ * <tr><td>{@code long}</td><td>{@link LongPoint}</td></tr>
+ * <tr><td>{@code float}</td><td>{@link FloatPoint}</td></tr>
+ * <tr><td>{@code double}</td><td>{@link DoublePoint}</td></tr>
+ * <tr><td>{@code byte[]}</td><td>{@link BinaryPoint}</td></tr>
+ * <tr><td>{@link BigInteger}</td><td><a href="{@docRoot}/../sandbox/org/apache/lucene/document/BigIntegerPoint.html">BigIntegerPoint</a>*</td></tr>
+ * <tr><td>{@link InetAddress}</td><td><a href="{@docRoot}/../sandbox/org/apache/lucene/document/InetAddressPoint.html">InetAddressPoint</a>*</td></tr>
+ * </table>
+ * * in the <i>lucene-sandbox</i> jar<br>
+ * <p>
+ * Basic Lucene point types behave like their java peers: for example {@link IntPoint} represents a signed 32-bit
+ * {@link Integer}, supporting values ranging from {@link Integer#MIN_VALUE} to {@link Integer#MAX_VALUE}, ordered
+ * consistent with {@link Integer#compareTo(Integer)}. In addition to indexing support, point classes also contain
+ * static methods (such as {@link IntPoint#newRangeQuery(String, int, int)}) for creating common queries. For example:
+ * <pre class="prettyprint">
+ * // add year 1970 to document
+ * document.add(new IntPoint("year", 1970));
+ * // index document
+ * writer.addDocument(document);
+ * ...
+ * // issue range query of 1960-1980
+ * Query query = IntPoint.newRangeQuery("year", 1960, 1980);
+ * TopDocs docs = searcher.search(query, ...);
+ * </pre>
+ * <h1>Geospatial Point Types</h1>
+ * Although basic point types such as {@link DoublePoint} support points in multi-dimensional space too, Lucene has
+ * specialized classes for location data. These classes are optimized for location data: they are more space-efficient and
+ * support special operations such as <i>distance</i> and <i>polygon</i> queries. There are currently two implementations:
+ * <br>
+ * <ol>
+ * <li><a href="{@docRoot}/../sandbox/org/apache/lucene/document/LatLonPoint.html">LatLonPoint</a> in <i>lucene-sandbox</i>: indexes {@code (latitude,longitude)} as {@code (x,y)} in two-dimensional space.
+ * <li><a href="{@docRoot}/../spatial3d/org/apache/lucene/spatial3d/Geo3DPoint.html">Geo3DPoint</a>* in <i>lucene-spatial3d</i>: indexes {@code (latitude,longitude)} as {@code (x,y,z)} in three-dimensional space.
+ * </ol>
+ * * does <b>not</b> support altitude, 3D here means "uses three dimensions under-the-hood"<br>
+ * <h1>Advanced usage</h1>
+ * Custom structures can be created on top of single- or multi- dimensional basic types, on top of
+ * {@link BinaryPoint} for more flexibility, or via custom {@link Field} subclasses.
*
* @lucene.experimental */
public abstract class PointValues {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
index f5ba12d..944fadf 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
@@ -16,15 +16,10 @@
*/
package org.apache.lucene.search;
-
import java.io.IOException;
import java.util.Arrays;
-import org.apache.lucene.document.BinaryPoint;
-import org.apache.lucene.document.DoublePoint;
-import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.IntPoint;
-import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
@@ -48,13 +43,7 @@ import org.apache.lucene.util.StringHelper;
* create range queries for lucene's standard {@code Point} types, refer to factory
* methods on those classes, e.g. {@link IntPoint#newSetQuery IntPoint.newSetQuery()} for
* fields indexed with {@link IntPoint}.
-
- * @see IntPoint
- * @see LongPoint
- * @see FloatPoint
- * @see DoublePoint
- * @see BinaryPoint
- *
+ * @see PointValues
* @lucene.experimental */
public abstract class PointInSetQuery extends Query {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
index 777c133..ebbe7e2 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
@@ -23,11 +23,7 @@ import java.util.Objects;
import org.apache.lucene.index.PointValues;
import org.apache.lucene.index.PointValues.IntersectVisitor;
import org.apache.lucene.index.PointValues.Relation;
-import org.apache.lucene.document.BinaryPoint; // javadocs
-import org.apache.lucene.document.DoublePoint; // javadocs
-import org.apache.lucene.document.FloatPoint; // javadocs
import org.apache.lucene.document.IntPoint; // javadocs
-import org.apache.lucene.document.LongPoint; // javadocs
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
@@ -44,12 +40,7 @@ import org.apache.lucene.util.StringHelper;
* fields indexed with {@link IntPoint}.
* <p>
* For a single-dimensional field this query is a simple range query; in a multi-dimensional field it's a box shape.
- * @see IntPoint
- * @see LongPoint
- * @see FloatPoint
- * @see DoublePoint
- * @see BinaryPoint
- *
+ * @see PointValues
* @lucene.experimental
*/
public abstract class PointRangeQuery extends Query {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/sandbox/src/java/org/apache/lucene/document/BigIntegerPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/BigIntegerPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/BigIntegerPoint.java
index f175858..70445d6 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/BigIntegerPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/BigIntegerPoint.java
@@ -19,6 +19,7 @@ package org.apache.lucene.document;
import java.math.BigInteger;
import java.util.Arrays;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
@@ -39,6 +40,7 @@ import org.apache.lucene.util.NumericUtils;
* <li>{@link #newRangeQuery(String, BigInteger, BigInteger)} for matching a 1D range.
* <li>{@link #newRangeQuery(String, BigInteger[], BigInteger[])} for matching points/ranges in n-dimensional space.
* </ul>
+ * @see PointValues
*/
public class BigIntegerPoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/sandbox/src/java/org/apache/lucene/document/InetAddressPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/InetAddressPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/InetAddressPoint.java
index a0623b3..f0df6ff 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/InetAddressPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/InetAddressPoint.java
@@ -20,6 +20,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
@@ -43,6 +44,7 @@ import org.apache.lucene.util.BytesRef;
* This field supports both IPv4 and IPv6 addresses: IPv4 addresses are converted
* to <a href="https://tools.ietf.org/html/rfc4291#section-2.5.5">IPv4-Mapped IPv6 Addresses</a>:
* indexing {@code 1.2.3.4} is the same as indexing {@code ::FFFF:1.2.3.4}.
+ * @see PointValues
*/
public class InetAddressPoint extends Field {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
index 5f45cb5..fd3284b 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java
@@ -20,6 +20,7 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;
import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreQuery;
@@ -43,6 +44,7 @@ import org.apache.lucene.spatial.util.GeoUtils;
* <p>
* <b>WARNING</b>: Values are indexed with some loss of precision, incurring up to 1E-7 error from the
* original {@code double} values.
+ * @see PointValues
*/
// TODO ^^^ that is very sandy and hurts the API, usage, and tests tremendously, because what the user passes
// to the field is not actually what gets indexed. Float would be 1E-5 error vs 1E-7, but it might be
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5bb072d4/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
index cd2c79a..955a2bc 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
@@ -18,6 +18,7 @@ package org.apache.lucene.spatial3d;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.spatial3d.geom.GeoPoint;
import org.apache.lucene.spatial3d.geom.GeoShape;
import org.apache.lucene.spatial3d.geom.PlanetModel;
@@ -34,7 +35,7 @@ import org.apache.lucene.util.NumericUtils;
* <ul>
* <li>{@link #newShapeQuery newShapeQuery()} for matching all points inside a specified shape
* </ul>
- *
+ * @see PointValues
* @lucene.experimental */
public final class Geo3DPoint extends Field {
[49/50] [abbrv] lucene-solr git commit: Merge remote-tracking branch
'remotes/origin/master' into apiv2
Posted by no...@apache.org.
Merge remote-tracking branch 'remotes/origin/master' into apiv2
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/78154085
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/78154085
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/78154085
Branch: refs/heads/apiv2
Commit: 781540855e41db12704cd54fa627486cf4be185a
Parents: 943f270 588aeea
Author: Noble Paul <no...@apache.org>
Authored: Wed Mar 9 21:26:15 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Wed Mar 9 21:26:15 2016 +0530
----------------------------------------------------------------------
dev-tools/idea/.idea/ant.xml | 1 +
dev-tools/idea/.idea/modules.xml | 1 +
dev-tools/idea/.idea/workspace.xml | 41 +-
.../idea/lucene/benchmark/src/benchmark.iml | 2 +-
.../lucene/spatial-extras/spatial-extras.iml | 32 +
dev-tools/idea/lucene/spatial/spatial.iml | 15 -
dev-tools/idea/solr/core/src/java/solr-core.iml | 2 +-
.../idea/solr/core/src/solr-core-tests.iml | 2 +-
dev-tools/maven/lucene/pom.xml.template | 1 +
.../lucene/spatial-extras/pom.xml.template | 62 +
dev-tools/maven/lucene/spatial/pom.xml.template | 2 +-
dev-tools/scripts/buildAndPushRelease.py | 2 +-
dev-tools/scripts/smokeTestRelease.py | 7 +-
lucene/CHANGES.txt | 60 +-
lucene/MIGRATE.txt | 14 +-
.../lucene/analysis/ar/ArabicAnalyzer.java | 4 +-
.../lucene/analysis/ckb/SoraniAnalyzer.java | 4 +-
.../lucene/analysis/fa/PersianAnalyzer.java | 4 +-
.../lucene/analysis/hi/HindiAnalyzer.java | 4 +-
.../miscellaneous/StemmerOverrideFilter.java | 2 +-
.../apache/lucene/analysis/th/ThaiAnalyzer.java | 5 +-
.../lucene/analysis/ar/TestArabicAnalyzer.java | 12 -
.../lucene/analysis/ckb/TestSoraniAnalyzer.java | 12 -
.../analysis/custom/TestCustomAnalyzer.java | 8 +-
.../lucene/analysis/fa/TestPersianAnalyzer.java | 12 -
.../lucene/analysis/hi/TestHindiAnalyzer.java | 12 -
.../lucene/analysis/th/TestThaiAnalyzer.java | 12 -
.../lucene/codecs/lucene50/Lucene50Codec.java | 6 +-
.../lucene/codecs/lucene53/Lucene53Codec.java | 8 +-
.../lucene/codecs/lucene54/Lucene54Codec.java | 8 +-
.../index/TestBackwardsCompatibility.java | 79 +-
.../lucene/index/TestMaxPositionInOldIndex.java | 107 -
.../org/apache/lucene/index/dvupdates.5.0.0.zip | Bin 13376 -> 0 bytes
.../org/apache/lucene/index/dvupdates.6.0.0.zip | Bin 0 -> 3420 bytes
.../org/apache/lucene/index/empty.5.0.0.zip | Bin 225 -> 0 bytes
.../org/apache/lucene/index/empty.6.0.0.zip | Bin 0 -> 225 bytes
.../org/apache/lucene/index/index.5.0.0-cfs.zip | Bin 13503 -> 0 bytes
.../apache/lucene/index/index.5.0.0-nocfs.zip | Bin 13485 -> 0 bytes
.../index/index.5.0.0.singlesegment-cfs.zip | Bin 4028 -> 0 bytes
.../index/index.5.0.0.singlesegment-nocfs.zip | Bin 6418 -> 0 bytes
.../org/apache/lucene/index/index.5.1.0-cfs.zip | Bin 13523 -> 0 bytes
.../apache/lucene/index/index.5.1.0-nocfs.zip | Bin 13530 -> 0 bytes
.../org/apache/lucene/index/index.5.2.0-cfs.zip | Bin 13528 -> 0 bytes
.../apache/lucene/index/index.5.2.0-nocfs.zip | Bin 13539 -> 0 bytes
.../org/apache/lucene/index/index.5.2.1-cfs.zip | Bin 13568 -> 0 bytes
.../apache/lucene/index/index.5.2.1-nocfs.zip | Bin 13566 -> 0 bytes
.../org/apache/lucene/index/index.5.3.0-cfs.zip | Bin 13747 -> 0 bytes
.../apache/lucene/index/index.5.3.0-nocfs.zip | Bin 13731 -> 0 bytes
.../org/apache/lucene/index/index.5.3.1-cfs.zip | Bin 13701 -> 0 bytes
.../apache/lucene/index/index.5.3.1-nocfs.zip | Bin 13703 -> 0 bytes
.../org/apache/lucene/index/index.5.3.2-cfs.zip | Bin 13724 -> 0 bytes
.../apache/lucene/index/index.5.3.2-nocfs.zip | Bin 13708 -> 0 bytes
.../org/apache/lucene/index/index.5.4.0-cfs.zip | Bin 13738 -> 0 bytes
.../apache/lucene/index/index.5.4.0-nocfs.zip | Bin 13730 -> 0 bytes
.../org/apache/lucene/index/index.5.4.1-cfs.zip | Bin 13761 -> 0 bytes
.../apache/lucene/index/index.5.4.1-nocfs.zip | Bin 13766 -> 0 bytes
.../org/apache/lucene/index/index.5.5.0-cfs.zip | Bin 24776 -> 0 bytes
.../apache/lucene/index/index.5.5.0-nocfs.zip | Bin 13756 -> 0 bytes
.../org/apache/lucene/index/moreterms.4.0.0.zip | Bin 78661 -> 0 bytes
.../org/apache/lucene/index/moreterms.5.0.0.zip | Bin 78653 -> 0 bytes
.../org/apache/lucene/index/moreterms.6.0.0.zip | Bin 0 -> 157215 bytes
.../lucene/index/unsupported.5.0.0-cfs.zip | Bin 0 -> 13503 bytes
.../lucene/index/unsupported.5.0.0-nocfs.zip | Bin 0 -> 13485 bytes
.../unsupported.5.0.0.singlesegment-cfs.zip | Bin 0 -> 4028 bytes
.../unsupported.5.0.0.singlesegment-nocfs.zip | Bin 0 -> 6418 bytes
.../lucene/index/unsupported.5.1.0-cfs.zip | Bin 0 -> 13523 bytes
.../lucene/index/unsupported.5.1.0-nocfs.zip | Bin 0 -> 13530 bytes
.../lucene/index/unsupported.5.2.0-cfs.zip | Bin 0 -> 13528 bytes
.../lucene/index/unsupported.5.2.0-nocfs.zip | Bin 0 -> 13539 bytes
.../lucene/index/unsupported.5.2.1-cfs.zip | Bin 0 -> 13568 bytes
.../lucene/index/unsupported.5.2.1-nocfs.zip | Bin 0 -> 13566 bytes
.../lucene/index/unsupported.5.3.0-cfs.zip | Bin 0 -> 13747 bytes
.../lucene/index/unsupported.5.3.0-nocfs.zip | Bin 0 -> 13731 bytes
.../lucene/index/unsupported.5.3.1-cfs.zip | Bin 0 -> 13701 bytes
.../lucene/index/unsupported.5.3.1-nocfs.zip | Bin 0 -> 13703 bytes
.../lucene/index/unsupported.5.3.2-cfs.zip | Bin 0 -> 13724 bytes
.../lucene/index/unsupported.5.3.2-nocfs.zip | Bin 0 -> 13708 bytes
.../lucene/index/unsupported.5.4.0-cfs.zip | Bin 0 -> 13738 bytes
.../lucene/index/unsupported.5.4.0-nocfs.zip | Bin 0 -> 13730 bytes
.../lucene/index/unsupported.5.4.1-cfs.zip | Bin 0 -> 13761 bytes
.../lucene/index/unsupported.5.4.1-nocfs.zip | Bin 0 -> 13766 bytes
.../lucene/index/unsupported.5.5.0-cfs.zip | Bin 0 -> 24776 bytes
.../lucene/index/unsupported.5.5.0-nocfs.zip | Bin 0 -> 13756 bytes
lucene/benchmark/build.xml | 8 +-
lucene/benchmark/conf/spatial.alg | 2 +-
lucene/benchmark/ivy.xml | 2 +-
.../lucene/benchmark/byTask/feeds/DocMaker.java | 44 +-
.../benchmark/byTask/feeds/SpatialDocMaker.java | 8 +-
.../byTask/feeds/SpatialFileQueryMaker.java | 4 +-
.../benchmark/byTask/tasks/ReadTokensTask.java | 13 +-
lucene/build.xml | 5 +-
.../codecs/blockterms/BlockTermsReader.java | 4 +-
.../lucene/codecs/memory/FSTTermsWriter.java | 2 +-
.../codecs/simpletext/SimpleTextBKDReader.java | 10 +-
.../codecs/simpletext/SimpleTextCodec.java | 8 +-
.../simpletext/SimpleTextPointFormat.java | 53 -
.../simpletext/SimpleTextPointReader.java | 270 -
.../simpletext/SimpleTextPointWriter.java | 230 -
.../simpletext/SimpleTextPointsFormat.java | 53 +
.../simpletext/SimpleTextPointsReader.java | 302 +
.../simpletext/SimpleTextPointsWriter.java | 244 +
.../simpletext/TestSimpleTextPointFormat.java | 33 -
.../simpletext/TestSimpleTextPointsFormat.java | 33 +
.../analysis/LegacyNumericTokenStream.java | 5 +-
.../java/org/apache/lucene/codecs/Codec.java | 2 +-
.../org/apache/lucene/codecs/FilterCodec.java | 4 +-
.../org/apache/lucene/codecs/PointFormat.java | 101 -
.../org/apache/lucene/codecs/PointReader.java | 51 -
.../org/apache/lucene/codecs/PointWriter.java | 134 -
.../org/apache/lucene/codecs/PointsFormat.java | 111 +
.../org/apache/lucene/codecs/PointsReader.java | 51 +
.../org/apache/lucene/codecs/PointsWriter.java | 157 +
.../lucene/codecs/lucene60/Lucene60Codec.java | 6 +-
.../codecs/lucene60/Lucene60PointFormat.java | 106 -
.../codecs/lucene60/Lucene60PointReader.java | 219 -
.../codecs/lucene60/Lucene60PointWriter.java | 218 -
.../codecs/lucene60/Lucene60PointsFormat.java | 106 +
.../codecs/lucene60/Lucene60PointsReader.java | 241 +
.../codecs/lucene60/Lucene60PointsWriter.java | 225 +
.../lucene/codecs/lucene60/package-info.java | 11 +-
.../org/apache/lucene/document/BinaryPoint.java | 151 +-
.../org/apache/lucene/document/Document.java | 6 +-
.../document/DocumentStoredFieldVisitor.java | 7 +-
.../org/apache/lucene/document/DoublePoint.java | 168 +-
.../java/org/apache/lucene/document/Field.java | 19 +-
.../org/apache/lucene/document/FieldType.java | 36 +-
.../org/apache/lucene/document/FloatPoint.java | 168 +-
.../org/apache/lucene/document/IntPoint.java | 166 +-
.../org/apache/lucene/document/LongPoint.java | 170 +-
.../document/SortedNumericDocValuesField.java | 4 +-
.../org/apache/lucene/document/StoredField.java | 4 +-
.../org/apache/lucene/index/CheckIndex.java | 137 +-
.../org/apache/lucene/index/CodecReader.java | 19 +-
.../lucene/index/DefaultIndexingChain.java | 22 +-
.../java/org/apache/lucene/index/FieldInfo.java | 2 +-
.../apache/lucene/index/FilterCodecReader.java | 8 +-
.../apache/lucene/index/FilterLeafReader.java | 10 +-
.../index/IndexFormatTooOldException.java | 4 +-
.../org/apache/lucene/index/IndexUpgrader.java | 2 +-
.../org/apache/lucene/index/IndexWriter.java | 1 +
.../org/apache/lucene/index/LeafReader.java | 2 +-
.../org/apache/lucene/index/MergeState.java | 12 +-
.../apache/lucene/index/MultiPointValues.java | 172 -
.../apache/lucene/index/ParallelLeafReader.java | 26 +
.../org/apache/lucene/index/PointValues.java | 68 +-
.../apache/lucene/index/PointValuesWriter.java | 19 +-
.../apache/lucene/index/PrefixCodedTerms.java | 2 +-
.../apache/lucene/index/SegmentCoreReaders.java | 10 +-
.../org/apache/lucene/index/SegmentInfos.java | 28 +-
.../org/apache/lucene/index/SegmentMerger.java | 4 +-
.../org/apache/lucene/index/SegmentReader.java | 8 +-
.../lucene/index/SlowCodecReaderWrapper.java | 18 +-
.../index/SlowCompositeReaderWrapper.java | 2 +-
.../lucene/index/SortedDocValuesWriter.java | 2 +-
.../lucene/index/SortedSetDocValuesWriter.java | 2 +-
.../apache/lucene/index/TermsHashPerField.java | 2 +-
.../apache/lucene/search/FieldValueQuery.java | 4 +
.../apache/lucene/search/FilterCollector.java | 2 +-
.../lucene/search/FilterLeafCollector.java | 2 +-
.../apache/lucene/search/FuzzyTermsEnum.java | 5 +-
.../lucene/search/LegacyNumericRangeQuery.java | 29 +-
.../apache/lucene/search/MultiPhraseQuery.java | 273 +-
.../MultiTermQueryConstantScoreWrapper.java | 3 +
.../apache/lucene/search/NGramPhraseQuery.java | 5 +
.../apache/lucene/search/PointInSetQuery.java | 363 +
.../apache/lucene/search/PointRangeQuery.java | 696 +-
.../org/apache/lucene/search/RegexpQuery.java | 7 +-
.../apache/lucene/search/ScoringRewrite.java | 2 +-
.../org/apache/lucene/search/SortField.java | 2 +-
.../lucene/search/SortedNumericSelector.java | 6 +-
.../org/apache/lucene/search/SynonymQuery.java | 5 +
.../search/UsageTrackingQueryCachingPolicy.java | 16 +-
.../lucene/search/spans/SpanContainQuery.java | 8 +
.../apache/lucene/store/FilterDirectory.java | 2 +-
.../org/apache/lucene/store/MMapDirectory.java | 10 +-
.../java/org/apache/lucene/util/ArrayUtil.java | 20 +-
.../org/apache/lucene/util/ByteBlockPool.java | 22 +
.../java/org/apache/lucene/util/BytesRef.java | 122 +-
.../org/apache/lucene/util/BytesRefArray.java | 41 +-
.../org/apache/lucene/util/BytesRefHash.java | 10 +-
.../org/apache/lucene/util/CollectionUtil.java | 4 +-
.../org/apache/lucene/util/DocIdSetBuilder.java | 14 +-
.../apache/lucene/util/LegacyNumericUtils.java | 63 -
.../org/apache/lucene/util/NumericUtils.java | 200 +-
.../org/apache/lucene/util/OfflineSorter.java | 7 +-
.../org/apache/lucene/util/QueryBuilder.java | 18 +-
.../apache/lucene/util/RamUsageEstimator.java | 49 +
.../org/apache/lucene/util/StringHelper.java | 1 +
.../java/org/apache/lucene/util/Version.java | 78 +-
.../org/apache/lucene/util/bkd/BKDReader.java | 26 +-
.../org/apache/lucene/util/bkd/BKDWriter.java | 94 +-
.../lucene60/TestLucene60PointFormat.java | 83 -
.../lucene60/TestLucene60PointsFormat.java | 83 +
.../apache/lucene/document/TestDocument.java | 4 +-
.../org/apache/lucene/document/TestField.java | 184 +-
.../apache/lucene/document/TestFieldType.java | 21 +-
.../index/TestDemoParallelLeafReader.java | 3 +-
.../apache/lucene/index/TestDuelingCodecs.java | 4 +-
.../lucene/index/TestFilterLeafReader.java | 2 +-
.../index/TestFlushByRamOrCountsPolicy.java | 2 +-
.../lucene/index/TestForceMergeForever.java | 2 +-
.../apache/lucene/index/TestMultiFields.java | 4 +-
.../test/org/apache/lucene/index/TestNorms.java | 2 +-
.../apache/lucene/index/TestPointValues.java | 154 +-
.../apache/lucene/index/TestRollingUpdates.java | 2 +-
.../apache/lucene/index/TestSegmentInfos.java | 10 +-
.../test/org/apache/lucene/index/TestTerms.java | 10 +-
.../org/apache/lucene/index/TestTermsEnum.java | 2 +-
.../lucene/search/TestComplexExplanations.java | 10 +-
.../lucene/search/TestMultiPhraseQuery.java | 190 +-
.../lucene/search/TestNumericRangeQuery32.java | 3 +-
.../lucene/search/TestNumericRangeQuery64.java | 3 +-
.../lucene/search/TestPhrasePrefixQuery.java | 16 +-
.../apache/lucene/search/TestPointQueries.java | 1196 +-
.../lucene/search/TestPositionIncrement.java | 6 +-
.../lucene/search/TestSimpleExplanations.java | 52 +-
.../search/TestSimpleSearchEquivalence.java | 16 +-
.../lucene/search/TestSloppyPhraseQuery2.java | 10 +-
.../search/TestSortedNumericSortField.java | 15 +-
.../TestUsageTrackingFilterCachingPolicy.java | 4 +-
.../lucene/store/TestFilterDirectory.java | 4 +-
.../lucene/store/TestNRTCachingDirectory.java | 2 +-
.../apache/lucene/util/TestBytesRefArray.java | 5 +-
.../apache/lucene/util/TestBytesRefHash.java | 12 +-
.../lucene/util/TestInPlaceMergeSorter.java | 4 +-
.../org/apache/lucene/util/TestIntroSorter.java | 4 +-
.../lucene/util/TestLegacyNumericUtils.java | 16 +-
.../apache/lucene/util/TestNumericUtils.java | 491 +
.../apache/lucene/util/TestQueryBuilder.java | 20 +-
.../org/apache/lucene/util/TestTimSorter.java | 3 +-
.../org/apache/lucene/util/TestUnicodeUtil.java | 15 +-
.../org/apache/lucene/util/TestVersion.java | 18 +-
.../org/apache/lucene/util/bkd/TestBKD.java | 139 +-
.../org/apache/lucene/util/fst/TestFSTs.java | 2 +-
.../demo/facet/DistanceFacetsExample.java | 10 +-
.../lucene/demo/facet/RangeFacetsExample.java | 5 +-
.../apache/lucene/facet/range/DoubleRange.java | 37 +-
.../facet/range/DoubleRangeFacetCounts.java | 8 +-
.../apache/lucene/facet/range/LongRange.java | 25 +-
.../lucene/facet/range/LongRangeCounter.java | 14 +-
.../facet/range/TestRangeFacetCounts.java | 215 +-
.../highlight/WeightedSpanTermExtractor.java | 6 +-
.../search/highlight/HighlighterTest.java | 19 +-
lucene/ivy-versions.properties | 3 +-
.../lucene/search/join/GlobalOrdinalsQuery.java | 27 +-
.../join/GlobalOrdinalsWithScoreQuery.java | 35 +-
.../search/join/TermsIncludingScoreQuery.java | 2 +-
.../apache/lucene/search/join/TermsQuery.java | 11 +-
.../search/join/ToParentBlockJoinSortField.java | 6 +-
.../lucene/search/join/TestBlockJoin.java | 72 +-
.../apache/lucene/search/join/TestJoinUtil.java | 105 +-
lucene/licenses/spatial4j-0.5-tests.jar.sha1 | 1 -
lucene/licenses/spatial4j-0.5.jar.sha1 | 1 -
lucene/licenses/spatial4j-0.6-tests.jar.sha1 | 1 +
lucene/licenses/spatial4j-0.6.jar.sha1 | 1 +
lucene/licenses/spatial4j-NOTICE.txt | 136 +-
.../apache/lucene/index/memory/MemoryIndex.java | 13 +-
.../apache/lucene/index/SortingLeafReader.java | 10 +
.../org/apache/lucene/index/SorterTestBase.java | 8 +-
lucene/module-build.xml | 22 +
.../apache/lucene/queries/BoostingQuery.java | 12 +
.../apache/lucene/queries/CommonTermsQuery.java | 44 +
.../org/apache/lucene/queries/TermsQuery.java | 5 +
.../queries/function/FunctionRangeQuery.java | 20 +
.../apache/lucene/queries/TermsQueryTest.java | 25 +
.../queries/function/FunctionTestSetup.java | 8 +-
.../queries/function/TestFunctionQuerySort.java | 4 +-
.../queries/function/TestValueSources.java | 16 -
.../classic/MultiFieldQueryParser.java | 6 +-
.../queryparser/classic/QueryParserBase.java | 9 +-
.../builders/MultiPhraseQueryNodeBuilder.java | 6 +-
.../standard/builders/SlopQueryNodeBuilder.java | 8 +-
.../classic/TestMultiPhraseQueryParsing.java | 10 +-
.../queryparser/classic/TestQueryParser.java | 28 +-
.../apache/lucene/document/BigIntegerPoint.java | 260 +
.../lucene/document/InetAddressPoint.java | 247 +
.../org/apache/lucene/document/LatLonPoint.java | 293 +-
.../document/LatLonPointDistanceQuery.java | 209 +
.../document/LatLonPointInPolygonQuery.java | 254 +
.../org/apache/lucene/document/package.html | 7 +-
.../apache/lucene/payloads/PayloadSpanUtil.java | 6 +-
.../lucene/search/DocValuesNumbersQuery.java | 8 +
.../lucene/search/DocValuesRangeQuery.java | 20 +
.../lucene/search/DocValuesTermsQuery.java | 2 +-
.../lucene/search/PointInPolygonQuery.java | 211 -
.../apache/lucene/search/PointInRectQuery.java | 200 -
.../lucene/document/TestBigIntegerPoint.java | 96 +
.../lucene/document/TestInetAddressPoint.java | 91 +
.../apache/lucene/document/TestLatLonPoint.java | 173 +
.../document/TestLatLonPointDistanceQuery.java | 190 +
.../lucene/search/TestDocValuesRangeQuery.java | 33 +-
.../lucene/search/TestLatLonPointQueries.java | 175 +-
.../lucene/search/TestTermAutomatonQuery.java | 8 +-
lucene/spatial-extras/build.xml | 57 +
lucene/spatial-extras/ivy.xml | 36 +
.../apache/lucene/spatial/SpatialStrategy.java | 149 +
.../bbox/BBoxOverlapRatioValueSource.java | 251 +
.../spatial/bbox/BBoxSimilarityValueSource.java | 117 +
.../lucene/spatial/bbox/BBoxStrategy.java | 589 +
.../lucene/spatial/bbox/BBoxValueSource.java | 115 +
.../lucene/spatial/bbox/package-info.java | 23 +
.../composite/CompositeSpatialStrategy.java | 144 +
.../spatial/composite/CompositeVerifyQuery.java | 120 +
.../composite/IntersectsRPTVerifyQuery.java | 235 +
.../lucene/spatial/composite/package-info.java | 19 +
.../java/org/apache/lucene/spatial/package.html | 26 +
.../spatial/prefix/AbstractPrefixTreeQuery.java | 133 +
.../prefix/AbstractVisitingPrefixTreeQuery.java | 380 +
.../prefix/BytesRefIteratorTokenStream.java | 72 +
.../spatial/prefix/CellToBytesRefIterator.java | 49 +
.../spatial/prefix/ContainsPrefixTreeQuery.java | 362 +
.../spatial/prefix/HeatmapFacetCounter.java | 310 +
.../prefix/IntersectsPrefixTreeQuery.java | 95 +
.../prefix/NumberRangePrefixTreeStrategy.java | 199 +
.../PointPrefixTreeFieldCacheProvider.java | 48 +
.../spatial/prefix/PrefixTreeFacetCounter.java | 201 +
.../spatial/prefix/PrefixTreeStrategy.java | 208 +
.../prefix/RecursivePrefixTreeStrategy.java | 192 +
.../prefix/TermQueryPrefixTreeStrategy.java | 111 +
.../spatial/prefix/WithinPrefixTreeQuery.java | 232 +
.../lucene/spatial/prefix/package-info.java | 21 +
.../apache/lucene/spatial/prefix/tree/Cell.java | 109 +
.../spatial/prefix/tree/CellIterator.java | 76 +
.../prefix/tree/DateRangePrefixTree.java | 444 +
.../spatial/prefix/tree/FilterCellIterator.java | 61 +
.../spatial/prefix/tree/GeohashPrefixTree.java | 162 +
.../lucene/spatial/prefix/tree/LegacyCell.java | 242 +
.../spatial/prefix/tree/LegacyPrefixTree.java | 84 +
.../prefix/tree/NumberRangePrefixTree.java | 989 +
.../prefix/tree/PackedQuadPrefixTree.java | 459 +
.../spatial/prefix/tree/QuadPrefixTree.java | 308 +
.../prefix/tree/SingletonCellIterator.java | 36 +
.../spatial/prefix/tree/SpatialPrefixTree.java | 117 +
.../prefix/tree/SpatialPrefixTreeFactory.java | 99 +
.../spatial/prefix/tree/TreeCellIterator.java | 87 +
.../spatial/prefix/tree/package-info.java | 30 +
.../lucene/spatial/query/SpatialArgs.java | 148 +
.../lucene/spatial/query/SpatialArgsParser.java | 146 +
.../lucene/spatial/query/SpatialOperation.java | 179 +
.../query/UnsupportedSpatialOperation.java | 28 +
.../lucene/spatial/query/package-info.java | 21 +
.../serialized/SerializedDVStrategy.java | 278 +
.../lucene/spatial/serialized/package-info.java | 21 +
.../lucene/spatial/spatial4j/Geo3dShape.java | 185 +
.../lucene/spatial/spatial4j/package-info.java | 19 +
.../spatial/util/CachingDoubleValueSource.java | 93 +
.../util/DistanceToShapeValueSource.java | 122 +
.../spatial/util/ShapeAreaValueSource.java | 116 +
.../lucene/spatial/util/ShapeFieldCache.java | 54 +
.../ShapeFieldCacheDistanceValueSource.java | 112 +
.../spatial/util/ShapeFieldCacheProvider.java | 87 +
.../spatial/util/ShapePredicateValueSource.java | 113 +
.../org/apache/lucene/spatial/util/package.html | 26 +
.../spatial/vector/DistanceValueSource.java | 120 +
.../spatial/vector/PointVectorStrategy.java | 178 +
.../lucene/spatial/vector/package-info.java | 21 +
lucene/spatial-extras/src/java/overview.html | 67 +
.../src/test-files/cities-Intersects-BBox.txt | 3 +
.../src/test-files/data/LUCENE-4464.txt | 3 +
.../src/test-files/data/countries-bbox.txt | 249 +
.../src/test-files/data/countries-poly.txt | 249 +
.../src/test-files/data/geonames-IE.txt | 22929 +++++++++++++++++
.../src/test-files/data/simple-bbox.txt | 4 +
.../src/test-files/data/states-bbox.txt | 52 +
.../src/test-files/data/states-poly.txt | 52 +
.../src/test-files/data/world-cities-points.txt | 2680 ++
.../src/test-files/simple-Queries-BBox.txt | 9 +
.../src/test-files/states-Intersects-BBox.txt | 3 +
.../src/test-files/states-IsWithin-BBox.txt | 4 +
.../lucene/spatial/DistanceStrategyTest.java | 135 +
.../apache/lucene/spatial/PortedSolr3Test.java | 167 +
.../lucene/spatial/QueryEqualsHashCodeTest.java | 119 +
.../apache/lucene/spatial/SpatialArgsTest.java | 50 +
.../apache/lucene/spatial/SpatialExample.java | 200 +
.../lucene/spatial/SpatialMatchConcern.java | 31 +
.../apache/lucene/spatial/SpatialTestCase.java | 280 +
.../apache/lucene/spatial/SpatialTestData.java | 71 +
.../apache/lucene/spatial/SpatialTestQuery.java | 96 +
.../apache/lucene/spatial/StrategyTestCase.java | 252 +
.../lucene/spatial/TestTestFramework.java | 68 +
.../lucene/spatial/bbox/TestBBoxStrategy.java | 301 +
.../composite/CompositeStrategyTest.java | 142 +
.../prefix/CellToBytesRefIterator50.java | 44 +
.../spatial/prefix/DateNRStrategyTest.java | 143 +
.../spatial/prefix/HeatmapFacetCounterTest.java | 252 +
.../lucene/spatial/prefix/JtsPolygonTest.java | 117 +
.../spatial/prefix/NumberRangeFacetsTest.java | 275 +
.../RandomSpatialOpFuzzyPrefixTree50Test.java | 31 +
.../RandomSpatialOpFuzzyPrefixTreeTest.java | 533 +
.../prefix/RandomSpatialOpStrategyTestCase.java | 141 +
.../prefix/TestRecursivePrefixTreeStrategy.java | 122 +
.../prefix/TestTermQueryPrefixGridStrategy.java | 63 +
.../prefix/tree/DateRangePrefixTreeTest.java | 175 +
.../prefix/tree/SpatialPrefixTreeTest.java | 114 +
.../spatial/query/SpatialArgsParserTest.java | 77 +
.../serialized/SerializedStrategyTest.java | 66 +
.../lucene/spatial/spatial4j/Geo3dRptTest.java | 227 +
.../Geo3dShapeRectRelationTestCase.java | 258 +
.../Geo3dShapeSphereModelRectRelationTest.java | 72 +
.../Geo3dShapeWGS84ModelRectRelationTest.java | 94 +
.../spatial4j/RandomizedShapeTestCase.java | 288 +
.../spatial/vector/TestPointVectorStrategy.java | 63 +
lucene/spatial/build.xml | 30 -
lucene/spatial/ivy.xml | 15 -
.../apache/lucene/spatial/SpatialStrategy.java | 149 -
.../bbox/BBoxOverlapRatioValueSource.java | 251 -
.../spatial/bbox/BBoxSimilarityValueSource.java | 117 -
.../lucene/spatial/bbox/BBoxStrategy.java | 591 -
.../lucene/spatial/bbox/BBoxValueSource.java | 115 -
.../lucene/spatial/bbox/package-info.java | 23 -
.../composite/CompositeSpatialStrategy.java | 144 -
.../spatial/composite/CompositeVerifyQuery.java | 121 -
.../composite/IntersectsRPTVerifyQuery.java | 235 -
.../lucene/spatial/composite/package-info.java | 19 -
.../geopoint/search/GeoPointDistanceQuery.java | 5 +
.../search/GeoPointDistanceRangeQuery.java | 6 +
.../geopoint/search/GeoPointInBBoxQuery.java | 10 +
.../geopoint/search/GeoPointInPolygonQuery.java | 6 +
.../GeoPointTermQueryConstantScoreWrapper.java | 7 +
.../spatial/prefix/AbstractPrefixTreeQuery.java | 133 -
.../prefix/AbstractVisitingPrefixTreeQuery.java | 380 -
.../prefix/BytesRefIteratorTokenStream.java | 72 -
.../spatial/prefix/CellToBytesRefIterator.java | 49 -
.../spatial/prefix/ContainsPrefixTreeQuery.java | 362 -
.../spatial/prefix/HeatmapFacetCounter.java | 310 -
.../prefix/IntersectsPrefixTreeQuery.java | 95 -
.../prefix/NumberRangePrefixTreeStrategy.java | 199 -
.../PointPrefixTreeFieldCacheProvider.java | 48 -
.../spatial/prefix/PrefixTreeFacetCounter.java | 201 -
.../spatial/prefix/PrefixTreeStrategy.java | 208 -
.../prefix/RecursivePrefixTreeStrategy.java | 196 -
.../prefix/TermQueryPrefixTreeStrategy.java | 111 -
.../spatial/prefix/WithinPrefixTreeQuery.java | 233 -
.../lucene/spatial/prefix/package-info.java | 21 -
.../apache/lucene/spatial/prefix/tree/Cell.java | 109 -
.../spatial/prefix/tree/CellIterator.java | 76 -
.../prefix/tree/DateRangePrefixTree.java | 444 -
.../spatial/prefix/tree/FilterCellIterator.java | 61 -
.../spatial/prefix/tree/GeohashPrefixTree.java | 162 -
.../lucene/spatial/prefix/tree/LegacyCell.java | 242 -
.../spatial/prefix/tree/LegacyPrefixTree.java | 84 -
.../prefix/tree/NumberRangePrefixTree.java | 989 -
.../prefix/tree/PackedQuadPrefixTree.java | 459 -
.../spatial/prefix/tree/QuadPrefixTree.java | 308 -
.../prefix/tree/SingletonCellIterator.java | 36 -
.../spatial/prefix/tree/SpatialPrefixTree.java | 117 -
.../prefix/tree/SpatialPrefixTreeFactory.java | 99 -
.../spatial/prefix/tree/TreeCellIterator.java | 87 -
.../spatial/prefix/tree/package-info.java | 30 -
.../lucene/spatial/query/SpatialArgs.java | 148 -
.../lucene/spatial/query/SpatialArgsParser.java | 146 -
.../lucene/spatial/query/SpatialOperation.java | 179 -
.../query/UnsupportedSpatialOperation.java | 28 -
.../lucene/spatial/query/package-info.java | 21 -
.../serialized/SerializedDVStrategy.java | 278 -
.../lucene/spatial/serialized/package-info.java | 21 -
.../lucene/spatial/spatial4j/Geo3dShape.java | 185 -
.../lucene/spatial/spatial4j/package-info.java | 19 -
.../spatial/util/CachingDoubleValueSource.java | 93 -
.../util/DistanceToShapeValueSource.java | 122 -
.../lucene/spatial/util/GeoEncodingUtils.java | 26 +-
.../org/apache/lucene/spatial/util/GeoRect.java | 12 +
.../lucene/spatial/util/GeoRelationUtils.java | 4 +
.../spatial/util/ShapeAreaValueSource.java | 116 -
.../lucene/spatial/util/ShapeFieldCache.java | 54 -
.../ShapeFieldCacheDistanceValueSource.java | 112 -
.../spatial/util/ShapeFieldCacheProvider.java | 87 -
.../spatial/util/ShapePredicateValueSource.java | 113 -
.../spatial/vector/DistanceValueSource.java | 120 -
.../spatial/vector/PointVectorStrategy.java | 182 -
.../lucene/spatial/vector/package-info.java | 21 -
lucene/spatial/src/java/overview.html | 50 +-
.../src/test-files/cities-Intersects-BBox.txt | 3 -
.../spatial/src/test-files/data/LUCENE-4464.txt | 3 -
.../src/test-files/data/countries-bbox.txt | 249 -
.../src/test-files/data/countries-poly.txt | 249 -
.../spatial/src/test-files/data/geonames-IE.txt | 22929 -----------------
.../spatial/src/test-files/data/simple-bbox.txt | 5 -
.../spatial/src/test-files/data/states-bbox.txt | 52 -
.../spatial/src/test-files/data/states-poly.txt | 52 -
.../src/test-files/data/world-cities-points.txt | 2680 --
.../src/test-files/simple-Queries-BBox.txt | 9 -
.../src/test-files/states-Intersects-BBox.txt | 3 -
.../src/test-files/states-IsWithin-BBox.txt | 4 -
.../lucene/spatial/DistanceStrategyTest.java | 135 -
.../apache/lucene/spatial/PortedSolr3Test.java | 167 -
.../lucene/spatial/QueryEqualsHashCodeTest.java | 119 -
.../apache/lucene/spatial/SpatialArgsTest.java | 50 -
.../apache/lucene/spatial/SpatialExample.java | 200 -
.../lucene/spatial/SpatialMatchConcern.java | 31 -
.../apache/lucene/spatial/SpatialTestCase.java | 281 -
.../apache/lucene/spatial/SpatialTestData.java | 71 -
.../apache/lucene/spatial/SpatialTestQuery.java | 96 -
.../apache/lucene/spatial/StrategyTestCase.java | 252 -
.../lucene/spatial/TestTestFramework.java | 68 -
.../lucene/spatial/bbox/TestBBoxStrategy.java | 301 -
.../composite/CompositeStrategyTest.java | 142 -
.../prefix/CellToBytesRefIterator50.java | 44 -
.../spatial/prefix/DateNRStrategyTest.java | 143 -
.../spatial/prefix/HeatmapFacetCounterTest.java | 252 -
.../lucene/spatial/prefix/JtsPolygonTest.java | 117 -
.../spatial/prefix/NumberRangeFacetsTest.java | 275 -
.../RandomSpatialOpFuzzyPrefixTree50Test.java | 31 -
.../RandomSpatialOpFuzzyPrefixTreeTest.java | 533 -
.../prefix/RandomSpatialOpStrategyTestCase.java | 141 -
.../prefix/TestRecursivePrefixTreeStrategy.java | 122 -
.../prefix/TestTermQueryPrefixGridStrategy.java | 63 -
.../prefix/tree/DateRangePrefixTreeTest.java | 175 -
.../prefix/tree/SpatialPrefixTreeTest.java | 114 -
.../spatial/query/SpatialArgsParserTest.java | 77 -
.../serialized/SerializedStrategyTest.java | 66 -
.../lucene/spatial/spatial4j/Geo3dRptTest.java | 227 -
.../Geo3dShapeRectRelationTestCase.java | 264 -
.../Geo3dShapeSphereModelRectRelationTest.java | 72 -
.../Geo3dShapeWGS84ModelRectRelationTest.java | 95 -
.../spatial4j/RandomizedShapeTestCase.java | 289 -
.../spatial/spatial4j/geo3d/GeoPointTest.java | 82 -
.../spatial/util/BaseGeoPointTestCase.java | 94 +-
.../spatial/vector/TestPointVectorStrategy.java | 63 -
.../org/apache/lucene/geo3d/ArcDistance.java | 56 -
.../apache/lucene/geo3d/BasePlanetObject.java | 52 -
.../org/apache/lucene/geo3d/BaseXYZSolid.java | 167 -
.../java/org/apache/lucene/geo3d/Bounds.java | 113 -
.../org/apache/lucene/geo3d/DistanceStyle.java | 83 -
.../org/apache/lucene/geo3d/Geo3DPoint.java | 68 -
.../java/org/apache/lucene/geo3d/Geo3DUtil.java | 59 -
.../java/org/apache/lucene/geo3d/GeoArea.java | 67 -
.../org/apache/lucene/geo3d/GeoAreaFactory.java | 55 -
.../java/org/apache/lucene/geo3d/GeoBBox.java | 36 -
.../org/apache/lucene/geo3d/GeoBBoxFactory.java | 111 -
.../org/apache/lucene/geo3d/GeoBaseBBox.java | 72 -
.../org/apache/lucene/geo3d/GeoBaseCircle.java | 34 -
.../lucene/geo3d/GeoBaseDistanceShape.java | 56 -
.../lucene/geo3d/GeoBaseMembershipShape.java | 56 -
.../org/apache/lucene/geo3d/GeoBasePolygon.java | 34 -
.../org/apache/lucene/geo3d/GeoBaseShape.java | 59 -
.../java/org/apache/lucene/geo3d/GeoCircle.java | 25 -
.../apache/lucene/geo3d/GeoCircleFactory.java | 43 -
.../geo3d/GeoCompositeMembershipShape.java | 117 -
.../lucene/geo3d/GeoCompositePolygon.java | 31 -
.../apache/lucene/geo3d/GeoConvexPolygon.java | 288 -
.../geo3d/GeoDegenerateHorizontalLine.java | 215 -
.../lucene/geo3d/GeoDegenerateLatitudeZone.java | 138 -
.../geo3d/GeoDegenerateLongitudeSlice.java | 153 -
.../apache/lucene/geo3d/GeoDegeneratePoint.java | 135 -
.../lucene/geo3d/GeoDegenerateVerticalLine.java | 205 -
.../org/apache/lucene/geo3d/GeoDistance.java | 59 -
.../apache/lucene/geo3d/GeoDistanceShape.java | 27 -
.../apache/lucene/geo3d/GeoLatitudeZone.java | 198 -
.../apache/lucene/geo3d/GeoLongitudeSlice.java | 204 -
.../apache/lucene/geo3d/GeoMembershipShape.java | 27 -
.../lucene/geo3d/GeoNorthLatitudeZone.java | 165 -
.../apache/lucene/geo3d/GeoNorthRectangle.java | 263 -
.../apache/lucene/geo3d/GeoOutsideDistance.java | 55 -
.../java/org/apache/lucene/geo3d/GeoPath.java | 797 -
.../java/org/apache/lucene/geo3d/GeoPoint.java | 193 -
.../org/apache/lucene/geo3d/GeoPolygon.java | 26 -
.../apache/lucene/geo3d/GeoPolygonFactory.java | 187 -
.../org/apache/lucene/geo3d/GeoRectangle.java | 288 -
.../java/org/apache/lucene/geo3d/GeoShape.java | 63 -
.../org/apache/lucene/geo3d/GeoSizeable.java | 40 -
.../lucene/geo3d/GeoSouthLatitudeZone.java | 168 -
.../apache/lucene/geo3d/GeoSouthRectangle.java | 259 -
.../apache/lucene/geo3d/GeoStandardCircle.java | 168 -
.../geo3d/GeoWideDegenerateHorizontalLine.java | 238 -
.../lucene/geo3d/GeoWideLongitudeSlice.java | 208 -
.../lucene/geo3d/GeoWideNorthRectangle.java | 286 -
.../apache/lucene/geo3d/GeoWideRectangle.java | 319 -
.../lucene/geo3d/GeoWideSouthRectangle.java | 284 -
.../java/org/apache/lucene/geo3d/GeoWorld.java | 106 -
.../org/apache/lucene/geo3d/LatLonBounds.java | 322 -
.../org/apache/lucene/geo3d/LinearDistance.java | 56 -
.../lucene/geo3d/LinearSquaredDistance.java | 56 -
.../org/apache/lucene/geo3d/Membership.java | 46 -
.../org/apache/lucene/geo3d/NormalDistance.java | 56 -
.../lucene/geo3d/NormalSquaredDistance.java | 56 -
.../src/java/org/apache/lucene/geo3d/Plane.java | 1657 --
.../org/apache/lucene/geo3d/PlanetModel.java | 277 -
.../lucene/geo3d/PointInGeo3DShapeQuery.java | 204 -
.../org/apache/lucene/geo3d/SidedPlane.java | 175 -
.../apache/lucene/geo3d/StandardXYZSolid.java | 417 -
.../src/java/org/apache/lucene/geo3d/Tools.java | 41 -
.../java/org/apache/lucene/geo3d/Vector.java | 378 -
.../java/org/apache/lucene/geo3d/XYZBounds.java | 267 -
.../java/org/apache/lucene/geo3d/XYZSolid.java | 26 -
.../apache/lucene/geo3d/XYZSolidFactory.java | 67 -
.../java/org/apache/lucene/geo3d/XYdZSolid.java | 213 -
.../java/org/apache/lucene/geo3d/XdYZSolid.java | 212 -
.../org/apache/lucene/geo3d/XdYdZSolid.java | 138 -
.../java/org/apache/lucene/geo3d/dXYZSolid.java | 216 -
.../org/apache/lucene/geo3d/dXYdZSolid.java | 138 -
.../org/apache/lucene/geo3d/dXdYZSolid.java | 138 -
.../org/apache/lucene/geo3d/dXdYdZSolid.java | 146 -
.../org/apache/lucene/geo3d/package-info.java | 21 -
.../org/apache/lucene/spatial3d/Geo3DPoint.java | 115 +
.../org/apache/lucene/spatial3d/Geo3DUtil.java | 59 +
.../spatial3d/PointInGeo3DShapeQuery.java | 215 +
.../lucene/spatial3d/geom/ArcDistance.java | 56 +
.../lucene/spatial3d/geom/BasePlanetObject.java | 57 +
.../lucene/spatial3d/geom/BaseXYZSolid.java | 167 +
.../apache/lucene/spatial3d/geom/Bounds.java | 113 +
.../lucene/spatial3d/geom/DistanceStyle.java | 83 +
.../apache/lucene/spatial3d/geom/GeoArea.java | 67 +
.../lucene/spatial3d/geom/GeoAreaFactory.java | 55 +
.../apache/lucene/spatial3d/geom/GeoBBox.java | 36 +
.../lucene/spatial3d/geom/GeoBBoxFactory.java | 111 +
.../lucene/spatial3d/geom/GeoBaseBBox.java | 72 +
.../lucene/spatial3d/geom/GeoBaseCircle.java | 34 +
.../spatial3d/geom/GeoBaseDistanceShape.java | 56 +
.../spatial3d/geom/GeoBaseMembershipShape.java | 56 +
.../lucene/spatial3d/geom/GeoBasePolygon.java | 34 +
.../lucene/spatial3d/geom/GeoBaseShape.java | 59 +
.../apache/lucene/spatial3d/geom/GeoCircle.java | 25 +
.../lucene/spatial3d/geom/GeoCircleFactory.java | 43 +
.../geom/GeoCompositeMembershipShape.java | 117 +
.../spatial3d/geom/GeoCompositePolygon.java | 31 +
.../lucene/spatial3d/geom/GeoConvexPolygon.java | 288 +
.../geom/GeoDegenerateHorizontalLine.java | 215 +
.../geom/GeoDegenerateLatitudeZone.java | 138 +
.../geom/GeoDegenerateLongitudeSlice.java | 153 +
.../spatial3d/geom/GeoDegeneratePoint.java | 135 +
.../geom/GeoDegenerateVerticalLine.java | 205 +
.../lucene/spatial3d/geom/GeoDistance.java | 59 +
.../lucene/spatial3d/geom/GeoDistanceShape.java | 27 +
.../lucene/spatial3d/geom/GeoLatitudeZone.java | 198 +
.../spatial3d/geom/GeoLongitudeSlice.java | 204 +
.../spatial3d/geom/GeoMembershipShape.java | 27 +
.../spatial3d/geom/GeoNorthLatitudeZone.java | 165 +
.../spatial3d/geom/GeoNorthRectangle.java | 263 +
.../spatial3d/geom/GeoOutsideDistance.java | 55 +
.../apache/lucene/spatial3d/geom/GeoPath.java | 797 +
.../apache/lucene/spatial3d/geom/GeoPoint.java | 193 +
.../lucene/spatial3d/geom/GeoPolygon.java | 26 +
.../spatial3d/geom/GeoPolygonFactory.java | 187 +
.../lucene/spatial3d/geom/GeoRectangle.java | 288 +
.../apache/lucene/spatial3d/geom/GeoShape.java | 63 +
.../lucene/spatial3d/geom/GeoSizeable.java | 40 +
.../spatial3d/geom/GeoSouthLatitudeZone.java | 168 +
.../spatial3d/geom/GeoSouthRectangle.java | 259 +
.../spatial3d/geom/GeoStandardCircle.java | 168 +
.../geom/GeoWideDegenerateHorizontalLine.java | 238 +
.../spatial3d/geom/GeoWideLongitudeSlice.java | 208 +
.../spatial3d/geom/GeoWideNorthRectangle.java | 286 +
.../lucene/spatial3d/geom/GeoWideRectangle.java | 319 +
.../spatial3d/geom/GeoWideSouthRectangle.java | 284 +
.../apache/lucene/spatial3d/geom/GeoWorld.java | 106 +
.../lucene/spatial3d/geom/LatLonBounds.java | 322 +
.../lucene/spatial3d/geom/LinearDistance.java | 56 +
.../spatial3d/geom/LinearSquaredDistance.java | 56 +
.../lucene/spatial3d/geom/Membership.java | 46 +
.../lucene/spatial3d/geom/NormalDistance.java | 56 +
.../spatial3d/geom/NormalSquaredDistance.java | 56 +
.../org/apache/lucene/spatial3d/geom/Plane.java | 1657 ++
.../lucene/spatial3d/geom/PlanetModel.java | 277 +
.../lucene/spatial3d/geom/SidedPlane.java | 175 +
.../lucene/spatial3d/geom/StandardXYZSolid.java | 417 +
.../org/apache/lucene/spatial3d/geom/Tools.java | 41 +
.../apache/lucene/spatial3d/geom/Vector.java | 378 +
.../apache/lucene/spatial3d/geom/XYZBounds.java | 267 +
.../apache/lucene/spatial3d/geom/XYZSolid.java | 26 +
.../lucene/spatial3d/geom/XYZSolidFactory.java | 67 +
.../apache/lucene/spatial3d/geom/XYdZSolid.java | 213 +
.../apache/lucene/spatial3d/geom/XdYZSolid.java | 212 +
.../lucene/spatial3d/geom/XdYdZSolid.java | 138 +
.../apache/lucene/spatial3d/geom/dXYZSolid.java | 216 +
.../lucene/spatial3d/geom/dXYdZSolid.java | 138 +
.../lucene/spatial3d/geom/dXdYZSolid.java | 138 +
.../lucene/spatial3d/geom/dXdYdZSolid.java | 146 +
.../lucene/spatial3d/geom/package-info.java | 22 +
.../apache/lucene/spatial3d/package-info.java | 21 +
lucene/spatial3d/src/java/overview.html | 3 +-
.../org/apache/lucene/geo3d/GeoBBoxTest.java | 364 -
.../org/apache/lucene/geo3d/GeoCircleTest.java | 415 -
.../lucene/geo3d/GeoConvexPolygonTest.java | 91 -
.../org/apache/lucene/geo3d/GeoModelTest.java | 110 -
.../org/apache/lucene/geo3d/GeoPathTest.java | 270 -
.../org/apache/lucene/geo3d/GeoPolygonTest.java | 165 -
.../test/org/apache/lucene/geo3d/PlaneTest.java | 64 -
.../org/apache/lucene/geo3d/TestGeo3DPoint.java | 794 -
.../org/apache/lucene/geo3d/XYZSolidTest.java | 220 -
.../apache/lucene/spatial3d/TestGeo3DPoint.java | 810 +
.../lucene/spatial3d/geom/GeoBBoxTest.java | 364 +
.../lucene/spatial3d/geom/GeoCircleTest.java | 410 +
.../spatial3d/geom/GeoConvexPolygonTest.java | 91 +
.../lucene/spatial3d/geom/GeoModelTest.java | 110 +
.../lucene/spatial3d/geom/GeoPathTest.java | 270 +
.../lucene/spatial3d/geom/GeoPointTest.java | 77 +
.../lucene/spatial3d/geom/GeoPolygonTest.java | 165 +
.../apache/lucene/spatial3d/geom/PlaneTest.java | 64 +
.../lucene/spatial3d/geom/XYZSolidTest.java | 220 +
.../search/suggest/SortedInputIterator.java | 23 +-
.../suggest/document/FuzzyCompletionQuery.java | 42 +
.../suggest/document/PrefixCompletionQuery.java | 7 +
.../suggest/document/RegexCompletionQuery.java | 15 +
.../suggest/fst/FSTCompletionBuilder.java | 5 +-
.../lucene/search/suggest/tst/TSTLookup.java | 46 +-
.../search/suggest/TestInputIterator.java | 21 +-
.../analyzing/AnalyzingInfixSuggesterTest.java | 21 +-
.../analyzing/TestFreeTextSuggester.java | 2 +-
.../suggest/document/TestSuggestField.java | 3 +-
.../search/suggest/fst/BytesRefSortersTest.java | 5 +-
.../lucene/codecs/asserting/AssertingCodec.java | 8 +-
.../codecs/asserting/AssertingPointFormat.java | 153 -
.../codecs/asserting/AssertingPointsFormat.java | 276 +
.../lucene/codecs/cranky/CrankyCodec.java | 6 +-
.../lucene/codecs/cranky/CrankyPointFormat.java | 175 -
.../codecs/cranky/CrankyPointsFormat.java | 185 +
.../index/BaseDocValuesFormatTestCase.java | 2 +-
.../lucene/index/BasePointFormatTestCase.java | 917 -
.../lucene/index/BasePointsFormatTestCase.java | 950 +
.../index/BaseStoredFieldsFormatTestCase.java | 53 +-
.../lucene/index/MockRandomMergePolicy.java | 2 +-
.../org/apache/lucene/index/RandomCodec.java | 37 +-
.../ThreadedIndexingAndSearchingTestCase.java | 4 +-
.../lucene/mockfile/FilterFileChannel.java | 2 +-
.../apache/lucene/mockfile/FilterFileStore.java | 2 +-
.../lucene/mockfile/FilterFileSystem.java | 2 +-
.../mockfile/FilterFileSystemProvider.java | 2 +-
.../lucene/mockfile/FilterOutputStream2.java | 2 +-
.../apache/lucene/search/AssertingQuery.java | 8 +
.../lucene/search/ShardSearchingTestBase.java | 2 +-
.../lucene/store/MockDirectoryWrapper.java | 7 +-
.../org/apache/lucene/util/LineFileDocs.java | 58 +-
.../org/apache/lucene/util/LuceneTestCase.java | 119 +-
.../java/org/apache/lucene/util/TestUtil.java | 57 +-
.../asserting/TestAssertingPointFormat.java | 30 -
.../asserting/TestAssertingPointsFormat.java | 30 +
lucene/tools/javadoc/ecj.javadocs.prefs | 2 +-
lucene/version.properties | 2 +-
solr/CHANGES.txt | 117 +
solr/bin/solr | 5 +-
solr/build.xml | 16 +-
solr/common-build.xml | 8 +-
.../solr/analytics/util/AnalyticsParsers.java | 9 +-
.../clustering/carrot2/CarrotParams.java | 10 +-
.../clustering/carrot2/SolrResourceLocator.java | 4 +-
.../SolrStopwordsCarrot2LexicalDataFactory.java | 6 +-
.../solr/collection1/conf/solrconfig.xml | 5 -
.../carrot2/CarrotClusteringEngineTest.java | 6 -
.../carrot2/EchoClusteringAlgorithm.java | 6 +-
.../carrot2/EchoStemsClusteringAlgorithm.java | 8 +-
.../carrot2/EchoTokensClusteringAlgorithm.java | 6 +-
...exicalResourcesCheckClusteringAlgorithm.java | 6 +-
.../carrot2/MockClusteringAlgorithm.java | 12 +-
.../dataimport/EntityProcessorWrapper.java | 12 -
.../dataimport/TestContentStreamDataSource.java | 6 +-
.../TestSolrEntityProcessorEndToEnd.java | 6 +-
.../solr/hadoop/MorphlineGoLiveMiniMRTest.java | 1 -
.../solr/collection1/conf/solrconfig.xml | 8 +-
.../test-files/solr/minimr/conf/solrconfig.xml | 8 +-
.../test-files/solr/mrunit/conf/solrconfig.xml | 9 +-
.../collection1/conf/solrconfig.xml | 8 +-
.../solr/solrcloud/conf/solrconfig.xml | 8 +-
.../UIMAUpdateRequestProcessorTest.java | 6 +-
solr/core/ivy.xml | 2 +-
.../client/solrj/embedded/JettySolrRunner.java | 120 +-
.../src/java/org/apache/solr/cloud/Assign.java | 19 +-
.../org/apache/solr/cloud/ElectionContext.java | 116 +-
.../org/apache/solr/cloud/LeaderElector.java | 10 +-
.../cloud/LeaderInitiatedRecoveryThread.java | 6 -
.../java/org/apache/solr/cloud/Overseer.java | 122 +-
.../cloud/OverseerCollectionMessageHandler.java | 195 +-
.../solr/cloud/OverseerNodePrioritizer.java | 2 +-
.../solr/cloud/OverseerTaskProcessor.java | 14 +-
.../solr/cloud/SizeLimitedDistributedMap.java | 5 +-
.../src/java/org/apache/solr/cloud/ZkCLI.java | 4 +-
.../org/apache/solr/cloud/ZkController.java | 113 +-
.../apache/solr/cloud/rule/ReplicaAssigner.java | 60 +-
.../java/org/apache/solr/cloud/rule/Rule.java | 4 +-
.../solr/core/CachingDirectoryFactory.java | 3 +-
.../org/apache/solr/core/CoreContainer.java | 9 +-
.../org/apache/solr/core/CoreDescriptor.java | 1 +
.../java/org/apache/solr/core/NodeConfig.java | 20 -
.../java/org/apache/solr/core/SolrConfig.java | 8 +-
.../src/java/org/apache/solr/core/SolrCore.java | 168 +-
.../java/org/apache/solr/core/SolrCores.java | 14 +-
.../solr/handler/CdcrReplicatorScheduler.java | 39 +-
.../apache/solr/handler/CdcrRequestHandler.java | 2 +-
.../org/apache/solr/handler/IndexFetcher.java | 13 +-
.../solr/handler/MoreLikeThisHandler.java | 17 -
.../apache/solr/handler/ReplicationHandler.java | 25 +-
.../org/apache/solr/handler/RestoreCore.java | 6 +-
.../org/apache/solr/handler/SchemaHandler.java | 77 +-
.../apache/solr/handler/SolrConfigHandler.java | 3 +-
.../solr/handler/admin/AdminHandlers.java | 151 -
.../solr/handler/admin/ClusterStatus.java | 3 -
.../solr/handler/admin/CollectionsHandler.java | 6 +-
.../solr/handler/admin/CoreAdminHandler.java | 31 +-
.../solr/handler/admin/CoreAdminOperation.java | 27 +-
.../solr/handler/admin/LukeRequestHandler.java | 19 +-
.../solr/handler/admin/RebalanceLeaders.java | 2 +-
.../handler/component/DateFacetProcessor.java | 255 -
.../solr/handler/component/FacetComponent.java | 74 +-
.../solr/handler/component/MergeStrategy.java | 12 +-
.../solr/handler/component/SearchHandler.java | 13 +-
.../component/ShardFieldSortedHitQueue.java | 25 +-
.../handler/component/SpatialHeatmapFacets.java | 4 +-
.../handler/component/StatsValuesFactory.java | 10 +-
.../solr/handler/component/TermsComponent.java | 30 +-
.../solr/handler/loader/CSVLoaderBase.java | 5 +-
.../solr/highlight/DefaultSolrHighlighter.java | 7 +-
.../org/apache/solr/internal/csv/CSVParser.java | 34 +-
.../apache/solr/internal/csv/CSVStrategy.java | 338 +-
.../java/org/apache/solr/parser/CharStream.java | 16 -
.../org/apache/solr/parser/FastCharStream.java | 8 -
.../apache/solr/parser/SolrQueryParserBase.java | 11 +-
.../org/apache/solr/request/IntervalFacets.java | 14 +-
.../org/apache/solr/request/SimpleFacets.java | 24 +-
.../apache/solr/response/CSVResponseWriter.java | 6 +-
.../org/apache/solr/rest/SolrSchemaRestApi.java | 56 +-
.../solr/rest/schema/BaseFieldResource.java | 146 -
.../solr/rest/schema/BaseFieldTypeResource.java | 98 -
.../schema/CopyFieldCollectionResource.java | 198 -
.../schema/DynamicFieldCollectionResource.java | 207 -
.../solr/rest/schema/DynamicFieldResource.java | 197 -
.../rest/schema/FieldCollectionResource.java | 225 -
.../apache/solr/rest/schema/FieldResource.java | 201 -
.../schema/FieldTypeCollectionResource.java | 197 -
.../solr/rest/schema/FieldTypeResource.java | 203 -
.../analysis/ManagedSynonymFilterFactory.java | 1 -
.../solr/schema/AbstractSpatialFieldType.java | 35 +-
.../AbstractSpatialPrefixTreeFieldType.java | 2 +-
.../java/org/apache/solr/schema/BBoxField.java | 2 +-
.../org/apache/solr/schema/DateRangeField.java | 2 +-
.../org/apache/solr/schema/GeoHashField.java | 8 +-
.../org/apache/solr/schema/IndexSchema.java | 20 +-
.../java/org/apache/solr/schema/LatLonType.java | 8 +-
.../java/org/apache/solr/schema/PointType.java | 2 +-
.../schema/RptWithGeometrySpatialField.java | 7 +-
.../org/apache/solr/schema/TrieDoubleField.java | 5 +-
.../java/org/apache/solr/schema/TrieField.java | 95 +-
.../org/apache/solr/schema/TrieFloatField.java | 5 +-
.../java/org/apache/solr/search/CursorMark.java | 11 +-
.../solr/search/ExtendedDismaxQParser.java | 8 +-
.../apache/solr/search/SolrIndexSearcher.java | 12 +-
.../apache/solr/search/ValueSourceParser.java | 2 +-
.../apache/solr/search/facet/FacetModule.java | 23 +-
.../apache/solr/search/facet/FacetRange.java | 6 +-
.../solr/search/facet/UnInvertedField.java | 9 +-
.../distance/GeoDistValueSourceParser.java | 10 +-
.../function/distance/GeohashFunction.java | 2 +-
.../distance/GeohashHaversineFunction.java | 10 +-
.../distance/HaversineConstFunction.java | 4 +-
.../function/distance/HaversineFunction.java | 2 +-
.../apache/solr/search/mlt/CloudMLTQParser.java | 2 +-
.../org/apache/solr/servlet/HttpSolrCall.java | 3 +
.../java/org/apache/solr/update/PeerSync.java | 38 +-
.../org/apache/solr/update/SolrIndexConfig.java | 12 +-
.../apache/solr/update/UpdateShardHandler.java | 5 -
.../processor/DistributedUpdateProcessor.java | 4 +-
.../DocExpirationUpdateProcessorFactory.java | 6 +-
.../processor/UpdateRequestProcessorChain.java | 6 -
.../org/apache/solr/util/DistanceUnits.java | 6 +-
.../java/org/apache/solr/util/FileUtils.java | 3 +
.../java/org/apache/solr/util/SpatialUtils.java | 18 +-
.../solr/collection1/conf/schema_latest.xml | 2 +-
.../solr/collection1/conf/solrconfig-sql.xml | 1 -
.../configsets/cloud-minimal/conf/schema.xml | 32 +
.../cloud-minimal/conf/solrconfig.xml | 48 +
.../solr/DistributedIntervalFacetingTest.java | 8 +-
.../org/apache/solr/TestDistributedSearch.java | 32 +-
.../org/apache/solr/TestGroupingSearch.java | 28 +-
.../org/apache/solr/TestRandomDVFaceting.java | 3 -
.../org/apache/solr/TestSolrCoreProperties.java | 5 +-
.../core/src/test/org/apache/solr/TestTrie.java | 14 +-
.../solr/cloud/BaseCdcrDistributedZkTest.java | 10 +-
.../solr/cloud/BasicDistributedZkTest.java | 31 +-
.../cloud/ChaosMonkeyNothingIsSafeTest.java | 2 +-
.../solr/cloud/ChaosMonkeyShardSplitTest.java | 2 +-
.../apache/solr/cloud/CollectionReloadTest.java | 2 +-
.../cloud/CollectionTooManyReplicasTest.java | 6 +-
.../CollectionsAPIAsyncDistributedZkTest.java | 174 +-
.../solr/cloud/CollectionsAPISolrJTest.java | 474 +
.../solr/cloud/CollectionsAPISolrJTests.java | 472 -
.../apache/solr/cloud/CustomCollectionTest.java | 1 -
.../apache/solr/cloud/DeleteReplicaTest.java | 60 +-
.../org/apache/solr/cloud/DeleteShardTest.java | 82 +-
.../org/apache/solr/cloud/ForceLeaderTest.java | 15 +-
.../apache/solr/cloud/HttpPartitionTest.java | 9 +-
.../apache/solr/cloud/LeaderElectionTest.java | 11 +-
.../cloud/LeaderFailoverAfterPartitionTest.java | 2 -
.../LeaderInitiatedRecoveryOnCommitTest.java | 4 +-
.../apache/solr/cloud/MigrateRouteKeyTest.java | 4 +-
.../apache/solr/cloud/OverseerRolesTest.java | 2 +-
.../org/apache/solr/cloud/OverseerTest.java | 64 +-
.../solr/cloud/ReplicaPropertiesBase.java | 3 -
.../org/apache/solr/cloud/ShardSplitTest.java | 28 +-
.../apache/solr/cloud/SolrCloudExampleTest.java | 10 +-
.../org/apache/solr/cloud/SyncSliceTest.java | 1 -
.../solr/cloud/TestCloudDeleteByQuery.java | 244 +
.../TestLeaderInitiatedRecoveryThread.java | 1 -
.../solr/cloud/TestMiniSolrCloudCluster.java | 47 +-
.../cloud/TestMiniSolrCloudClusterBase.java | 3 +-
.../cloud/TestRandomRequestDistribution.java | 6 +-
.../apache/solr/cloud/TestRebalanceLeaders.java | 1 -
.../solr/cloud/TestReplicaProperties.java | 1 -
.../cloud/TestSizeLimitedDistributedMap.java | 58 +
.../cloud/TestSolrCloudWithKerberosAlt.java | 1 +
.../solr/cloud/UnloadDistributedZkTest.java | 21 +-
.../org/apache/solr/cloud/ZkControllerTest.java | 2 +-
.../apache/solr/cloud/hdfs/StressHdfsTest.java | 3 +-
.../solr/cloud/overseer/ZkStateReaderTest.java | 6 +-
.../solr/cloud/overseer/ZkStateWriterTest.java | 10 +-
.../solr/core/TestImplicitCoreProperties.java | 61 +-
.../apache/solr/core/TestSolrConfigHandler.java | 4 +-
.../test/org/apache/solr/core/TestSolrXml.java | 4 -
.../apache/solr/core/TestXIncludeConfig.java | 4 +-
.../solr/handler/TestReplicationHandler.java | 7 +-
.../handler/TestReplicationHandlerBackup.java | 8 +-
.../apache/solr/handler/TestRestoreCore.java | 63 +-
.../handler/component/StatsComponentTest.java | 44 +-
.../solr/index/hdfs/CheckHdfsIndexTest.java | 2 +
.../apache/solr/internal/csv/CSVParserTest.java | 10 +-
.../solr/internal/csv/CSVPrinterTest.java | 3 +-
.../apache/solr/request/SimpleFacetsTest.java | 134 +-
.../org/apache/solr/request/TestFaceting.java | 105 +-
.../solr/request/TestIntervalFaceting.java | 8 +-
.../rest/schema/TestClassNameShortening.java | 3 +-
.../schema/TestCopyFieldCollectionResource.java | 96 +-
.../TestDynamicFieldCollectionResource.java | 29 -
.../rest/schema/TestDynamicFieldResource.java | 7 -
.../schema/TestFieldCollectionResource.java | 45 -
.../solr/rest/schema/TestFieldResource.java | 23 +-
.../schema/TestFieldTypeCollectionResource.java | 1 +
.../solr/rest/schema/TestFieldTypeResource.java | 17 +-
.../TestManagedSchemaDynamicFieldResource.java | 366 -
.../schema/TestManagedSchemaFieldResource.java | 369 -
.../TestManagedSchemaFieldTypeResource.java | 350 -
.../schema/TestRemoveLastDynamicCopyField.java | 80 -
.../schema/TestSchemaSimilarityResource.java | 1 -
.../analysis/TestManagedStopFilterFactory.java | 2 +-
.../TestManagedSynonymFilterFactory.java | 14 +-
.../solr/schema/SpatialRPTFieldTypeTest.java | 56 +-
.../TestCloudManagedSchemaConcurrent.java | 3 +-
.../org/apache/solr/search/TestLFUCache.java | 13 +-
.../apache/solr/search/TestRankQueryPlugin.java | 34 +-
.../org/apache/solr/search/TestRecovery.java | 160 +-
.../apache/solr/search/TestRecoveryHdfs.java | 140 +-
.../apache/solr/search/TestSolr4Spatial.java | 8 +-
.../test/org/apache/solr/search/TestSort.java | 33 +-
.../solr/search/facet/TestJsonFacets.java | 30 +-
.../function/distance/DistanceFunctionTest.java | 4 +-
.../solr/search/join/TestScoreJoinQPScore.java | 9 +-
.../similarities/TestPerFieldSimilarity.java | 1 -
.../TestPerFieldSimilarityClassic.java | 86 -
.../solr/security/BasicAuthIntegrationTest.java | 2 +-
.../apache/solr/update/CdcrUpdateLogTest.java | 27 +-
.../solr/update/DirectUpdateHandlerTest.java | 2 +-
.../update/TestDocBasedVersionConstraints.java | 30 +-
...DocExpirationUpdateProcessorFactoryTest.java | 11 +-
.../SignatureUpdateProcessorFactoryTest.java | 12 +-
...atelessScriptUpdateProcessorFactoryTest.java | 4 +-
.../UniqFieldsUpdateProcessorFactoryTest.java | 3 +-
.../UpdateRequestProcessorFactoryTest.java | 8 +-
.../org/apache/solr/util/DistanceUnitsTest.java | 2 +-
.../example-DIH/solr/db/conf/solrconfig.xml | 10 +-
.../example-DIH/solr/mail/conf/solrconfig.xml | 10 +-
.../example-DIH/solr/rss/conf/solrconfig.xml | 10 +-
.../example-DIH/solr/solr/conf/solrconfig.xml | 10 +-
.../example-DIH/solr/tika/conf/solrconfig.xml | 11 +-
solr/example/files/conf/params.json | 6 +-
solr/example/files/conf/solrconfig.xml | 21 +-
solr/licenses/spatial4j-0.5.jar.sha1 | 1 -
solr/licenses/spatial4j-0.6.jar.sha1 | 1 +
solr/licenses/spatial4j-NOTICE.txt | 136 +-
.../basic_configs/conf/solrconfig.xml | 7 +-
.../conf/solrconfig.xml | 11 +-
.../conf/solrconfig.xml | 12 +-
solr/site/quickstart.mdtext | 2 -
.../solr/client/solrj/impl/HttpSolrClient.java | 5 -
.../client/solrj/impl/LBHttpSolrClient.java | 13 +-
.../solr/client/solrj/io/sql/ResultSetImpl.java | 2 +-
.../solrj/request/CollectionAdminRequest.java | 772 +-
.../client/solrj/request/CoreAdminRequest.java | 8 +-
.../solr/client/solrj/response/FacetField.java | 26 -
.../solr/client/solrj/response/PivotField.java | 8 -
.../client/solrj/response/QueryResponse.java | 24 -
.../solr/client/solrj/util/ClientUtils.java | 36 -
.../solr/common/cloud/ClosableThread.java | 26 -
.../apache/solr/common/cloud/SolrZkClient.java | 7 +-
.../apache/solr/common/cloud/ZkCmdExecutor.java | 5 -
.../apache/solr/common/util/ExecutorUtil.java | 59 +-
.../apache/solr/common/util/IteratorChain.java | 86 -
.../apache/solr/common/util/JavaBinCodec.java | 40 +-
.../solrj/sampleDateFacetResponse.xml | 81 -
.../solrj/sampleRangeFacetResponse.xml | 44 +
.../solr/collection1/conf/solrconfig-sql.xml | 1 -
.../solrj/beans/TestDocumentObjectBinder.java | 101 +-
.../solr/client/solrj/io/sql/JdbcTest.java | 15 +
.../solr/client/solrj/request/SchemaTest.java | 4 -
.../request/TestCollectionAdminRequest.java | 8 +-
.../client/solrj/request/TestCoreAdmin.java | 4 +-
.../solrj/response/NoOpResponseParserTest.java | 2 +-
.../solrj/response/QueryResponseTest.java | 26 +-
.../solr/common/params/SolrParamTest.java | 36 +-
.../solr/common/util/IteratorChainTest.java | 104 -
.../solr/common/util/TestJavaBinCodec.java | 54 +-
.../solr/BaseDistributedSearchTestCase.java | 32 +
.../java/org/apache/solr/SolrTestCaseHS.java | 13 +-
.../java/org/apache/solr/SolrTestCaseJ4.java | 22 +-
.../solr/cloud/AbstractDistribZkTestBase.java | 4 +-
.../cloud/AbstractFullDistribZkTestBase.java | 12 +-
.../java/org/apache/solr/cloud/ChaosMonkey.java | 14 +-
.../apache/solr/cloud/SolrCloudTestCase.java | 163 +
solr/webapp/web/index.html | 2 +-
solr/webapp/web/js/angular/app.js | 11 -
solr/webapp/web/js/scripts/app.js | 11 -
1007 files changed, 70995 insertions(+), 70102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/core/CoreContainer.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/handler/CdcrRequestHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
----------------------------------------------------------------------
diff --cc solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
index 0fa90bc,4279864..e850796
--- a/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
@@@ -20,13 -19,16 +20,18 @@@ package org.apache.solr.handler
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
+ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+ import java.util.Locale;
+ import java.util.Map;
import java.util.Set;
+ import com.google.common.collect.ImmutableMap;
+ import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableList;
import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.ContentStream;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
----------------------------------------------------------------------
diff --cc solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index abfea2c,593dac8..b12e1fb
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@@ -76,6 -74,6 +76,7 @@@ import org.apache.solr.client.solrj.req
import org.apache.solr.client.solrj.request.CoreAdminRequest.RequestSyncShard;
import org.apache.solr.client.solrj.response.RequestStatusState;
import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
++import org.apache.solr.cloud.DistributedMap;
import org.apache.solr.cloud.Overseer;
import org.apache.solr.cloud.OverseerCollectionMessageHandler;
import org.apache.solr.cloud.OverseerSolrResponse;
@@@ -110,6 -108,6 +111,7 @@@ import org.apache.solr.common.util.Simp
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.CloudConfig;
import org.apache.solr.core.CoreContainer;
++import org.apache.solr.handler.BlobHandler;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.component.ShardHandler;
import org.apache.solr.request.SolrQueryRequest;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/78154085/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
----------------------------------------------------------------------
[02/50] [abbrv] lucene-solr git commit: SOLR-8736: schema GET
operations on fields, dynamicFields, fieldTypes,
copyField are reimplemented as a part of the bulk API with less details. The
tests and write implementations are removed
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestRemoveLastDynamicCopyField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestRemoveLastDynamicCopyField.java b/solr/core/src/test/org/apache/solr/rest/schema/TestRemoveLastDynamicCopyField.java
deleted file mode 100644
index 4b4ddd3..0000000
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestRemoveLastDynamicCopyField.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-
-import java.io.File;
-import java.io.StringReader;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.solr.util.RestTestBase;
-import org.junit.After;
-import org.junit.Before;
-import org.noggit.JSONParser;
-import org.noggit.ObjectBuilder;
-
-public class TestRemoveLastDynamicCopyField extends RestTestBase {
- private static File tmpSolrHome;
-
- @Before
- public void before() throws Exception {
- tmpSolrHome = createTempDir().toFile();
- FileUtils.copyDirectory(new File(TEST_HOME()), tmpSolrHome.getAbsoluteFile());
-
- System.setProperty("managed.schema.mutable", "true");
- System.setProperty("enable.update.log", "false");
-
- createJettyAndHarness(tmpSolrHome.getAbsolutePath(), "solrconfig-managed-schema.xml", "schema-single-dynamic-copy-field.xml",
- "/solr", true, null);
- }
-
- @After
- public void after() throws Exception {
- if (jetty != null) {
- jetty.stop();
- jetty = null;
- }
- client = null;
- if (restTestHarness != null) {
- restTestHarness.close();
- }
- restTestHarness = null;
- }
-
- public void test() throws Exception {
- List copyFields = getCopyFields();
- assertEquals("There is more than one copyField directive", 1, copyFields.size());
- assertEquals("The copyField source is not '*'", "*", ((Map)copyFields.get(0)).get("source"));
- assertEquals("The copyField dest is not 'text'", "text", ((Map)copyFields.get(0)).get("dest"));
-
- String payload = "{ 'delete-copy-field': { 'source': '*', 'dest': 'text' } }";
-
- String response = restTestHarness.post("/schema?wt=json", json(payload));
- Map map = (Map)ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
- assertNull(response, map.get("errors"));
-
- assertEquals(0, getCopyFields().size());
- }
-
- private List getCopyFields() throws Exception {
- String response = restTestHarness.query("/schema?wt=json");
- System.err.println(response);
- Map map = (Map)ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
- return (List)((Map)map.get("schema")).get("copyFields");
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestSchemaSimilarityResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestSchemaSimilarityResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestSchemaSimilarityResource.java
index 6b7be71..2016677 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestSchemaSimilarityResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestSchemaSimilarityResource.java
@@ -24,7 +24,6 @@ public class TestSchemaSimilarityResource extends SolrRestletTestBase {
* NOTE: schema used by parent class doesn't define a global sim, so we get the implicit default
* which causes the FQN of the class to be returned
*
- * @see TestClassNameShortening#testShortenedGlobalSimilarityStaysShortened
*/
@Test
public void testGetSchemaSimilarity() throws Exception {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedStopFilterFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedStopFilterFactory.java b/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedStopFilterFactory.java
index 242e5b5..be8c394 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedStopFilterFactory.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedStopFilterFactory.java
@@ -140,7 +140,7 @@ public class TestManagedStopFilterFactory extends RestTestBase {
"/response/lst[@name='error']/int[@name='code'] = '404'");
// add the new field
- assertJPut("/schema/fields/" + newFieldName, json("{'type':'managed_en'}"),
+ assertJPost("/schema/fields", "{add-field : { name :managed_en_field, type : managed_en}}",
"/responseHeader/status==0");
// make sure the new field exists now
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedSynonymFilterFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedSynonymFilterFactory.java b/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedSynonymFilterFactory.java
index 9afaf6f..26fcde1 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedSynonymFilterFactory.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/analysis/TestManagedSynonymFilterFactory.java
@@ -90,8 +90,8 @@ public class TestManagedSynonymFilterFactory extends RestTestBase {
JSONUtil.toJSON(syns),
"/responseHeader/status==0");
- assertJQ(endpoint,
- "/synonymMappings/managedMap/happy==['cheerful','glad','joyful']");
+ assertJQ(endpoint,
+ "/synonymMappings/managedMap/happy==['cheerful','glad','joyful']");
// request to a specific mapping
assertJQ(endpoint+"/happy",
@@ -146,7 +146,7 @@ public class TestManagedSynonymFilterFactory extends RestTestBase {
"/response/lst[@name='error']/int[@name='code'] = '404'");
// add the new field
- assertJPut("/schema/fields/" + newFieldName, json("{'type':'managed_en'}"),
+ assertJPost("/schema", "{ add-field : { name: managed_en_field, type : managed_en}}",
"/responseHeader/status==0");
// make sure the new field exists now
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchemaConcurrent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchemaConcurrent.java b/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchemaConcurrent.java
index 3d0d120..0993ba1 100644
--- a/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchemaConcurrent.java
+++ b/solr/core/src/test/org/apache/solr/schema/TestCloudManagedSchemaConcurrent.java
@@ -37,11 +37,12 @@ import org.apache.solr.util.RestTestHarness;
import org.apache.zookeeper.data.Stat;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.restlet.ext.servlet.ServerServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
+@Ignore
public class TestCloudManagedSchemaConcurrent extends AbstractFullDistribZkTestBase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String SUCCESS_XPATH = "/response/lst[@name='responseHeader']/int[@name='status'][.='0']";
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
index b723abf..72051b1 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
@@ -575,10 +575,6 @@ public class SchemaTest extends RestTestBase {
assertThat("solr.TextField", is(equalTo(newFieldTypeRepresentation.getAttributes().get("class"))));
assertThat(analyzerDefinition.getTokenizer().get("class"),
is(equalTo(newFieldTypeRepresentation.getAnalyzer().getTokenizer().get("class"))));
- assertTrue(newFieldTypeRepresentation.getFields().size() == 1);
- assertTrue(newFieldTypeRepresentation.getFields().contains(fieldName));
- assertTrue(newFieldTypeRepresentation.getDynamicFields().size() == 1);
- assertTrue(newFieldTypeRepresentation.getDynamicFields().contains(dynamicFieldName));
}
@Test
[16/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBoxFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBoxFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBoxFactory.java
new file mode 100755
index 0000000..de7493e
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBBoxFactory.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Factory for {@link GeoBBox}.
+ *
+ * @lucene.experimental
+ */
+public class GeoBBoxFactory {
+ private GeoBBoxFactory() {
+ }
+
+ /**
+ * Create a geobbox of the right kind given the specified bounds.
+ *
+ * @param planetModel is the planet model
+ * @param topLat is the top latitude
+ * @param bottomLat is the bottom latitude
+ * @param leftLon is the left longitude
+ * @param rightLon is the right longitude
+ * @return a GeoBBox corresponding to what was specified.
+ */
+ public static GeoBBox makeGeoBBox(final PlanetModel planetModel, double topLat, double bottomLat, double leftLon, double rightLon) {
+ //System.err.println("Making rectangle for topLat="+topLat*180.0/Math.PI+", bottomLat="+bottomLat*180.0/Math.PI+", leftLon="+leftLon*180.0/Math.PI+", rightlon="+rightLon*180.0/Math.PI);
+ if (topLat > Math.PI * 0.5)
+ topLat = Math.PI * 0.5;
+ if (bottomLat < -Math.PI * 0.5)
+ bottomLat = -Math.PI * 0.5;
+ if (leftLon < -Math.PI)
+ leftLon = -Math.PI;
+ if (rightLon > Math.PI)
+ rightLon = Math.PI;
+ if (Math.abs(leftLon + Math.PI) < Vector.MINIMUM_RESOLUTION && Math.abs(rightLon - Math.PI) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION && Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
+ return new GeoWorld(planetModel);
+ if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION || Math.abs(topLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
+ return new GeoDegeneratePoint(planetModel, topLat, 0.0);
+ return new GeoDegenerateLatitudeZone(planetModel, topLat);
+ }
+ if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
+ return new GeoNorthLatitudeZone(planetModel, bottomLat);
+ else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
+ return new GeoSouthLatitudeZone(planetModel, topLat);
+ return new GeoLatitudeZone(planetModel, topLat, bottomLat);
+ }
+ //System.err.println(" not latitude zone");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0)
+ extent += Math.PI * 2.0;
+ if (topLat == Math.PI * 0.5 && bottomLat == -Math.PI * 0.5) {
+ if (Math.abs(leftLon - rightLon) < Vector.MINIMUM_RESOLUTION)
+ return new GeoDegenerateLongitudeSlice(planetModel, leftLon);
+
+ if (extent >= Math.PI)
+ return new GeoWideLongitudeSlice(planetModel, leftLon, rightLon);
+
+ return new GeoLongitudeSlice(planetModel, leftLon, rightLon);
+ }
+ //System.err.println(" not longitude slice");
+ if (Math.abs(leftLon - rightLon) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION)
+ return new GeoDegeneratePoint(planetModel, topLat, leftLon);
+ return new GeoDegenerateVerticalLine(planetModel, topLat, bottomLat, leftLon);
+ }
+ //System.err.println(" not vertical line");
+ if (extent >= Math.PI) {
+ if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION) {
+ //System.err.println(" wide degenerate line");
+ return new GeoWideDegenerateHorizontalLine(planetModel, topLat, leftLon, rightLon);
+ }
+ if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
+ return new GeoWideNorthRectangle(planetModel, bottomLat, leftLon, rightLon);
+ } else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
+ return new GeoWideSouthRectangle(planetModel, topLat, leftLon, rightLon);
+ }
+ //System.err.println(" wide rect");
+ return new GeoWideRectangle(planetModel, topLat, bottomLat, leftLon, rightLon);
+ }
+ if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION) {
+ if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION || Math.abs(topLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
+ return new GeoDegeneratePoint(planetModel, topLat, 0.0);
+ }
+ //System.err.println(" horizontal line");
+ return new GeoDegenerateHorizontalLine(planetModel, topLat, leftLon, rightLon);
+ }
+ if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
+ return new GeoNorthRectangle(planetModel, bottomLat, leftLon, rightLon);
+ } else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
+ return new GeoSouthRectangle(planetModel, topLat, leftLon, rightLon);
+ }
+ //System.err.println(" rectangle");
+ return new GeoRectangle(planetModel, topLat, bottomLat, leftLon, rightLon);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
new file mode 100644
index 0000000..7190cdc
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseBBox.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * All bounding box shapes can derive from this base class, which furnishes
+ * some common code
+ *
+ * @lucene.internal
+ */
+public abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
+
+ /** Construct, given planet model.
+ *@param planetModel is the planet model.
+ */
+ public GeoBaseBBox(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+ // Signals for relationship of edge points to shape
+
+ /** All edgepoints inside shape */
+ protected final static int ALL_INSIDE = 0;
+ /** Some edgepoints inside shape */
+ protected final static int SOME_INSIDE = 1;
+ /** No edgepoints inside shape */
+ protected final static int NONE_INSIDE = 2;
+
+ /** Determine the relationship between this BBox and the provided
+ * shape's edgepoints.
+ *@param path is the shape.
+ *@return the relationship.
+ */
+ protected int isShapeInsideBBox(final GeoShape path) {
+ final GeoPoint[] pathPoints = path.getEdgePoints();
+ boolean foundOutside = false;
+ boolean foundInside = false;
+ for (GeoPoint p : pathPoints) {
+ if (isWithin(p)) {
+ foundInside = true;
+ } else {
+ foundOutside = true;
+ }
+ if (foundInside && foundOutside) {
+ return SOME_INSIDE;
+ }
+ }
+ if (!foundInside && !foundOutside)
+ return NONE_INSIDE;
+ if (foundInside && !foundOutside)
+ return ALL_INSIDE;
+ if (foundOutside && !foundInside)
+ return NONE_INSIDE;
+ return SOME_INSIDE;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCircle.java
new file mode 100644
index 0000000..75219fd
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCircle.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * GeoCircles have all the characteristics of GeoBaseDistanceShapes, plus GeoSizeable.
+ *
+ * @lucene.experimental
+ */
+public abstract class GeoBaseCircle extends GeoBaseDistanceShape implements GeoCircle {
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ */
+ public GeoBaseCircle(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
new file mode 100644
index 0000000..39dcf96
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Distance shapes have capabilities of both geohashing and distance
+ * computation (which also includes point membership determination).
+ *
+ * @lucene.experimental
+ */
+public abstract class GeoBaseDistanceShape extends GeoBaseMembershipShape implements GeoDistanceShape {
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ */
+ public GeoBaseDistanceShape(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+ @Override
+ public boolean isWithin(Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
+
+ @Override
+ public double computeDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+ return computeDistance(distanceStyle, point.x, point.y, point.z);
+ }
+
+ @Override
+ public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (!isWithin(x,y,z)) {
+ return Double.MAX_VALUE;
+ }
+ return distance(distanceStyle, x, y, z);
+ }
+
+ /** Called by a {@code computeDistance} method if X/Y/Z is not within this shape. */
+ protected abstract double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseMembershipShape.java
new file mode 100644
index 0000000..831a7c6
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseMembershipShape.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Membership shapes have capabilities of both geohashing and membership
+ * determination. This is a useful baseclass for them.
+ *
+ * @lucene.experimental
+ */
+public abstract class GeoBaseMembershipShape extends GeoBaseShape implements GeoMembershipShape {
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ */
+ public GeoBaseMembershipShape(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+ @Override
+ public boolean isWithin(Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
+
+ @Override
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+ return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
+ }
+
+ @Override
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (isWithin(x,y,z)) {
+ return 0.0;
+ }
+ return outsideDistance(distanceStyle, x,y,z);
+ }
+
+ /** Called by a {@code computeOutsideDistance} method if X/Y/Z is not within this shape. */
+ protected abstract double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
new file mode 100644
index 0000000..ba221ae
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBasePolygon.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * GeoBasePolygon objects are the base class of most GeoPolygon objects.
+ *
+ * @lucene.experimental
+ */
+public abstract class GeoBasePolygon extends GeoBaseMembershipShape implements GeoPolygon {
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ */
+ public GeoBasePolygon(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseShape.java
new file mode 100644
index 0000000..54896fc
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseShape.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Base extended shape object.
+ *
+ * @lucene.internal
+ */
+public abstract class GeoBaseShape extends BasePlanetObject implements GeoShape {
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ */
+ public GeoBaseShape(final PlanetModel planetModel) {
+ super(planetModel);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ if (isWithin(planetModel.NORTH_POLE)) {
+ bounds.noTopLatitudeBound().noLongitudeBound()
+ .addPoint(planetModel.NORTH_POLE);
+ }
+ if (isWithin(planetModel.SOUTH_POLE)) {
+ bounds.noBottomLatitudeBound().noLongitudeBound()
+ .addPoint(planetModel.SOUTH_POLE);
+ }
+ if (isWithin(planetModel.MIN_X_POLE)) {
+ bounds.addPoint(planetModel.MIN_X_POLE);
+ }
+ if (isWithin(planetModel.MAX_X_POLE)) {
+ bounds.addPoint(planetModel.MAX_X_POLE);
+ }
+ if (isWithin(planetModel.MIN_Y_POLE)) {
+ bounds.addPoint(planetModel.MIN_Y_POLE);
+ }
+ if (isWithin(planetModel.MAX_Y_POLE)) {
+ bounds.addPoint(planetModel.MAX_Y_POLE);
+ }
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircle.java
new file mode 100755
index 0000000..b05dff6
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircle.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Interface describing circular area with a center and radius.
+ *
+ * @lucene.experimental
+ */
+public interface GeoCircle extends GeoDistanceShape, GeoSizeable {
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircleFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircleFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircleFactory.java
new file mode 100644
index 0000000..ee75179
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCircleFactory.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Class which constructs a GeoCircle representing an arbitrary circle.
+ *
+ * @lucene.experimental
+ */
+public class GeoCircleFactory {
+ private GeoCircleFactory() {
+ }
+
+ /**
+ * Create a GeoCircle of the right kind given the specified bounds.
+ * @param planetModel is the planet model.
+ * @param latitude is the center latitude.
+ * @param longitude is the center longitude.
+ * @param radius is the radius 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_RESOLUTION) {
+ return new GeoDegeneratePoint(planetModel, latitude, longitude);
+ }
+ return new GeoStandardCircle(planetModel, latitude, longitude, radius);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
new file mode 100755
index 0000000..9747eda
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositeMembershipShape.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * GeoComposite is a set of GeoMembershipShape's, treated as a unit.
+ *
+ * @lucene.experimental
+ */
+public class GeoCompositeMembershipShape implements GeoMembershipShape {
+ /** The list of shapes. */
+ protected final List<GeoMembershipShape> shapes = new ArrayList<GeoMembershipShape>();
+
+ /** Constructor.
+ */
+ public GeoCompositeMembershipShape() {
+ }
+
+ /**
+ * Add a shape to the composite.
+ *@param shape is the shape to add.
+ */
+ public void addShape(final GeoMembershipShape shape) {
+ shapes.add(shape);
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (GeoMembershipShape shape : shapes) {
+ if (shape.isWithin(x, y, z))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return shapes.get(0).getEdgePoints();
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ for (GeoMembershipShape shape : shapes) {
+ if (shape.intersects(p, notablePoints, bounds))
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ for (GeoMembershipShape shape : shapes) {
+ shape.getBounds(bounds);
+ }
+ }
+
+ @Override
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+ return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
+ }
+
+ @Override
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (isWithin(x,y,z))
+ return 0.0;
+ double distance = Double.MAX_VALUE;
+ for (GeoMembershipShape shape : shapes) {
+ final double normalDistance = shape.computeOutsideDistance(distanceStyle, x, y, z);
+ if (normalDistance < distance) {
+ distance = normalDistance;
+ }
+ }
+ return distance;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoCompositeMembershipShape))
+ return false;
+ GeoCompositeMembershipShape other = (GeoCompositeMembershipShape) o;
+
+ return super.equals(o) && shapes.equals(other.shapes);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() * 31 + shapes.hashCode();//TODO cache
+ }
+
+ @Override
+ public String toString() {
+ return "GeoCompositeMembershipShape: {" + shapes + '}';
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
new file mode 100644
index 0000000..920d3fb
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoCompositePolygon.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * GeoCompositePolygon is a specific implementation of GeoMembershipShape, which implements GeoPolygon explicitly.
+ *
+ * @lucene.experimental
+ */
+public class GeoCompositePolygon extends GeoCompositeMembershipShape implements GeoPolygon {
+ /** Constructor.
+ */
+ public GeoCompositePolygon() {
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
new file mode 100755
index 0000000..fb024b6
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java
@@ -0,0 +1,288 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * GeoConvexPolygon objects are generic building blocks of more complex structures.
+ * The only restrictions on these objects are: (1) they must be convex; (2) they must have
+ * a maximum extent no larger than PI. Violating either one of these limits will
+ * cause the logic to fail.
+ *
+ * @lucene.experimental
+ */
+public class GeoConvexPolygon extends GeoBasePolygon {
+ /** The list of polygon points */
+ protected final List<GeoPoint> points;
+ /** A bitset describing, for each edge, whether it is internal or not */
+ protected final BitSet isInternalEdges;
+
+ /** A list of edges */
+ protected SidedPlane[] edges = null;
+ /** The set of notable points for each edge */
+ protected GeoPoint[][] notableEdgePoints = null;
+ /** A point which is on the boundary of the polygon */
+ protected GeoPoint[] edgePoints = null;
+ /** Tracking the maximum distance we go at any one time, so to be sure it's legal */
+ protected double fullDistance = 0.0;
+ /** Set to true when the polygon is complete */
+ protected boolean isDone = false;
+
+ /**
+ * Create a convex polygon from a list of points. The first point must be on the
+ * external edge.
+ *@param planetModel is the planet model.
+ *@param pointList is the list of points to create the polygon from.
+ */
+ public GeoConvexPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList) {
+ super(planetModel);
+ this.points = pointList;
+ this.isInternalEdges = new BitSet();
+ done(false);
+ }
+
+ /**
+ * Create a convex polygon from a list of points, keeping track of which boundaries
+ * are internal. This is used when creating a polygon as a building block for another shape.
+ *@param planetModel is the planet model.
+ *@param pointList is the set of points to create the polygon from.
+ *@param internalEdgeFlags is a bitset describing whether each edge is internal or not.
+ *@param returnEdgeInternal is true when the final return edge is an internal one.
+ */
+ public GeoConvexPolygon(final PlanetModel planetModel, final List<GeoPoint> pointList, final BitSet internalEdgeFlags,
+ final boolean returnEdgeInternal) {
+ super(planetModel);
+ this.points = pointList;
+ this.isInternalEdges = internalEdgeFlags;
+ done(returnEdgeInternal);
+ }
+
+ /**
+ * Create a convex polygon, with a starting latitude and longitude.
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *@param planetModel is the planet model.
+ *@param startLatitude is the latitude of the first point.
+ *@param startLongitude is the longitude of the first point.
+ */
+ public GeoConvexPolygon(final PlanetModel planetModel, final double startLatitude, final double startLongitude) {
+ super(planetModel);
+ points = new ArrayList<>();
+ isInternalEdges = new BitSet();
+ points.add(new GeoPoint(planetModel, startLatitude, startLongitude));
+ }
+
+ /**
+ * Add a point to the polygon.
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *
+ * @param latitude is the latitude of the next point.
+ * @param longitude is the longitude of the next point.
+ * @param isInternalEdge is true if the edge just added with this point should be considered "internal", and not
+ * intersected as part of the intersects() operation.
+ */
+ public void addPoint(final double latitude, final double longitude, final boolean isInternalEdge) {
+ if (isDone)
+ throw new IllegalStateException("Can't call addPoint() if done() already called");
+ if (isInternalEdge)
+ isInternalEdges.set(points.size() - 1);
+ points.add(new GeoPoint(planetModel, latitude, longitude));
+ }
+
+ /**
+ * Finish the polygon, by connecting the last added point with the starting point.
+ *@param isInternalReturnEdge is true if the return edge (back to start) is an internal one.
+ */
+ public void done(final boolean isInternalReturnEdge) {
+ if (isDone)
+ throw new IllegalStateException("Can't call done() more than once");
+ // If fewer than 3 points, can't do it.
+ if (points.size() < 3)
+ throw new IllegalArgumentException("Polygon needs at least three points.");
+
+ if (isInternalReturnEdge)
+ isInternalEdges.set(points.size() - 1);
+
+ isDone = true;
+
+ // Time to construct the planes. If the polygon is truly convex, then any adjacent point
+ // to a segment can provide an interior measurement.
+ edges = new SidedPlane[points.size()];
+ notableEdgePoints = new GeoPoint[points.size()][];
+
+ for (int i = 0; i < points.size(); i++) {
+ final GeoPoint start = points.get(i);
+ final GeoPoint end = points.get(legalIndex(i + 1));
+ final double distance = start.arcDistance(end);
+ if (distance > fullDistance)
+ fullDistance = distance;
+ final GeoPoint check = points.get(legalIndex(i + 2));
+ final SidedPlane sp = new SidedPlane(check, start, end);
+ //System.out.println("Created edge "+sp+" using start="+start+" end="+end+" check="+check);
+ edges[i] = sp;
+ notableEdgePoints[i] = new GeoPoint[]{start, end};
+ }
+ createCenterPoint();
+ }
+
+ /** Compute a reasonable center point.
+ */
+ protected void createCenterPoint() {
+ // In order to naively confirm that the polygon is convex, I would need to
+ // check every edge, and verify that every point (other than the edge endpoints)
+ // is within the edge's sided plane. This is an order n^2 operation. That's still
+ // not wrong, though, because everything else about polygons has a similar cost.
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) {
+ if (pointIndex != edgeIndex && pointIndex != legalIndex(edgeIndex + 1)) {
+ if (!edge.isWithin(points.get(pointIndex)))
+ throw new IllegalArgumentException("Polygon is not convex: Point " + points.get(pointIndex) + " Edge " + edge);
+ }
+ }
+ }
+ edgePoints = new GeoPoint[]{points.get(0)};
+ }
+
+ /** Compute a legal point index from a possibly illegal one, that may have wrapped.
+ *@param index is the index.
+ *@return the normalized index.
+ */
+ protected int legalIndex(int index) {
+ while (index >= points.size())
+ index -= points.size();
+ return index;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ for (final SidedPlane edge : edges) {
+ if (!edge.isWithin(x, y, z))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ //System.err.println("Checking for polygon intersection with plane "+p+"...");
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ final GeoPoint[] points = this.notableEdgePoints[edgeIndex];
+ if (!isInternalEdges.get(edgeIndex)) {
+ //System.err.println(" non-internal edge "+edge);
+ // Edges flagged as 'internal only' are excluded from the matching
+ // Construct boundaries
+ final Membership[] membershipBounds = new Membership[edges.length - 1];
+ int count = 0;
+ for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
+ if (otherIndex != edgeIndex) {
+ membershipBounds[count++] = edges[otherIndex];
+ }
+ }
+ if (edge.intersects(planetModel, p, notablePoints, points, bounds, membershipBounds)) {
+ //System.err.println(" intersects!");
+ return true;
+ }
+ }
+ }
+ //System.err.println(" no intersection");
+ return false;
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+
+ // Add all the points
+ for (final GeoPoint point : points) {
+ bounds.addPoint(point);
+ }
+
+ // Add planes with membership.
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final SidedPlane edge = edges[edgeIndex];
+ // Construct boundaries
+ final Membership[] membershipBounds = new Membership[edges.length - 1];
+ int count = 0;
+ for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
+ if (otherIndex != edgeIndex) {
+ membershipBounds[count++] = edges[otherIndex];
+ }
+ }
+ bounds.addPlane(planetModel, edge, membershipBounds);
+ }
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ double minimumDistance = Double.MAX_VALUE;
+ for (final GeoPoint edgePoint : points) {
+ final double newDist = distanceStyle.computeDistance(edgePoint, x,y,z);
+ if (newDist < minimumDistance) {
+ minimumDistance = newDist;
+ }
+ }
+ for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
+ final Plane edgePlane = edges[edgeIndex];
+ final Membership[] membershipBounds = new Membership[edges.length - 1];
+ int count = 0;
+ for (int otherIndex = 0; otherIndex < edges.length; otherIndex++) {
+ if (otherIndex != edgeIndex) {
+ membershipBounds[count++] = edges[otherIndex];
+ }
+ }
+ final double newDist = distanceStyle.computeDistance(planetModel, edgePlane, x, y, z, membershipBounds);
+ if (newDist < minimumDistance) {
+ minimumDistance = newDist;
+ }
+ }
+ return minimumDistance;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoConvexPolygon))
+ return false;
+ GeoConvexPolygon other = (GeoConvexPolygon) o;
+ if (!super.equals(other))
+ return false;
+ if (!other.isInternalEdges.equals(isInternalEdges))
+ return false;
+ return (other.points.equals(points));
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + points.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoConvexPolygon: {planetmodel=" + planetModel + ", points=" + points + "}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
new file mode 100644
index 0000000..b7de0c2
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateHorizontalLine.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Degenerate bounding box limited on two sides (left lon, right lon).
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * GeoWideDegenerateHorizontalLine.
+ *
+ * @lucene.internal
+ */
+public class GeoDegenerateHorizontalLine extends GeoBaseBBox {
+ /** Latitude of horizontal line */
+ protected final double latitude;
+ /** Left bounding longitude of line */
+ protected final double leftLon;
+ /** Right bounding longitude of line */
+ protected final double rightLon;
+
+ /** Left hand endpoint of line */
+ protected final GeoPoint LHC;
+ /** Right hand endpoint of line */
+ protected final GeoPoint RHC;
+
+ /** The plane describing the line */
+ protected final Plane plane;
+ /** The left side end plane */
+ protected final SidedPlane leftPlane;
+ /** The right side end plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for the line */
+ protected final GeoPoint[] planePoints;
+
+ /** Center of line */
+ protected final GeoPoint centerPoint;
+ /** A point that's on the line */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *@param planetModel is the planet model.
+ *@param latitude is the latitude of the line.
+ *@param leftLon is the left end longitude.
+ *@param rightLon is the right end longitude.
+ */
+ public GeoDegenerateHorizontalLine(final PlanetModel planetModel, final double latitude, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent > Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too great");
+
+ this.latitude = latitude;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinLatitude = Math.sin(latitude);
+ final double cosLatitude = Math.cos(latitude);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the two points
+ this.LHC = new GeoPoint(planetModel, sinLatitude, sinLeftLon, cosLatitude, cosLeftLon, latitude, leftLon);
+ this.RHC = new GeoPoint(planetModel, sinLatitude, sinRightLon, cosLatitude, cosRightLon, latitude, rightLon);
+
+ this.plane = new Plane(planetModel, sinLatitude);
+
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.planePoints = new GeoPoint[]{LHC, RHC};
+
+ this.edgePoints = new GeoPoint[]{centerPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ double newTopLat = latitude + angle;
+ double newBottomLat = latitude - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(x, y, z) &&
+ leftPlane.isWithin(x, y, z) &&
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ double topAngle = centerPoint.arcDistance(RHC);
+ double bottomAngle = centerPoint.arcDistance(LHC);
+ return Math.max(topAngle, bottomAngle);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, leftPlane, rightPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.addHorizontalPlane(planetModel, latitude, plane, leftPlane, rightPlane)
+ .addPoint(LHC).addPoint(RHC);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println("getting relationship between "+this+" and "+path);
+ if (path.intersects(plane, planePoints, leftPlane, rightPlane)) {
+ //System.err.println(" overlaps");
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(centerPoint)) {
+ //System.err.println(" contains");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, leftPlane, rightPlane);
+
+ final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
+ final double RHCDistance = distanceStyle.computeDistance(RHC, x,y,z);
+
+ return Math.min(
+ distance,
+ Math.min(LHCDistance, RHCDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateHorizontalLine))
+ return false;
+ GeoDegenerateHorizontalLine other = (GeoDegenerateHorizontalLine) o;
+ return super.equals(other) && other.LHC.equals(LHC) && other.RHC.equals(RHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + LHC.hashCode();
+ result = 31 * result + RHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateHorizontalLine: {planetmodel="+planetModel+", latitude=" + latitude + "(" + latitude * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightLon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
new file mode 100644
index 0000000..e794123
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLatitudeZone.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * This GeoBBox represents an area rectangle of one specific latitude with
+ * no longitude bounds.
+ *
+ * @lucene.internal
+ */
+public class GeoDegenerateLatitudeZone extends GeoBaseBBox {
+ /** The latitude */
+ protected final double latitude;
+ /** Sine of the latitude */
+ protected final double sinLatitude;
+ /** Plane describing the latitude zone */
+ protected final Plane plane;
+ /** A point on the world that's also on the zone */
+ protected final GeoPoint interiorPoint;
+ /** An array consisting of the interiorPoint */
+ protected final GeoPoint[] edgePoints;
+ /** No notable points */
+ protected final static GeoPoint[] planePoints = new GeoPoint[0];
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ *@param latitude is the latitude of the latitude zone.
+ */
+ public GeoDegenerateLatitudeZone(final PlanetModel planetModel, final double latitude) {
+ super(planetModel);
+ this.latitude = latitude;
+
+ this.sinLatitude = Math.sin(latitude);
+ double cosLatitude = Math.cos(latitude);
+ this.plane = new Plane(planetModel, sinLatitude);
+ // Compute an interior point.
+ interiorPoint = new GeoPoint(planetModel, sinLatitude, 0.0, cosLatitude, 1.0);
+ edgePoints = new GeoPoint[]{interiorPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ double newTopLat = latitude + angle;
+ double newBottomLat = latitude - angle;
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return Math.abs(z - this.sinLatitude) < 1e-10;
+ }
+
+ @Override
+ public double getRadius() {
+ return Math.PI;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ // Totally arbitrary
+ return interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, plane, notablePoints, planePoints, bounds);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.noLongitudeBound()
+ .addHorizontalPlane(planetModel, latitude, plane);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ // Second, the shortcut of seeing whether endpoints are in/out is not going to
+ // work with no area endpoints. So we rely entirely on intersections.
+ //System.out.println("Got here! latitude="+latitude+" path="+path);
+
+ if (path.intersects(plane, planePoints)) {
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(interiorPoint)) {
+ return CONTAINS;
+ }
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(planetModel, plane, x,y,z);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateLatitudeZone))
+ return false;
+ GeoDegenerateLatitudeZone other = (GeoDegenerateLatitudeZone) o;
+ return super.equals(other) && other.latitude == latitude;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp = Double.doubleToLongBits(latitude);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateLatitudeZone: {planetmodel="+planetModel+", lat=" + latitude + "(" + latitude * 180.0 / Math.PI + ")}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
new file mode 100644
index 0000000..0bb7b90
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateLongitudeSlice.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Degenerate longitude slice.
+ *
+ * @lucene.internal
+ */
+public class GeoDegenerateLongitudeSlice extends GeoBaseBBox {
+ /** The longitude of the slice */
+ protected final double longitude;
+
+ /** The bounding plane for the slice (through both poles, perpendicular to the slice) */
+ protected final SidedPlane boundingPlane;
+ /** The plane of the slice */
+ protected final Plane plane;
+ /** A point on the slice */
+ protected final GeoPoint interiorPoint;
+ /** An array consisting of the one point chosen on the slice */
+ protected final GeoPoint[] edgePoints;
+ /** Notable points for the slice (north and south poles) */
+ protected final GeoPoint[] planePoints;
+
+ /**
+ * Accepts only values in the following ranges: lon: {@code -PI -> PI}
+ */
+ public GeoDegenerateLongitudeSlice(final PlanetModel planetModel, final double longitude) {
+ super(planetModel);
+ // Argument checking
+ if (longitude < -Math.PI || longitude > Math.PI)
+ throw new IllegalArgumentException("Longitude out of range");
+ this.longitude = longitude;
+
+ final double sinLongitude = Math.sin(longitude);
+ final double cosLongitude = Math.cos(longitude);
+
+ this.plane = new Plane(cosLongitude, sinLongitude);
+ // We need a bounding plane too, which is perpendicular to the longitude plane and sided so that the point (0.0, longitude) is inside.
+ this.interiorPoint = new GeoPoint(planetModel, 0.0, sinLongitude, 1.0, cosLongitude);
+ this.boundingPlane = new SidedPlane(interiorPoint, -sinLongitude, cosLongitude);
+ this.edgePoints = new GeoPoint[]{interiorPoint};
+ this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double newLeftLon = longitude - angle;
+ double newRightLon = longitude + angle;
+ double currentLonSpan = 2.0 * angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(x, y, z) &&
+ boundingPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ return Math.PI * 0.5;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, boundingPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds
+ .addVerticalPlane(planetModel, longitude, plane, boundingPlane)
+ .addPoint(planetModel.NORTH_POLE).addPoint(planetModel.SOUTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ // Look for intersections.
+ if (path.intersects(plane, planePoints, boundingPlane))
+ return OVERLAPS;
+
+ if (path.isWithin(interiorPoint))
+ return CONTAINS;
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, boundingPlane);
+
+ final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
+ final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
+
+ return Math.min(
+ distance,
+ Math.min(northDistance, southDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateLongitudeSlice))
+ return false;
+ GeoDegenerateLongitudeSlice other = (GeoDegenerateLongitudeSlice) o;
+ return super.equals(other) && other.longitude == longitude;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp = Double.doubleToLongBits(longitude);
+ result = result * 31 + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateLongitudeSlice: {planetmodel="+planetModel+", longitude=" + longitude + "(" + longitude * 180.0 / Math.PI + ")}";
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
new file mode 100644
index 0000000..fcd2037
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * This class represents a degenerate point bounding box.
+ * It is not a simple GeoPoint because we must have the latitude and longitude.
+ *
+ * @lucene.internal
+ */
+public class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
+ /** Current planet model, since we don't extend BasePlanetObject */
+ protected final PlanetModel planetModel;
+ /** Edge point is an area containing just this */
+ protected final GeoPoint[] edgePoints;
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ *@param lat is the latitude.
+ *@param lon is the longitude.
+ */
+ public GeoDegeneratePoint(final PlanetModel planetModel, final double lat, final double lon) {
+ super(planetModel, lat, lon);
+ this.planetModel = planetModel;
+ this.edgePoints = new GeoPoint[]{this};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = latitude + angle;
+ final double newBottomLat = latitude - angle;
+ final double newLeftLon = longitude - angle;
+ final double newRightLon = longitude + angle;
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // If not on the plane, no intersection
+ if (!plane.evaluateIsZero(this))
+ return false;
+
+ for (Membership m : bounds) {
+ if (!m.isWithin(this))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ bounds.addPoint(this);
+ }
+
+ @Override
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+ return distanceStyle.computeDistance(this, point);
+ }
+
+ @Override
+ public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(this, x,y,z);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegeneratePoint))
+ return false;
+ GeoDegeneratePoint other = (GeoDegeneratePoint) o;
+ return super.equals(other) && other.latitude == latitude && other.longitude == longitude;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegeneratePoint: {planetmodel="+planetModel+", lat=" + latitude + "(" + latitude * 180.0 / Math.PI + "), lon=" + longitude + "(" + longitude * 180.0 / Math.PI + ")}";
+ }
+
+ @Override
+ public boolean isWithin(final Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return x == this.x && y == this.y && z == this.z;
+ }
+
+ @Override
+ public double getRadius() {
+ return 0.0;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return this;
+ }
+
+ @Override
+ public int getRelationship(final GeoShape shape) {
+ if (shape.isWithin(this)) {
+ //System.err.println("Degenerate point "+this+" is WITHIN shape "+shape);
+ return CONTAINS;
+ }
+
+ //System.err.println("Degenerate point "+this+" is NOT within shape "+shape);
+ return DISJOINT;
+ }
+
+ @Override
+ public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ if (isWithin(x,y,z))
+ return 0.0;
+ return Double.MAX_VALUE;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
new file mode 100644
index 0000000..dff53b4
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegenerateVerticalLine.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Degenerate bounding box limited on two sides (top lat, bottom lat).
+ *
+ * @lucene.internal
+ */
+public class GeoDegenerateVerticalLine extends GeoBaseBBox {
+ /** Top latitude of the vertical line */
+ protected final double topLat;
+ /** Bottom latitude of the vertical line */
+ protected final double bottomLat;
+ /** Longitude of the vertical line */
+ protected final double longitude;
+
+ /** Point at the upper end of the vertical line */
+ protected final GeoPoint UHC;
+ /** Point at the lower end of the vertical line */
+ protected final GeoPoint LHC;
+
+ /** Top end cutoff plane */
+ protected final SidedPlane topPlane;
+ /** Bottom end cutoff plane */
+ protected final SidedPlane bottomPlane;
+ /** Back-side cutoff plane */
+ protected final SidedPlane boundingPlane;
+ /** The vertical line plane */
+ protected final Plane plane;
+ /** Notable points for the line (end points) */
+ protected final GeoPoint[] planePoints;
+ /** A computed center point for the line */
+ protected final GeoPoint centerPoint;
+ /** A point that's on the line */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, longitude: {@code -PI -> PI}
+ */
+ public GeoDegenerateVerticalLine(final PlanetModel planetModel, final double topLat, final double bottomLat, final double longitude) {
+ super(planetModel);
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top latitude out of range");
+ if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (topLat < bottomLat)
+ throw new IllegalArgumentException("Top latitude less than bottom latitude");
+ if (longitude < -Math.PI || longitude > Math.PI)
+ throw new IllegalArgumentException("Longitude out of range");
+
+ this.topLat = topLat;
+ this.bottomLat = bottomLat;
+ this.longitude = longitude;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ final double sinBottomLat = Math.sin(bottomLat);
+ final double cosBottomLat = Math.cos(bottomLat);
+ final double sinLongitude = Math.sin(longitude);
+ final double cosLongitude = Math.cos(longitude);
+
+ // Now build the two points
+ this.UHC = new GeoPoint(planetModel, sinTopLat, sinLongitude, cosTopLat, cosLongitude, topLat, longitude);
+ this.LHC = new GeoPoint(planetModel, sinBottomLat, sinLongitude, cosBottomLat, cosLongitude, bottomLat, longitude);
+
+ this.plane = new Plane(cosLongitude, sinLongitude);
+
+ final double middleLat = (topLat + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ final double cosMiddleLat = Math.cos(middleLat);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinLongitude, cosMiddleLat, cosLongitude);
+
+ this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+ this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
+
+ this.boundingPlane = new SidedPlane(centerPoint, -sinLongitude, cosLongitude);
+
+ this.planePoints = new GeoPoint[]{UHC, LHC};
+
+ this.edgePoints = new GeoPoint[]{centerPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = bottomLat - angle;
+ double newLeftLon = longitude - angle;
+ double newRightLon = longitude + angle;
+ double currentLonSpan = 2.0 * angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(x, y, z) &&
+ boundingPlane.isWithin(x, y, z) &&
+ topPlane.isWithin(x, y, z) &&
+ bottomPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double topAngle = centerPoint.arcDistance(UHC);
+ final double bottomAngle = centerPoint.arcDistance(LHC);
+ return Math.max(topAngle, bottomAngle);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, boundingPlane, topPlane, bottomPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.addVerticalPlane(planetModel, longitude, plane, boundingPlane, topPlane, bottomPlane)
+ .addPoint(UHC).addPoint(LHC);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" relationship to "+path);
+ if (path.intersects(plane, planePoints, boundingPlane, topPlane, bottomPlane)) {
+ //System.err.println(" overlaps");
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(centerPoint)) {
+ //System.err.println(" contains");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, topPlane, bottomPlane, boundingPlane);
+
+ final double UHCDistance = distanceStyle.computeDistance(UHC, x,y,z);
+ final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
+
+ return Math.min(
+ distance,
+ Math.min(UHCDistance, LHCDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoDegenerateVerticalLine))
+ return false;
+ GeoDegenerateVerticalLine other = (GeoDegenerateVerticalLine) o;
+ return super.equals(other) && other.UHC.equals(UHC) && other.LHC.equals(LHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + UHC.hashCode();
+ result = 31 * result + LHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoDegenerateVerticalLine: {longitude=" + longitude + "(" + longitude * 180.0 / Math.PI + "), toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
new file mode 100755
index 0000000..d41dd51
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * An implementer of this interface is capable of computing the described "distance" values,
+ * which are meant to provide both actual distance values, as well as
+ * distance estimates that can be computed more cheaply.
+ *
+ * @lucene.experimental
+ */
+public interface GeoDistance extends Membership {
+
+ // The following methods compute distances from the shape to a point
+ // expected to be INSIDE the shape. Typically a value of Double.MAX_VALUE
+ // is returned for points that happen to be outside the shape.
+
+ /**
+ * Compute this shape's <em>internal</em> "distance" to the GeoPoint.
+ * Implementations should clarify how this is computed when it's non-obvious.
+ * A return value of Double.MAX_VALUE should be returned for
+ * points outside of the shape.
+ *
+ * @param distanceStyle is the distance style.
+ * @param point is the point to compute the distance to.
+ * @return the distance.
+ */
+ public default double computeDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
+ return computeDistance(distanceStyle, point.x, point.y, point.z);
+ }
+
+ /**
+ * Compute this shape's <em>internal</em> "distance" to the GeoPoint.
+ * Implementations should clarify how this is computed when it's non-obvious.
+ * A return value of Double.MAX_VALUE should be returned for
+ * points outside of the shape.
+ *
+ * @param x is the point's unit x coordinate (using U.S. convention).
+ * @param y is the point's unit y coordinate (using U.S. convention).
+ * @param z is the point's unit z coordinate (using U.S. convention).
+ * @return the distance.
+ */
+ public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
new file mode 100755
index 0000000..e7b0348
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Distance shapes have capabilities of both geohashing and distance
+ * computation (which also includes point membership determination).
+ *
+ * @lucene.experimental
+ */
+public interface GeoDistanceShape extends GeoMembershipShape, GeoDistance {
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
new file mode 100755
index 0000000..912ca32
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoLatitudeZone.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * This GeoBBox represents an area rectangle limited only in latitude.
+ *
+ * @lucene.internal
+ */
+public class GeoLatitudeZone extends GeoBaseBBox {
+ /** The top latitude of the zone */
+ protected final double topLat;
+ /** The bottom latitude of the zone */
+ protected final double bottomLat;
+ /** Cosine of the top lat */
+ protected final double cosTopLat;
+ /** Cosine of the bottom lat */
+ protected final double cosBottomLat;
+ /** The top plane */
+ protected final SidedPlane topPlane;
+ /** The bottom plane */
+ protected final SidedPlane bottomPlane;
+ /** An interior point */
+ protected final GeoPoint interiorPoint;
+ /** Notable points (none) */
+ protected final static GeoPoint[] planePoints = new GeoPoint[0];
+
+ // We need two additional points because a latitude zone's boundaries don't intersect. This is a very
+ // special case that most GeoBBox's do not have.
+
+ /** Top boundary point */
+ protected final GeoPoint topBoundaryPoint;
+ /** Bottom boundary point */
+ protected final GeoPoint bottomBoundaryPoint;
+ /** A point on each distinct edge */
+ protected final GeoPoint[] edgePoints;
+
+ /** Constructor.
+ *@param planetModel is the planet model to use.
+ *@param topLat is the top latitude.
+ *@param bottomLat is the bottom latitude.
+ */
+ public GeoLatitudeZone(final PlanetModel planetModel, final double topLat, final double bottomLat) {
+ super(planetModel);
+ this.topLat = topLat;
+ this.bottomLat = bottomLat;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double sinBottomLat = Math.sin(bottomLat);
+ this.cosTopLat = Math.cos(topLat);
+ this.cosBottomLat = Math.cos(bottomLat);
+
+ // Compute an interior point. Pick one whose lat is between top and bottom.
+ final double middleLat = (topLat + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
+ this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0);
+ this.bottomBoundaryPoint = new GeoPoint(planetModel, sinBottomLat, 0.0, Math.sqrt(1.0 - sinBottomLat * sinBottomLat), 1.0);
+
+ this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat);
+ this.bottomPlane = new SidedPlane(interiorPoint, planetModel, sinBottomLat);
+
+ this.edgePoints = new GeoPoint[]{topBoundaryPoint, bottomBoundaryPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = bottomLat - angle;
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z) &&
+ bottomPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
+ // would contain all the bounding box points, when starting in the "center".
+ if (topLat > 0.0 && bottomLat < 0.0)
+ return Math.PI;
+ double maxCosLat = cosTopLat;
+ if (maxCosLat < cosBottomLat)
+ maxCosLat = cosBottomLat;
+ return maxCosLat * Math.PI;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ // This is totally arbitrary and only a cartesian could agree with it.
+ return interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, topPlane, notablePoints, planePoints, bounds, bottomPlane) ||
+ p.intersects(planetModel, bottomPlane, notablePoints, planePoints, bounds, topPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.noLongitudeBound()
+ .addHorizontalPlane(planetModel, topLat, topPlane)
+ .addHorizontalPlane(planetModel, bottomLat, bottomPlane);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean topBoundaryInsideShape = path.isWithin(topBoundaryPoint);
+ final boolean bottomBoundaryInsideShape = path.isWithin(bottomBoundaryPoint);
+
+ if (topBoundaryInsideShape && !bottomBoundaryInsideShape ||
+ !topBoundaryInsideShape && bottomBoundaryInsideShape)
+ return OVERLAPS;
+
+ final boolean insideShape = topBoundaryInsideShape && bottomBoundaryInsideShape;
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ // Second, the shortcut of seeing whether endpoints are in/out is not going to
+ // work with no area endpoints. So we rely entirely on intersections.
+
+ if (path.intersects(topPlane, planePoints, bottomPlane) ||
+ path.intersects(bottomPlane, planePoints, topPlane))
+ return OVERLAPS;
+
+ // There is another case for latitude zones only. This is when the boundaries of the shape all fit
+ // within the zone, but the shape includes areas outside the zone crossing a pole.
+ // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
+ // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
+ // one such point is within, then OVERLAPS is the right answer.
+
+ if (insideShape)
+ return CONTAINS;
+
+ if (insideRectangle == ALL_INSIDE)
+ return WITHIN;
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane);
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane);
+
+ return Math.min(topDistance, bottomDistance);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoLatitudeZone))
+ return false;
+ GeoLatitudeZone other = (GeoLatitudeZone) o;
+ return super.equals(other) && other.topBoundaryPoint.equals(topBoundaryPoint) && other.bottomBoundaryPoint.equals(bottomBoundaryPoint);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + topBoundaryPoint.hashCode();
+ result = 31 * result + bottomBoundaryPoint.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoLatitudeZone: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + ")}";
+ }
+}
[47/50] [abbrv] lucene-solr git commit: remove troublesome float
tests since facets only actually expose doubles
Posted by no...@apache.org.
remove troublesome float tests since facets only actually expose doubles
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/12f7ad66
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/12f7ad66
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/12f7ad66
Branch: refs/heads/apiv2
Commit: 12f7ad66963a5ae784f2bd0bf8b5dbc4b3c1630e
Parents: a6c8ccb
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 8 17:30:30 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 8 17:30:30 2016 -0500
----------------------------------------------------------------------
.../facet/range/TestRangeFacetCounts.java | 203 -------------------
1 file changed, 203 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/12f7ad66/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
index 9f8b109..626d772 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
@@ -23,11 +23,9 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.lucene.document.DoublePoint;
-import org.apache.lucene.document.FloatPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.DoubleDocValuesField;
-import org.apache.lucene.document.FloatDocValuesField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.facet.DrillDownQuery;
import org.apache.lucene.facet.DrillSideways;
@@ -52,7 +50,6 @@ import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
-import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
@@ -321,37 +318,6 @@ public class TestRangeFacetCounts extends FacetTestCase {
IOUtils.close(r, d);
}
- public void testBasicFloat() throws Exception {
- Directory d = newDirectory();
- RandomIndexWriter w = new RandomIndexWriter(random(), d);
- Document doc = new Document();
- FloatDocValuesField field = new FloatDocValuesField("field", 0.0f);
- doc.add(field);
- for(long l=0;l<100;l++) {
- field.setFloatValue(l);
- w.addDocument(doc);
- }
-
- IndexReader r = w.getReader();
-
- FacetsCollector fc = new FacetsCollector();
-
- IndexSearcher s = newSearcher(r);
- s.search(new MatchAllDocsQuery(), fc);
-
- Facets facets = new DoubleRangeFacetCounts("field", new FloatFieldSource("field"), fc,
- new DoubleRange("less than 10", 0.0f, true, 10.0f, false),
- new DoubleRange("less than or equal to 10", 0.0f, true, 10.0f, true),
- new DoubleRange("over 90", 90.0f, false, 100.0f, false),
- new DoubleRange("90 or above", 90.0f, true, 100.0f, false),
- new DoubleRange("over 1000", 1000.0f, false, Double.POSITIVE_INFINITY, false));
-
- assertEquals("dim=field path=[] value=21 childCount=5\n less than 10 (10)\n less than or equal to 10 (11)\n over 90 (9)\n 90 or above (10)\n over 1000 (0)\n",
- facets.getTopChildren(10, "field").toString());
- w.close();
- IOUtils.close(r, d);
- }
-
public void testRandomLongs() throws Exception {
Directory dir = newDirectory();
RandomIndexWriter w = new RandomIndexWriter(random(), dir);
@@ -499,175 +465,6 @@ public class TestRangeFacetCounts extends FacetTestCase {
IOUtils.close(r, dir);
}
- public void testRandomFloats() throws Exception {
- Directory dir = newDirectory();
- RandomIndexWriter w = new RandomIndexWriter(random(), dir);
-
- int numDocs = atLeast(1000);
- float[] values = new float[numDocs];
- float minValue = Float.POSITIVE_INFINITY;
- float maxValue = Float.NEGATIVE_INFINITY;
- for(int i=0;i<numDocs;i++) {
- Document doc = new Document();
- float v = random().nextFloat();
- values[i] = v;
- doc.add(new FloatDocValuesField("field", v));
- doc.add(new FloatPoint("field", v));
- w.addDocument(doc);
- minValue = Math.min(minValue, v);
- maxValue = Math.max(maxValue, v);
- }
- IndexReader r = w.getReader();
-
- IndexSearcher s = newSearcher(r, false);
- FacetsConfig config = new FacetsConfig();
-
- int numIters = atLeast(10);
- for(int iter=0;iter<numIters;iter++) {
- if (VERBOSE) {
- System.out.println("TEST: iter=" + iter);
- }
- int numRange = TestUtil.nextInt(random(), 1, 5);
- DoubleRange[] ranges = new DoubleRange[numRange];
- int[] expectedCounts = new int[numRange];
- float minAcceptedValue = Float.POSITIVE_INFINITY;
- float maxAcceptedValue = Float.NEGATIVE_INFINITY;
- boolean[] rangeMinIncl = new boolean[numRange];
- boolean[] rangeMaxIncl = new boolean[numRange];
- if (VERBOSE) {
- System.out.println("TEST: " + numRange + " ranges");
- }
- for(int rangeID=0;rangeID<numRange;rangeID++) {
- double min;
- if (rangeID > 0 && random().nextInt(10) == 7) {
- // Use an existing boundary:
- DoubleRange prevRange = ranges[random().nextInt(rangeID)];
- if (random().nextBoolean()) {
- min = prevRange.min;
- } else {
- min = prevRange.max;
- }
- } else {
- min = random().nextDouble();
- }
- double max;
- if (rangeID > 0 && random().nextInt(10) == 7) {
- // Use an existing boundary:
- DoubleRange prevRange = ranges[random().nextInt(rangeID)];
- if (random().nextBoolean()) {
- max = prevRange.min;
- } else {
- max = prevRange.max;
- }
- } else {
- max = random().nextDouble();
- }
-
- if (min > max) {
- double x = min;
- min = max;
- max = x;
- }
-
- // Must truncate to float precision so that the
- // drill-down counts (which use NRQ.newFloatRange)
- // are correct:
- min = (float) min;
- max = (float) max;
-
- boolean minIncl;
- boolean maxIncl;
- if (min == max) {
- minIncl = true;
- maxIncl = true;
- } else {
- minIncl = random().nextBoolean();
- maxIncl = random().nextBoolean();
- }
- rangeMinIncl[rangeID] = minIncl;
- rangeMaxIncl[rangeID] = maxIncl;
- ranges[rangeID] = new DoubleRange("r" + rangeID, min, minIncl, max, maxIncl);
-
- if (VERBOSE) {
- System.out.println("TEST: range " + rangeID + ": " + ranges[rangeID]);
- }
-
- // Do "slow but hopefully correct" computation of
- // expected count:
- for(int i=0;i<numDocs;i++) {
- boolean accept = true;
- if (minIncl) {
- accept &= values[i] >= min;
- } else {
- accept &= values[i] > min;
- }
- if (maxIncl) {
- accept &= values[i] <= max;
- } else {
- accept &= values[i] < max;
- }
- if (VERBOSE) {
- System.out.println("TEST: check doc=" + i + " val=" + values[i] + " accept=" + accept);
- }
- if (accept) {
- expectedCounts[rangeID]++;
- minAcceptedValue = Math.min(minAcceptedValue, values[i]);
- maxAcceptedValue = Math.max(maxAcceptedValue, values[i]);
- }
- }
- }
-
- FacetsCollector sfc = new FacetsCollector();
- s.search(new MatchAllDocsQuery(), sfc);
- Query fastMatchQuery;
- if (random().nextBoolean()) {
- if (random().nextBoolean()) {
- fastMatchQuery = FloatPoint.newRangeQuery("field", minValue, maxValue);
- } else {
- fastMatchQuery = FloatPoint.newRangeQuery("field", minAcceptedValue, maxAcceptedValue);
- }
- } else {
- fastMatchQuery = null;
- }
- ValueSource vs = new FloatFieldSource("field");
- Facets facets = new DoubleRangeFacetCounts("field", vs, sfc, fastMatchQuery, ranges);
- FacetResult result = facets.getTopChildren(10, "field");
- assertEquals(numRange, result.labelValues.length);
- for(int rangeID=0;rangeID<numRange;rangeID++) {
- if (VERBOSE) {
- System.out.println("TEST: verify range " + rangeID + " expectedCount=" + expectedCounts[rangeID]);
- }
- LabelAndValue subNode = result.labelValues[rangeID];
- assertEquals("r" + rangeID, subNode.label);
- assertEquals(expectedCounts[rangeID], subNode.value.intValue());
-
- DoubleRange range = ranges[rangeID];
-
- // Test drill-down:
- DrillDownQuery ddq = new DrillDownQuery(config);
- if (random().nextBoolean()) {
- // We must do the nextUp/down in float space, here, because the nextUp that DoubleRange did in double space, when cast back to float,
- // in fact does nothing!
- float minFloat = (float) range.min;
- if (rangeMinIncl[rangeID] == false) {
- minFloat = Math.nextUp(minFloat);
- }
- float maxFloat = (float) range.max;
- if (rangeMaxIncl[rangeID] == false) {
- maxFloat = Math.nextAfter(maxFloat, Float.NEGATIVE_INFINITY);
- }
- ddq.add("field", FloatPoint.newRangeQuery("field", minFloat, maxFloat));
- } else {
- ddq.add("field", range.getQuery(fastMatchQuery, vs));
- }
- assertEquals(expectedCounts[rangeID], s.search(ddq, 10).totalHits);
- }
- }
-
- w.close();
- IOUtils.close(r, dir);
- }
-
public void testRandomDoubles() throws Exception {
Directory dir = newDirectory();
RandomIndexWriter w = new RandomIndexWriter(random(), dir);
[34/50] [abbrv] lucene-solr git commit: SOLR-8766: Remove support for
admin/gettableFiles as well
Posted by no...@apache.org.
SOLR-8766: Remove support for admin/gettableFiles as well
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/dcb7a882
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/dcb7a882
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/dcb7a882
Branch: refs/heads/apiv2
Commit: dcb7a882b61d679ce220de8f40045ce8b0d8830b
Parents: 4cc9ad4
Author: Varun Thacker <va...@gmail.com>
Authored: Tue Mar 8 19:11:00 2016 +0530
Committer: Varun Thacker <va...@gmail.com>
Committed: Tue Mar 8 19:32:10 2016 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 3 +-
.../src/java/org/apache/solr/core/SolrCore.java | 51 --------------------
2 files changed, 2 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/dcb7a882/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 02021c5..ecf8b32 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -405,7 +405,8 @@ Other Changes
* SOLR-8736: schema GET operations on fields, dynamicFields, fieldTypes, copyField are
reimplemented as a part of the bulk API with less details (noble)
-* SOLR-8766 : deprecated <admin> tag in solrconfig.xml is removed (noble)
+* SOLR-8766: Remove deprecated <admin> tag in solrconfig.xml and support for admin/gettableFiles
+ (noble, Jason Gerlowski, Varun Thacker)
================== 5.5.1 ==================
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/dcb7a882/solr/core/src/java/org/apache/solr/core/SolrCore.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index f4c40f8..cde878a 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -726,9 +726,6 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
reqHandlers = new RequestHandlers(this);
reqHandlers.initHandlersFromConfig(solrConfig);
- // Handle things that should eventually go away
- initDeprecatedSupport();
-
statsCache = initStatsCache();
// cause the executor to stall so firstSearcher events won't fire
@@ -2270,54 +2267,6 @@ public final class SolrCore implements SolrInfoMBean, Closeable {
}
/**
- * Manage anything that should be taken care of in case configs change
- */
- private void initDeprecatedSupport()
- {
- // TODO -- this should be removed in deprecation release...
- String gettable = solrConfig.get("admin/gettableFiles", null );
- if( gettable != null ) {
- log.warn(
- "solrconfig.xml uses deprecated <admin/gettableFiles>, Please "+
- "update your config to use the ShowFileRequestHandler." );
- if( getRequestHandler( "/admin/file" ) == null ) {
- NamedList<String> invariants = new NamedList<>();
-
- // Hide everything...
- Set<String> hide = new HashSet<>();
-
- for (String file : solrConfig.getResourceLoader().listConfigDir()) {
- hide.add(file.toUpperCase(Locale.ROOT));
- }
-
- // except the "gettable" list
- StringTokenizer st = new StringTokenizer( gettable );
- while( st.hasMoreTokens() ) {
- hide.remove( st.nextToken().toUpperCase(Locale.ROOT) );
- }
- for( String s : hide ) {
- invariants.add( ShowFileRequestHandler.HIDDEN, s );
- }
-
- NamedList<Object> args = new NamedList<>();
- args.add( "invariants", invariants );
- ShowFileRequestHandler handler = new ShowFileRequestHandler();
- handler.init( args );
- reqHandlers.register("/admin/file", handler);
-
- log.warn( "adding ShowFileRequestHandler with hidden files: "+hide );
- }
- }
-
- String facetSort = solrConfig.get("//bool[@name='facet.sort']", null);
- if (facetSort != null) {
- log.warn(
- "solrconfig.xml uses deprecated <bool name='facet.sort'>. Please "+
- "update your config to use <string name='facet.sort'>.");
- }
- }
-
- /**
* Creates and initializes a RestManager based on configuration args in solrconfig.xml.
* RestManager provides basic storage support for managed resource data, such as to
* persist stopwords to ZooKeeper if running in SolrCloud mode.
[42/50] [abbrv] lucene-solr git commit: improve testing for sparse
points
Posted by no...@apache.org.
improve testing for sparse points
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/62b3aaa5
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/62b3aaa5
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/62b3aaa5
Branch: refs/heads/apiv2
Commit: 62b3aaa526d6b883e95cf899d0fc89da11fc5e93
Parents: 56ad6e5
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 8 15:21:37 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 8 15:21:37 2016 -0500
----------------------------------------------------------------------
.../index/TestBackwardsCompatibility.java | 2 +-
.../index/TestFlushByRamOrCountsPolicy.java | 2 +-
.../lucene/index/TestForceMergeForever.java | 2 +-
.../test/org/apache/lucene/index/TestNorms.java | 2 +-
.../apache/lucene/index/TestPointValues.java | 46 ++++++++++++++++
.../apache/lucene/index/TestRollingUpdates.java | 2 +-
.../org/apache/lucene/index/TestTermsEnum.java | 2 +-
.../lucene/store/TestNRTCachingDirectory.java | 2 +-
.../org/apache/lucene/util/fst/TestFSTs.java | 2 +-
.../analyzing/TestFreeTextSuggester.java | 2 +-
.../ThreadedIndexingAndSearchingTestCase.java | 2 +-
.../lucene/search/ShardSearchingTestBase.java | 2 +-
.../org/apache/lucene/util/LineFileDocs.java | 58 +++++++++++++-------
13 files changed, 95 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/backward-codecs/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
----------------------------------------------------------------------
diff --git a/lucene/backward-codecs/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java b/lucene/backward-codecs/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
index 68b32d3..bc48c7a 100644
--- a/lucene/backward-codecs/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
+++ b/lucene/backward-codecs/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
@@ -148,7 +148,7 @@ public class TestBackwardsCompatibility extends LuceneTestCase {
IndexWriterConfig conf = new IndexWriterConfig(analyzer)
.setMergePolicy(mp).setUseCompoundFile(false);
IndexWriter writer = new IndexWriter(dir, conf);
- LineFileDocs docs = new LineFileDocs(null, true);
+ LineFileDocs docs = new LineFileDocs(null);
for(int i=0;i<50;i++) {
writer.addDocument(docs.nextDoc());
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/index/TestFlushByRamOrCountsPolicy.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestFlushByRamOrCountsPolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestFlushByRamOrCountsPolicy.java
index 562913e..993a521 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestFlushByRamOrCountsPolicy.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestFlushByRamOrCountsPolicy.java
@@ -39,7 +39,7 @@ public class TestFlushByRamOrCountsPolicy extends LuceneTestCase {
@BeforeClass
public static void beforeClass() throws Exception {
- lineDocFile = new LineFileDocs(random(), true);
+ lineDocFile = new LineFileDocs(random());
}
@AfterClass
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/index/TestForceMergeForever.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestForceMergeForever.java b/lucene/core/src/test/org/apache/lucene/index/TestForceMergeForever.java
index 3edeef1..0379395 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestForceMergeForever.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestForceMergeForever.java
@@ -62,7 +62,7 @@ public class TestForceMergeForever extends LuceneTestCase {
// Try to make an index that requires merging:
w.getConfig().setMaxBufferedDocs(TestUtil.nextInt(random(), 2, 11));
final int numStartDocs = atLeast(20);
- final LineFileDocs docs = new LineFileDocs(random(), true);
+ final LineFileDocs docs = new LineFileDocs(random());
for(int docIDX=0;docIDX<numStartDocs;docIDX++) {
w.addDocument(docs.nextDoc());
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/index/TestNorms.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestNorms.java b/lucene/core/src/test/org/apache/lucene/index/TestNorms.java
index 78fc872..562cefb 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestNorms.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestNorms.java
@@ -133,7 +133,7 @@ public class TestNorms extends LuceneTestCase {
Similarity provider = new MySimProvider();
config.setSimilarity(provider);
RandomIndexWriter writer = new RandomIndexWriter(random, dir, config);
- final LineFileDocs docs = new LineFileDocs(random, true);
+ final LineFileDocs docs = new LineFileDocs(random);
int num = atLeast(100);
for (int i = 0; i < num; i++) {
Document doc = docs.nextDoc();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
index 9ced11a..55d4794 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
@@ -582,4 +582,50 @@ public class TestPointValues extends LuceneTestCase {
w.close();
dir.close();
}
+
+ public void testSparsePoints() throws Exception {
+ Directory dir = newDirectory();
+ int numDocs = atLeast(1000);
+ int numFields = TestUtil.nextInt(random(), 1, 10);
+ RandomIndexWriter w = new RandomIndexWriter(random(), dir);
+ int[] fieldDocCounts = new int[numFields];
+ int[] fieldSizes = new int[numFields];
+ for(int i=0;i<numDocs;i++) {
+ Document doc = new Document();
+ for(int field=0;field<numFields;field++) {
+ String fieldName = "int" + field;
+ if (random().nextInt(100) == 17) {
+ doc.add(new IntPoint(fieldName, random().nextInt()));
+ fieldDocCounts[field]++;
+ fieldSizes[field]++;
+
+ if (random().nextInt(10) == 5) {
+ // add same field again!
+ doc.add(new IntPoint(fieldName, random().nextInt()));
+ fieldSizes[field]++;
+ }
+ }
+ }
+ w.addDocument(doc);
+ }
+
+ IndexReader r = w.getReader();
+ for(int field=0;field<numFields;field++) {
+ int docCount = 0;
+ int size = 0;
+ String fieldName = "int" + field;
+ for(LeafReaderContext ctx : r.leaves()) {
+ PointValues points = ctx.reader().getPointValues();
+ if (ctx.reader().getFieldInfos().fieldInfo(fieldName) != null) {
+ docCount += points.getDocCount(fieldName);
+ size += points.size(fieldName);
+ }
+ }
+ assertEquals(fieldDocCounts[field], docCount);
+ assertEquals(fieldSizes[field], size);
+ }
+ r.close();
+ w.close();
+ dir.close();
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java b/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java
index e02afc0..23be40b 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestRollingUpdates.java
@@ -40,7 +40,7 @@ public class TestRollingUpdates extends LuceneTestCase {
Random random = new Random(random().nextLong());
final BaseDirectoryWrapper dir = newDirectory();
- final LineFileDocs docs = new LineFileDocs(random, true);
+ final LineFileDocs docs = new LineFileDocs(random);
//provider.register(new MemoryCodec());
if (random().nextBoolean()) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java b/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
index 3296330..aa2ca24 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
@@ -41,7 +41,7 @@ public class TestTermsEnum extends LuceneTestCase {
public void test() throws Exception {
Random random = new Random(random().nextLong());
- final LineFileDocs docs = new LineFileDocs(random, true);
+ final LineFileDocs docs = new LineFileDocs(random);
final Directory d = newDirectory();
MockAnalyzer analyzer = new MockAnalyzer(random());
analyzer.setMaxTokenLength(TestUtil.nextInt(random(), 1, IndexWriter.MAX_TERM_LENGTH));
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java b/lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java
index dfbb7b2..227d41f 100644
--- a/lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java
+++ b/lucene/core/src/test/org/apache/lucene/store/TestNRTCachingDirectory.java
@@ -56,7 +56,7 @@ public class TestNRTCachingDirectory extends BaseDirectoryTestCase {
analyzer.setMaxTokenLength(TestUtil.nextInt(random(), 1, IndexWriter.MAX_TERM_LENGTH));
IndexWriterConfig conf = newIndexWriterConfig(analyzer);
RandomIndexWriter w = new RandomIndexWriter(random(), cachedDir, conf);
- final LineFileDocs docs = new LineFileDocs(random(), true);
+ final LineFileDocs docs = new LineFileDocs(random());
final int numDocs = TestUtil.nextInt(random(), 100, 400);
if (VERBOSE) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/core/src/test/org/apache/lucene/util/fst/TestFSTs.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/util/fst/TestFSTs.java b/lucene/core/src/test/org/apache/lucene/util/fst/TestFSTs.java
index c352938..5f01482 100644
--- a/lucene/core/src/test/org/apache/lucene/util/fst/TestFSTs.java
+++ b/lucene/core/src/test/org/apache/lucene/util/fst/TestFSTs.java
@@ -310,7 +310,7 @@ public class TestFSTs extends LuceneTestCase {
// file, up until a doc limit
public void testRealTerms() throws Exception {
- final LineFileDocs docs = new LineFileDocs(random(), true);
+ final LineFileDocs docs = new LineFileDocs(random());
final int numDocs = TEST_NIGHTLY ? atLeast(1000) : atLeast(100);
MockAnalyzer analyzer = new MockAnalyzer(random());
analyzer.setMaxTokenLength(TestUtil.nextInt(random(), 1, IndexWriter.MAX_TERM_LENGTH));
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestFreeTextSuggester.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestFreeTextSuggester.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestFreeTextSuggester.java
index 4fd7773..b26b5332 100644
--- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestFreeTextSuggester.java
+++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/analyzing/TestFreeTextSuggester.java
@@ -131,7 +131,7 @@ public class TestFreeTextSuggester extends LuceneTestCase {
@Ignore
public void testWiki() throws Exception {
- final LineFileDocs lfd = new LineFileDocs(null, "/lucenedata/enwiki/enwiki-20120502-lines-1k.txt", false);
+ final LineFileDocs lfd = new LineFileDocs(null, "/lucenedata/enwiki/enwiki-20120502-lines-1k.txt");
// Skip header:
lfd.nextDoc();
Analyzer analyzer = new MockAnalyzer(random());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
index 80c3903..e79d548 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
@@ -429,7 +429,7 @@ public abstract class ThreadedIndexingAndSearchingTestCase extends LuceneTestCas
final long t0 = System.currentTimeMillis();
Random random = new Random(random().nextLong());
- final LineFileDocs docs = new LineFileDocs(random, true);
+ final LineFileDocs docs = new LineFileDocs(random);
final Path tempDir = createTempDir(testName);
dir = getDirectory(newMockFSDirectory(tempDir)); // some subclasses rely on this being MDW
if (dir instanceof BaseDirectoryWrapper) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
index 52c16dc..9449a72 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
@@ -552,7 +552,7 @@ public abstract class ShardSearchingTestBase extends LuceneTestCase {
@Override
public void run() {
try {
- final LineFileDocs docs = new LineFileDocs(random(), true);
+ final LineFileDocs docs = new LineFileDocs(random());
int numDocs = 0;
while (System.nanoTime() < endTimeNanos) {
final int what = random().nextInt(3);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/62b3aaa5/lucene/test-framework/src/java/org/apache/lucene/util/LineFileDocs.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LineFileDocs.java b/lucene/test-framework/src/java/org/apache/lucene/util/LineFileDocs.java
index 26d7cc3..8844d8f 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/LineFileDocs.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/LineFileDocs.java
@@ -33,16 +33,17 @@ import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPInputStream;
-import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.IntPoint;
+import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.index.IndexableField;
/** Minimal port of benchmark's LneDocSource +
* DocMaker, so tests can enum docs from a line file created
@@ -53,22 +54,18 @@ public class LineFileDocs implements Closeable {
private final static int BUFFER_SIZE = 1 << 16; // 64K
private final AtomicInteger id = new AtomicInteger();
private final String path;
- private final boolean useDocValues;
+ private final Random random;
/** If forever is true, we rewind the file at EOF (repeat
* the docs over and over) */
- public LineFileDocs(Random random, String path, boolean useDocValues) throws IOException {
+ public LineFileDocs(Random random, String path) throws IOException {
this.path = path;
- this.useDocValues = useDocValues;
+ this.random = new Random(random.nextLong());
open(random);
}
public LineFileDocs(Random random) throws IOException {
- this(random, LuceneTestCase.TEST_LINE_DOCS_FILE, true);
- }
-
- public LineFileDocs(Random random, boolean useDocValues) throws IOException {
- this(random, LuceneTestCase.TEST_LINE_DOCS_FILE, useDocValues);
+ this(random, LuceneTestCase.TEST_LINE_DOCS_FILE);
}
@Override
@@ -165,7 +162,7 @@ public class LineFileDocs implements Closeable {
final Field idNumDV;
final Field date;
- public DocState(boolean useDocValues) {
+ public DocState() {
doc = new Document();
title = new StringField("title", "", Field.Store.NO);
@@ -192,15 +189,10 @@ public class LineFileDocs implements Closeable {
date = new StringField("date", "", Field.Store.YES);
doc.add(date);
- if (useDocValues) {
- titleDV = new SortedDocValuesField("titleDV", new BytesRef());
- idNumDV = new NumericDocValuesField("docid_intDV", 0);
- doc.add(titleDV);
- doc.add(idNumDV);
- } else {
- titleDV = null;
- idNumDV = null;
- }
+ titleDV = new SortedDocValuesField("titleDV", new BytesRef());
+ idNumDV = new NumericDocValuesField("docid_intDV", 0);
+ doc.add(titleDV);
+ doc.add(idNumDV);
}
}
@@ -225,7 +217,7 @@ public class LineFileDocs implements Closeable {
DocState docState = threadDocs.get();
if (docState == null) {
- docState = new DocState(useDocValues);
+ docState = new DocState();
threadDocs.set(docState);
}
@@ -252,6 +244,32 @@ public class LineFileDocs implements Closeable {
if (docState.idNumDV != null) {
docState.idNumDV.setLongValue(i);
}
+
+ if (random.nextInt(5) == 4) {
+ // Make some sparse fields
+ Document doc = new Document();
+ for(IndexableField field : docState.doc) {
+ doc.add(field);
+ }
+
+ if (random.nextInt(3) == 1) {
+ int x = random.nextInt(4);
+ doc.add(new IntPoint("docLength" + x, line.length()));
+ }
+
+ if (random.nextInt(3) == 1) {
+ int x = random.nextInt(4);
+ doc.add(new IntPoint("docTitleLength" + x, title.length()));
+ }
+
+ if (random.nextInt(3) == 1) {
+ int x = random.nextInt(4);
+ doc.add(new NumericDocValuesField("docLength" + x, line.length()));
+ }
+
+ // TODO: more random sparse fields here too
+ }
+
return docState.doc;
}
}
[23/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
LUCENE-7056: Geo3D package re-org
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/f7f81c32
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/f7f81c32
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/f7f81c32
Branch: refs/heads/apiv2
Commit: f7f81c3284cb855136c4e468b6e1f73cf58ced4c
Parents: 3d633c6
Author: David Smiley <ds...@apache.org>
Authored: Mon Mar 7 17:29:46 2016 -0500
Committer: David Smiley <ds...@apache.org>
Committed: Mon Mar 7 20:14:19 2016 -0500
----------------------------------------------------------------------
lucene/CHANGES.txt | 2 +
.../lucene/spatial/spatial4j/Geo3dShape.java | 12 +-
.../lucene/spatial/spatial4j/Geo3dRptTest.java | 14 +-
.../Geo3dShapeRectRelationTestCase.java | 18 +-
.../Geo3dShapeSphereModelRectRelationTest.java | 16 +-
.../Geo3dShapeWGS84ModelRectRelationTest.java | 16 +-
.../spatial/spatial4j/geo3d/GeoPointTest.java | 80 -
.../org/apache/lucene/geo3d/ArcDistance.java | 56 -
.../apache/lucene/geo3d/BasePlanetObject.java | 57 -
.../org/apache/lucene/geo3d/BaseXYZSolid.java | 167 --
.../java/org/apache/lucene/geo3d/Bounds.java | 113 --
.../org/apache/lucene/geo3d/DistanceStyle.java | 83 -
.../org/apache/lucene/geo3d/Geo3DPoint.java | 112 --
.../java/org/apache/lucene/geo3d/Geo3DUtil.java | 59 -
.../java/org/apache/lucene/geo3d/GeoArea.java | 67 -
.../org/apache/lucene/geo3d/GeoAreaFactory.java | 55 -
.../java/org/apache/lucene/geo3d/GeoBBox.java | 36 -
.../org/apache/lucene/geo3d/GeoBBoxFactory.java | 111 --
.../org/apache/lucene/geo3d/GeoBaseBBox.java | 72 -
.../org/apache/lucene/geo3d/GeoBaseCircle.java | 34 -
.../lucene/geo3d/GeoBaseDistanceShape.java | 56 -
.../lucene/geo3d/GeoBaseMembershipShape.java | 56 -
.../org/apache/lucene/geo3d/GeoBasePolygon.java | 34 -
.../org/apache/lucene/geo3d/GeoBaseShape.java | 59 -
.../java/org/apache/lucene/geo3d/GeoCircle.java | 25 -
.../apache/lucene/geo3d/GeoCircleFactory.java | 43 -
.../geo3d/GeoCompositeMembershipShape.java | 117 --
.../lucene/geo3d/GeoCompositePolygon.java | 31 -
.../apache/lucene/geo3d/GeoConvexPolygon.java | 288 ---
.../geo3d/GeoDegenerateHorizontalLine.java | 215 ---
.../lucene/geo3d/GeoDegenerateLatitudeZone.java | 138 --
.../geo3d/GeoDegenerateLongitudeSlice.java | 153 --
.../apache/lucene/geo3d/GeoDegeneratePoint.java | 135 --
.../lucene/geo3d/GeoDegenerateVerticalLine.java | 205 ---
.../org/apache/lucene/geo3d/GeoDistance.java | 59 -
.../apache/lucene/geo3d/GeoDistanceShape.java | 27 -
.../apache/lucene/geo3d/GeoLatitudeZone.java | 198 ---
.../apache/lucene/geo3d/GeoLongitudeSlice.java | 204 ---
.../apache/lucene/geo3d/GeoMembershipShape.java | 27 -
.../lucene/geo3d/GeoNorthLatitudeZone.java | 165 --
.../apache/lucene/geo3d/GeoNorthRectangle.java | 263 ---
.../apache/lucene/geo3d/GeoOutsideDistance.java | 55 -
.../java/org/apache/lucene/geo3d/GeoPath.java | 797 ---------
.../java/org/apache/lucene/geo3d/GeoPoint.java | 193 --
.../org/apache/lucene/geo3d/GeoPolygon.java | 26 -
.../apache/lucene/geo3d/GeoPolygonFactory.java | 187 --
.../org/apache/lucene/geo3d/GeoRectangle.java | 288 ---
.../java/org/apache/lucene/geo3d/GeoShape.java | 63 -
.../org/apache/lucene/geo3d/GeoSizeable.java | 40 -
.../lucene/geo3d/GeoSouthLatitudeZone.java | 168 --
.../apache/lucene/geo3d/GeoSouthRectangle.java | 259 ---
.../apache/lucene/geo3d/GeoStandardCircle.java | 168 --
.../geo3d/GeoWideDegenerateHorizontalLine.java | 238 ---
.../lucene/geo3d/GeoWideLongitudeSlice.java | 208 ---
.../lucene/geo3d/GeoWideNorthRectangle.java | 286 ---
.../apache/lucene/geo3d/GeoWideRectangle.java | 319 ----
.../lucene/geo3d/GeoWideSouthRectangle.java | 284 ---
.../java/org/apache/lucene/geo3d/GeoWorld.java | 106 --
.../org/apache/lucene/geo3d/LatLonBounds.java | 322 ----
.../org/apache/lucene/geo3d/LinearDistance.java | 56 -
.../lucene/geo3d/LinearSquaredDistance.java | 56 -
.../org/apache/lucene/geo3d/Membership.java | 46 -
.../org/apache/lucene/geo3d/NormalDistance.java | 56 -
.../lucene/geo3d/NormalSquaredDistance.java | 56 -
.../src/java/org/apache/lucene/geo3d/Plane.java | 1657 ------------------
.../org/apache/lucene/geo3d/PlanetModel.java | 277 ---
.../lucene/geo3d/PointInGeo3DShapeQuery.java | 210 ---
.../org/apache/lucene/geo3d/SidedPlane.java | 175 --
.../apache/lucene/geo3d/StandardXYZSolid.java | 417 -----
.../src/java/org/apache/lucene/geo3d/Tools.java | 41 -
.../java/org/apache/lucene/geo3d/Vector.java | 378 ----
.../java/org/apache/lucene/geo3d/XYZBounds.java | 267 ---
.../java/org/apache/lucene/geo3d/XYZSolid.java | 26 -
.../apache/lucene/geo3d/XYZSolidFactory.java | 67 -
.../java/org/apache/lucene/geo3d/XYdZSolid.java | 213 ---
.../java/org/apache/lucene/geo3d/XdYZSolid.java | 212 ---
.../org/apache/lucene/geo3d/XdYdZSolid.java | 138 --
.../java/org/apache/lucene/geo3d/dXYZSolid.java | 216 ---
.../org/apache/lucene/geo3d/dXYdZSolid.java | 138 --
.../org/apache/lucene/geo3d/dXdYZSolid.java | 138 --
.../org/apache/lucene/geo3d/dXdYdZSolid.java | 146 --
.../org/apache/lucene/geo3d/package-info.java | 21 -
.../org/apache/lucene/spatial3d/Geo3DPoint.java | 114 ++
.../org/apache/lucene/spatial3d/Geo3DUtil.java | 59 +
.../spatial3d/PointInGeo3DShapeQuery.java | 215 +++
.../lucene/spatial3d/geom/ArcDistance.java | 56 +
.../lucene/spatial3d/geom/BasePlanetObject.java | 57 +
.../lucene/spatial3d/geom/BaseXYZSolid.java | 167 ++
.../apache/lucene/spatial3d/geom/Bounds.java | 113 ++
.../lucene/spatial3d/geom/DistanceStyle.java | 83 +
.../apache/lucene/spatial3d/geom/GeoArea.java | 67 +
.../lucene/spatial3d/geom/GeoAreaFactory.java | 55 +
.../apache/lucene/spatial3d/geom/GeoBBox.java | 36 +
.../lucene/spatial3d/geom/GeoBBoxFactory.java | 111 ++
.../lucene/spatial3d/geom/GeoBaseBBox.java | 72 +
.../lucene/spatial3d/geom/GeoBaseCircle.java | 34 +
.../spatial3d/geom/GeoBaseDistanceShape.java | 56 +
.../spatial3d/geom/GeoBaseMembershipShape.java | 56 +
.../lucene/spatial3d/geom/GeoBasePolygon.java | 34 +
.../lucene/spatial3d/geom/GeoBaseShape.java | 59 +
.../apache/lucene/spatial3d/geom/GeoCircle.java | 25 +
.../lucene/spatial3d/geom/GeoCircleFactory.java | 43 +
.../geom/GeoCompositeMembershipShape.java | 117 ++
.../spatial3d/geom/GeoCompositePolygon.java | 31 +
.../lucene/spatial3d/geom/GeoConvexPolygon.java | 288 +++
.../geom/GeoDegenerateHorizontalLine.java | 215 +++
.../geom/GeoDegenerateLatitudeZone.java | 138 ++
.../geom/GeoDegenerateLongitudeSlice.java | 153 ++
.../spatial3d/geom/GeoDegeneratePoint.java | 135 ++
.../geom/GeoDegenerateVerticalLine.java | 205 +++
.../lucene/spatial3d/geom/GeoDistance.java | 59 +
.../lucene/spatial3d/geom/GeoDistanceShape.java | 27 +
.../lucene/spatial3d/geom/GeoLatitudeZone.java | 198 +++
.../spatial3d/geom/GeoLongitudeSlice.java | 204 +++
.../spatial3d/geom/GeoMembershipShape.java | 27 +
.../spatial3d/geom/GeoNorthLatitudeZone.java | 165 ++
.../spatial3d/geom/GeoNorthRectangle.java | 263 +++
.../spatial3d/geom/GeoOutsideDistance.java | 55 +
.../apache/lucene/spatial3d/geom/GeoPath.java | 797 +++++++++
.../apache/lucene/spatial3d/geom/GeoPoint.java | 193 ++
.../lucene/spatial3d/geom/GeoPolygon.java | 26 +
.../spatial3d/geom/GeoPolygonFactory.java | 187 ++
.../lucene/spatial3d/geom/GeoRectangle.java | 288 +++
.../apache/lucene/spatial3d/geom/GeoShape.java | 63 +
.../lucene/spatial3d/geom/GeoSizeable.java | 40 +
.../spatial3d/geom/GeoSouthLatitudeZone.java | 168 ++
.../spatial3d/geom/GeoSouthRectangle.java | 259 +++
.../spatial3d/geom/GeoStandardCircle.java | 168 ++
.../geom/GeoWideDegenerateHorizontalLine.java | 238 +++
.../spatial3d/geom/GeoWideLongitudeSlice.java | 208 +++
.../spatial3d/geom/GeoWideNorthRectangle.java | 286 +++
.../lucene/spatial3d/geom/GeoWideRectangle.java | 319 ++++
.../spatial3d/geom/GeoWideSouthRectangle.java | 284 +++
.../apache/lucene/spatial3d/geom/GeoWorld.java | 106 ++
.../lucene/spatial3d/geom/LatLonBounds.java | 322 ++++
.../lucene/spatial3d/geom/LinearDistance.java | 56 +
.../spatial3d/geom/LinearSquaredDistance.java | 56 +
.../lucene/spatial3d/geom/Membership.java | 46 +
.../lucene/spatial3d/geom/NormalDistance.java | 56 +
.../spatial3d/geom/NormalSquaredDistance.java | 56 +
.../org/apache/lucene/spatial3d/geom/Plane.java | 1657 ++++++++++++++++++
.../lucene/spatial3d/geom/PlanetModel.java | 277 +++
.../lucene/spatial3d/geom/SidedPlane.java | 175 ++
.../lucene/spatial3d/geom/StandardXYZSolid.java | 417 +++++
.../org/apache/lucene/spatial3d/geom/Tools.java | 41 +
.../apache/lucene/spatial3d/geom/Vector.java | 378 ++++
.../apache/lucene/spatial3d/geom/XYZBounds.java | 267 +++
.../apache/lucene/spatial3d/geom/XYZSolid.java | 26 +
.../lucene/spatial3d/geom/XYZSolidFactory.java | 67 +
.../apache/lucene/spatial3d/geom/XYdZSolid.java | 213 +++
.../apache/lucene/spatial3d/geom/XdYZSolid.java | 212 +++
.../lucene/spatial3d/geom/XdYdZSolid.java | 138 ++
.../apache/lucene/spatial3d/geom/dXYZSolid.java | 216 +++
.../lucene/spatial3d/geom/dXYdZSolid.java | 138 ++
.../lucene/spatial3d/geom/dXdYZSolid.java | 138 ++
.../lucene/spatial3d/geom/dXdYdZSolid.java | 146 ++
.../lucene/spatial3d/geom/package-info.java | 22 +
.../apache/lucene/spatial3d/package-info.java | 21 +
lucene/spatial3d/src/java/overview.html | 3 +-
.../org/apache/lucene/geo3d/GeoBBoxTest.java | 364 ----
.../org/apache/lucene/geo3d/GeoCircleTest.java | 415 -----
.../lucene/geo3d/GeoConvexPolygonTest.java | 91 -
.../org/apache/lucene/geo3d/GeoModelTest.java | 110 --
.../org/apache/lucene/geo3d/GeoPathTest.java | 270 ---
.../org/apache/lucene/geo3d/GeoPolygonTest.java | 165 --
.../test/org/apache/lucene/geo3d/PlaneTest.java | 64 -
.../org/apache/lucene/geo3d/TestGeo3DPoint.java | 801 ---------
.../org/apache/lucene/geo3d/XYZSolidTest.java | 220 ---
.../apache/lucene/spatial3d/TestGeo3DPoint.java | 810 +++++++++
.../lucene/spatial3d/geom/GeoBBoxTest.java | 364 ++++
.../lucene/spatial3d/geom/GeoCircleTest.java | 410 +++++
.../spatial3d/geom/GeoConvexPolygonTest.java | 91 +
.../lucene/spatial3d/geom/GeoModelTest.java | 110 ++
.../lucene/spatial3d/geom/GeoPathTest.java | 270 +++
.../lucene/spatial3d/geom/GeoPointTest.java | 77 +
.../lucene/spatial3d/geom/GeoPolygonTest.java | 165 ++
.../apache/lucene/spatial3d/geom/PlaneTest.java | 64 +
.../lucene/spatial3d/geom/XYZSolidTest.java | 220 +++
178 files changed, 15186 insertions(+), 15153 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 5e717d4..65281b5 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -133,6 +133,8 @@ API Changes
* LUCENE-7072: Geo3DPoint always uses WGS84 planet model.
(Robert Muir, Mike McCandless)
+* LUCENE-7056: Geo3D classes are in different packages now. (David Smiley)
+
Optimizations
* LUCENE-6891: Use prefix coding when writing points in
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
index 518fb32..9fa6d8e 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/spatial4j/Geo3dShape.java
@@ -23,12 +23,12 @@ import org.locationtech.spatial4j.shape.Rectangle;
import org.locationtech.spatial4j.shape.Shape;
import org.locationtech.spatial4j.shape.SpatialRelation;
import org.locationtech.spatial4j.shape.impl.RectangleImpl;
-import org.apache.lucene.geo3d.LatLonBounds;
-import org.apache.lucene.geo3d.GeoArea;
-import org.apache.lucene.geo3d.GeoAreaFactory;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
+import org.apache.lucene.spatial3d.geom.LatLonBounds;
+import org.apache.lucene.spatial3d.geom.GeoArea;
+import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
/**
* A Spatial4j Shape wrapping a {@link GeoShape} ("Geo3D") -- a 3D planar geometry based Spatial4j Shape implementation.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
index d26bb29..e62b857 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
@@ -32,13 +32,13 @@ import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPath;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoPolygonFactory;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
+import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
+import org.apache.lucene.spatial3d.geom.GeoStandardCircle;
+import org.apache.lucene.spatial3d.geom.GeoPath;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
import org.junit.Test;
import static org.locationtech.spatial4j.distance.DistanceUtils.DEGREES_TO_RADIANS;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
index 134b8c7..d58985f 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeRectRelationTestCase.java
@@ -25,15 +25,15 @@ import org.locationtech.spatial4j.distance.DistanceUtils;
import org.locationtech.spatial4j.shape.Circle;
import org.locationtech.spatial4j.shape.Point;
import org.locationtech.spatial4j.shape.RectIntersectionTestHelper;
-import org.apache.lucene.geo3d.LatLonBounds;
-import org.apache.lucene.geo3d.GeoBBox;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPath;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoPolygonFactory;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
+import org.apache.lucene.spatial3d.geom.LatLonBounds;
+import org.apache.lucene.spatial3d.geom.GeoBBox;
+import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
+import org.apache.lucene.spatial3d.geom.GeoStandardCircle;
+import org.apache.lucene.spatial3d.geom.GeoPath;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
import org.junit.Rule;
import org.junit.Test;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
index 2d95823..3bce480 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeSphereModelRectRelationTest.java
@@ -20,14 +20,14 @@ import java.util.ArrayList;
import java.util.List;
import org.locationtech.spatial4j.shape.Rectangle;
-import org.apache.lucene.geo3d.GeoArea;
-import org.apache.lucene.geo3d.GeoBBox;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.GeoPolygonFactory;
-import org.apache.lucene.geo3d.GeoShape;
-import org.apache.lucene.geo3d.PlanetModel;
+import org.apache.lucene.spatial3d.geom.GeoArea;
+import org.apache.lucene.spatial3d.geom.GeoBBox;
+import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
+import org.apache.lucene.spatial3d.geom.GeoStandardCircle;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
import org.junit.Test;
public class Geo3dShapeSphereModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
index 3b026c3..b59d7df 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dShapeWGS84ModelRectRelationTest.java
@@ -16,14 +16,14 @@
*/
package org.apache.lucene.spatial.spatial4j;
-import org.apache.lucene.geo3d.GeoArea;
-import org.apache.lucene.geo3d.GeoBBox;
-import org.apache.lucene.geo3d.GeoBBoxFactory;
-import org.apache.lucene.geo3d.GeoCircle;
-import org.apache.lucene.geo3d.GeoStandardCircle;
-import org.apache.lucene.geo3d.GeoPath;
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.PlanetModel;
+import org.apache.lucene.spatial3d.geom.GeoArea;
+import org.apache.lucene.spatial3d.geom.GeoBBox;
+import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
+import org.apache.lucene.spatial3d.geom.GeoCircle;
+import org.apache.lucene.spatial3d.geom.GeoStandardCircle;
+import org.apache.lucene.spatial3d.geom.GeoPath;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
import org.junit.Test;
public class Geo3dShapeWGS84ModelRectRelationTest extends Geo3dShapeRectRelationTestCase {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
deleted file mode 100644
index 4446474..0000000
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/geo3d/GeoPointTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.spatial.spatial4j.geo3d;
-
-import org.apache.lucene.geo3d.GeoPoint;
-import org.apache.lucene.geo3d.PlanetModel;
-import org.apache.lucene.util.LuceneTestCase;
-import org.junit.Test;
-
-import org.locationtech.spatial4j.distance.DistanceUtils;
-
-import static com.carrotsearch.randomizedtesting.RandomizedTest.randomFloat;
-
-/**
- * Test basic GeoPoint functionality.
- */
-public class GeoPointTest extends LuceneTestCase {
-
- @Test
- public void testConversion() {
- testPointRoundTrip(PlanetModel.SPHERE, 90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
- testPointRoundTrip(PlanetModel.SPHERE, -90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
- testPointRoundTrip(PlanetModel.WGS84, 90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
- testPointRoundTrip(PlanetModel.WGS84, -90 * DistanceUtils.DEGREES_TO_RADIANS, 0, 1e-6);
-
- final int times = atLeast(100);
- for (int i = 0; i < times; i++) {
- final double pLat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
- final double pLon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
- testPointRoundTrip(PlanetModel.SPHERE, pLat, pLon, 1e-6);//1e-6 since there's a square root in there (Karl says)
- testPointRoundTrip(PlanetModel.WGS84, pLat, pLon, 1e-6);
- }
- }
-
- protected void testPointRoundTrip(PlanetModel planetModel, double pLat, double pLon, double epsilon) {
- final GeoPoint p1 = new GeoPoint(planetModel, pLat, pLon);
- // In order to force the reverse conversion, we have to construct a geopoint from just x,y,z
- final GeoPoint p2 = new GeoPoint(p1.x, p1.y, p1.z);
- // Now, construct the final point based on getLatitude() and getLongitude()
- final GeoPoint p3 = new GeoPoint(planetModel, p2.getLatitude(), p2.getLongitude());
- double dist = p1.arcDistance(p3);
- assertEquals(0, dist, epsilon);
- }
-
- @Test
- public void testSurfaceDistance() {
- final int times = atLeast(100);
- for (int i = 0; i < times; i++) {
- final double p1Lat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
- final double p1Lon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
- final double p2Lat = (randomFloat() * 180.0 - 90.0) * DistanceUtils.DEGREES_TO_RADIANS;
- final double p2Lon = (randomFloat() * 360.0 - 180.0) * DistanceUtils.DEGREES_TO_RADIANS;
- final GeoPoint p1 = new GeoPoint(PlanetModel.SPHERE, p1Lat, p1Lon);
- final GeoPoint p2 = new GeoPoint(PlanetModel.SPHERE, p2Lat, p2Lon);
- final double arcDistance = p1.arcDistance(p2);
- // Compute ellipsoid distance; it should agree for a sphere
- final double surfaceDistance = PlanetModel.SPHERE.surfaceDistance(p1,p2);
- assertEquals(arcDistance, surfaceDistance, 1e-6);
- }
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testBadLatLon() {
- new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2);
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/ArcDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/ArcDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/ArcDistance.java
deleted file mode 100644
index c49fd1f..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/ArcDistance.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Arc distance computation style.
- *
- * @lucene.experimental
- */
-public class ArcDistance implements DistanceStyle {
-
- /** An instance of the ArcDistance DistanceStyle. */
- public final static ArcDistance INSTANCE = new ArcDistance();
-
- /** Constructor.
- */
- public ArcDistance() {
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
- return point1.arcDistance(point2);
- }
-
- @Override
- public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
- return point1.arcDistance(x2,y2,z2);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
- return plane.arcDistance(planetModel, point, bounds);
- }
-
- @Override
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
- return plane.arcDistance(planetModel, x,y,z, bounds);
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java
deleted file mode 100644
index c64b974..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BasePlanetObject.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * All Geo3D shapes can derive from this base class, which furnishes
- * some common code
- *
- * @lucene.internal
- */
-public abstract class BasePlanetObject {
-
- /** This is the planet model embedded in all objects derived from this
- * class. */
- protected final PlanetModel planetModel;
-
- /** Constructor creating class instance given a planet model.
- * @param planetModel is the planet model.
- */
- public BasePlanetObject(final PlanetModel planetModel) {
- this.planetModel = planetModel;
- }
-
- /** Returns the {@link PlanetModel} provided when this shape was created. */
- public PlanetModel getPlanetModel() {
- return planetModel;
- }
-
- @Override
- public int hashCode() {
- return planetModel.hashCode();
- }
-
- @Override
- public boolean equals(final Object o) {
- if (!(o instanceof BasePlanetObject))
- return false;
- return planetModel.equals(((BasePlanetObject)o).planetModel);
- }
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BaseXYZSolid.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BaseXYZSolid.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BaseXYZSolid.java
deleted file mode 100644
index 52bd5da..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/BaseXYZSolid.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Base class of a family of 3D rectangles, bounded on six sides by X,Y,Z limits
- *
- * @lucene.internal
- */
-public abstract class BaseXYZSolid extends BasePlanetObject implements XYZSolid {
-
- /** Unit vector in x */
- protected static final Vector xUnitVector = new Vector(1.0, 0.0, 0.0);
- /** Unit vector in y */
- protected static final Vector yUnitVector = new Vector(0.0, 1.0, 0.0);
- /** Unit vector in z */
- protected static final Vector zUnitVector = new Vector(0.0, 0.0, 1.0);
-
- /** Vertical plane normal to x unit vector passing through origin */
- protected static final Plane xVerticalPlane = new Plane(0.0, 1.0, 0.0, 0.0);
- /** Vertical plane normal to y unit vector passing through origin */
- protected static final Plane yVerticalPlane = new Plane(1.0, 0.0, 0.0, 0.0);
-
- /** Empty point vector */
- protected static final GeoPoint[] EMPTY_POINTS = new GeoPoint[0];
-
- /**
- * Base solid constructor.
- *@param planetModel is the planet model.
- */
- public BaseXYZSolid(final PlanetModel planetModel) {
- super(planetModel);
- }
-
- /** Construct a single array from a number of individual arrays.
- * @param pointArrays is the array of point arrays.
- * @return the single unified array.
- */
- protected static GeoPoint[] glueTogether(final GeoPoint[]... pointArrays) {
- int count = 0;
- for (final GeoPoint[] pointArray : pointArrays) {
- count += pointArray.length;
- }
- final GeoPoint[] rval = new GeoPoint[count];
- count = 0;
- for (final GeoPoint[] pointArray : pointArrays) {
- for (final GeoPoint point : pointArray) {
- rval[count++] = point;
- }
- }
- return rval;
- }
-
- @Override
- public boolean isWithin(final Vector point) {
- return isWithin(point.x, point.y, point.z);
- }
-
- @Override
- public abstract boolean isWithin(final double x, final double y, final double z);
-
- // Signals for relationship of edge points to shape
-
- /** All edgepoints inside shape */
- protected final static int ALL_INSIDE = 0;
- /** Some edgepoints inside shape */
- protected final static int SOME_INSIDE = 1;
- /** No edgepoints inside shape */
- protected final static int NONE_INSIDE = 2;
- /** No edgepoints at all (means a shape that is the whole world) */
- protected final static int NO_EDGEPOINTS = 3;
-
- /** Determine the relationship between this area and the provided
- * shape's edgepoints.
- *@param path is the shape.
- *@return the relationship.
- */
- protected int isShapeInsideArea(final GeoShape path) {
- final GeoPoint[] pathPoints = path.getEdgePoints();
- if (pathPoints.length == 0)
- return NO_EDGEPOINTS;
- boolean foundOutside = false;
- boolean foundInside = false;
- for (final GeoPoint p : pathPoints) {
- if (isWithin(p)) {
- foundInside = true;
- } else {
- foundOutside = true;
- }
- if (foundInside && foundOutside) {
- return SOME_INSIDE;
- }
- }
- if (!foundInside && !foundOutside)
- return NONE_INSIDE;
- if (foundInside && !foundOutside)
- return ALL_INSIDE;
- if (foundOutside && !foundInside)
- return NONE_INSIDE;
- return SOME_INSIDE;
- }
-
- /** Determine the relationship between a shape and this area's
- * edgepoints.
- *@param path is the shape.
- *@return the relationship.
- */
- protected int isAreaInsideShape(final GeoShape path) {
- final GeoPoint[] edgePoints = getEdgePoints();
- if (edgePoints.length == 0) {
- return NO_EDGEPOINTS;
- }
- boolean foundOutside = false;
- boolean foundInside = false;
- for (final GeoPoint p : edgePoints) {
- if (path.isWithin(p)) {
- foundInside = true;
- } else {
- foundOutside = true;
- }
- if (foundInside && foundOutside) {
- return SOME_INSIDE;
- }
- }
- if (!foundInside && !foundOutside)
- return NONE_INSIDE;
- if (foundInside && !foundOutside)
- return ALL_INSIDE;
- if (foundOutside && !foundInside)
- return NONE_INSIDE;
- return SOME_INSIDE;
- }
-
- /** Get the edge points for this shape.
- *@return the edge points.
- */
- protected abstract GeoPoint[] getEdgePoints();
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof BaseXYZSolid))
- return false;
- BaseXYZSolid other = (BaseXYZSolid) o;
- return super.equals(other);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Bounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Bounds.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Bounds.java
deleted file mode 100755
index 6717220..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Bounds.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * An interface for accumulating bounds information.
- * The bounds object is initially empty. Bounding points
- * are then applied by supplying (x,y,z) tuples. It is also
- * possible to indicate the following edge cases:
- * (1) No longitude bound possible
- * (2) No upper latitude bound possible
- * (3) No lower latitude bound possible
- * When any of these have been applied, further application of
- * points cannot override that decision.
- *
- * @lucene.experimental
- */
-public interface Bounds {
-
- /** Add a general plane to the bounds description.
- *@param planetModel is the planet model.
- *@param plane is the plane.
- *@param bounds are the membership bounds for points along the arc.
- */
- public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds);
-
- /** Add a horizontal plane to the bounds description.
- * This method should EITHER use the supplied latitude, OR use the supplied
- * plane, depending on what is most efficient.
- *@param planetModel is the planet model.
- *@param latitude is the latitude.
- *@param horizontalPlane is the plane.
- *@param bounds are the constraints on the plane.
- *@return updated Bounds object.
- */
- public Bounds addHorizontalPlane(final PlanetModel planetModel,
- final double latitude,
- final Plane horizontalPlane,
- final Membership... bounds);
-
- /** Add a vertical plane to the bounds description.
- * This method should EITHER use the supplied longitude, OR use the supplied
- * plane, depending on what is most efficient.
- *@param planetModel is the planet model.
- *@param longitude is the longitude.
- *@param verticalPlane is the plane.
- *@param bounds are the constraints on the plane.
- *@return updated Bounds object.
- */
- public Bounds addVerticalPlane(final PlanetModel planetModel,
- final double longitude,
- final Plane verticalPlane,
- final Membership... bounds);
-
- /** Add a single point.
- *@param point is the point.
- *@return the updated Bounds object.
- */
- public Bounds addPoint(final GeoPoint point);
-
- /** Add an X value.
- *@param point is the point to take the x value from.
- *@return the updated object.
- */
- public Bounds addXValue(final GeoPoint point);
-
- /** Add a Y value.
- *@param point is the point to take the y value from.
- *@return the updated object.
- */
- public Bounds addYValue(final GeoPoint point);
-
- /** Add a Z value.
- *@param point is the point to take the z value from.
- *@return the updated object.
- */
- public Bounds addZValue(final GeoPoint point);
-
- /** Signal that the shape exceeds Math.PI in longitude.
- *@return the updated Bounds object.
- */
- public Bounds isWide();
-
- /** Signal that there is no longitude bound.
- *@return the updated Bounds object.
- */
- public Bounds noLongitudeBound();
-
- /** Signal that there is no top latitude bound.
- *@return the updated Bounds object.
- */
- public Bounds noTopLatitudeBound();
-
- /** Signal that there is no bottom latitude bound.
- *@return the updated Bounds object.
- */
- public Bounds noBottomLatitudeBound();
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/DistanceStyle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/DistanceStyle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/DistanceStyle.java
deleted file mode 100644
index 28056cb..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/DistanceStyle.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Distance computation styles, supporting various ways of computing
- * distance to shapes.
- *
- * @lucene.experimental
- */
-public interface DistanceStyle {
-
- // convenient access to built-in styles:
-
- /** Arc distance calculator */
- public static final ArcDistance ARC = ArcDistance.INSTANCE;
- /** Linear distance calculator */
- public static final LinearDistance LINEAR = LinearDistance.INSTANCE;
- /** Linear distance squared calculator */
- public static final LinearSquaredDistance LINEAR_SQUARED = LinearSquaredDistance.INSTANCE;
- /** Normal distance calculator */
- public static final NormalDistance NORMAL = NormalDistance.INSTANCE;
- /** Normal distance squared calculator */
- public static final NormalSquaredDistance NORMAL_SQUARED = NormalSquaredDistance.INSTANCE;
-
- /** Compute the distance from a point to another point.
- * @param point1 Starting point
- * @param point2 Final point
- * @return the distance
- */
- public default double computeDistance(final GeoPoint point1, final GeoPoint point2) {
- return computeDistance(point1, point2.x, point2.y, point2.z);
- }
-
- /** Compute the distance from a point to another point.
- * @param point1 Starting point
- * @param x2 Final point x
- * @param y2 Final point y
- * @param z2 Final point z
- * @return the distance
- */
- public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2);
-
- /** Compute the distance from a plane to a point.
- * @param planetModel The planet model
- * @param plane The plane
- * @param point The point
- * @param bounds are the plane bounds
- * @return the distance
- */
- public default double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point,
- final Membership... bounds) {
- return computeDistance(planetModel, plane, point.x, point.y, point.z, bounds);
- }
-
- /** Compute the distance from a plane to a point.
- * @param planetModel The planet model
- * @param plane The plane
- * @param x The point x
- * @param y The point y
- * @param z The point z
- * @param bounds are the plane bounds
- * @return the distance
- */
- public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds);
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java
deleted file mode 100644
index cde87f3..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DPoint.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.NumericUtils;
-import org.apache.lucene.util.RamUsageEstimator;
-
-/**
- * Add this to a document to index lat/lon or x/y/z point, indexed as a 3D point.
- * Multiple values are allowed: just add multiple Geo3DPoint to the document with the
- * same field name.
- * <p>
- * This field defines static factory methods for creating a shape query:
- * <ul>
- * <li>{@link #newShapeQuery newShapeQuery()} for matching all points inside a specified shape
- * </ul>
- *
- * @lucene.experimental */
-public final class Geo3DPoint extends Field {
-
- /** Indexing {@link FieldType}. */
- public static final FieldType TYPE = new FieldType();
- static {
- TYPE.setDimensions(3, Integer.BYTES);
- TYPE.freeze();
- }
-
- /**
- * Creates a new Geo3DPoint field with the specified lat, lon (in radians).
- *
- * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
- */
- public Geo3DPoint(String name, double lat, double lon) {
- super(name, TYPE);
- // Translate lat/lon to x,y,z:
- final GeoPoint point = new GeoPoint(PlanetModel.WGS84, lat, lon);
- fillFieldsData(point.x, point.y, point.z);
- }
-
- /**
- * Creates a new Geo3DPoint field with the specified x,y,z.
- *
- * @throws IllegalArgumentException if the field name is null or lat or lon are out of bounds
- */
- public Geo3DPoint(String name, double x, double y, double z) {
- super(name, TYPE);
- fillFieldsData(x, y, z);
- }
-
- private void fillFieldsData(double x, double y, double z) {
- byte[] bytes = new byte[12];
- encodeDimension(x, bytes, 0);
- encodeDimension(y, bytes, Integer.BYTES);
- encodeDimension(z, bytes, 2*Integer.BYTES);
- fieldsData = new BytesRef(bytes);
- }
-
- // public helper methods (e.g. for queries)
-
- /** Encode single dimension */
- public static void encodeDimension(double value, byte bytes[], int offset) {
- NumericUtils.intToSortableBytes(Geo3DUtil.encodeValue(PlanetModel.WGS84.getMaximumMagnitude(), value), bytes, offset);
- }
-
- /** Decode single dimension */
- public static double decodeDimension(byte value[], int offset) {
- return Geo3DUtil.decodeValueCenter(PlanetModel.WGS84.getMaximumMagnitude(), NumericUtils.sortableBytesToInt(value, offset));
- }
-
- /** Returns a query matching all points inside the provided shape.
- *
- * @param field field name. must not be {@code null}.
- * @param shape Which {@link GeoShape} to match
- */
- public static Query newShapeQuery(String field, GeoShape shape) {
- return new PointInGeo3DShapeQuery(field, shape);
- }
-
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder();
- result.append(getClass().getSimpleName());
- result.append(" <");
- result.append(name);
- result.append(':');
-
- BytesRef bytes = (BytesRef) fieldsData;
- result.append(" x=" + decodeDimension(bytes.bytes, bytes.offset));
- result.append(" y=" + decodeDimension(bytes.bytes, bytes.offset + Integer.BYTES));
- result.append(" z=" + decodeDimension(bytes.bytes, bytes.offset + 2*Integer.BYTES));
- result.append('>');
- return result.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DUtil.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DUtil.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DUtil.java
deleted file mode 100644
index 34880a1..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/Geo3DUtil.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-class Geo3DUtil {
-
- /** Clips the incoming value to the allowed min/max range before encoding, instead of throwing an exception. */
- public static int encodeValueLenient(double planetMax, double x) {
- if (x > planetMax) {
- x = planetMax;
- } else if (x < -planetMax) {
- x = -planetMax;
- }
- return encodeValue(planetMax, x);
- }
-
- public static int encodeValue(double planetMax, double x) {
- if (x > planetMax) {
- throw new IllegalArgumentException("value=" + x + " is out-of-bounds (greater than planetMax=" + planetMax + ")");
- }
- if (x < -planetMax) {
- throw new IllegalArgumentException("value=" + x + " is out-of-bounds (less than than -planetMax=" + -planetMax + ")");
- }
- long y = Math.round (x * (Integer.MAX_VALUE / planetMax));
- assert y >= Integer.MIN_VALUE;
- assert y <= Integer.MAX_VALUE;
-
- return (int) y;
- }
-
- /** Center decode */
- public static double decodeValueCenter(double planetMax, int x) {
- return x * (planetMax / Integer.MAX_VALUE);
- }
-
- /** More negative decode, at bottom of cell */
- public static double decodeValueMin(double planetMax, int x) {
- return (((double)x) - 0.5) * (planetMax / Integer.MAX_VALUE);
- }
-
- /** More positive decode, at top of cell */
- public static double decodeValueMax(double planetMax, int x) {
- return (((double)x) + 0.5) * (planetMax / Integer.MAX_VALUE);
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoArea.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoArea.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoArea.java
deleted file mode 100755
index 424e494..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoArea.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * A GeoArea represents a standard 2-D breakdown of a part of sphere. It can
- * be bounded in latitude, or bounded in both latitude and longitude, or not
- * bounded at all. The purpose of the interface is to describe bounding shapes used for
- * computation of geo hashes.
- *
- * @lucene.experimental
- */
-public interface GeoArea extends Membership {
- // Since we don't know what each GeoArea's constraints are,
- // we put the onus on the GeoArea implementation to do the right thing.
- // This will, of course, rely heavily on methods provided by
- // the underlying GeoShape class.
-
- // Relationship values for "getRelationship()"
-
- /** The referenced shape CONTAINS this area */
- public static final int CONTAINS = 0;
- /** The referenced shape IS WITHIN this area */
- public static final int WITHIN = 1;
- /** The referenced shape OVERLAPS this area */
- public static final int OVERLAPS = 2;
- /** The referenced shape has no relation to this area */
- public static final int DISJOINT = 3;
-
- /**
- * Find the spatial relationship between a shape and the current geo area.
- * Note: return value is how the GeoShape relates to the GeoArea, not the
- * other way around. For example, if this GeoArea is entirely within the
- * shape, then CONTAINS should be returned. If the shape is entirely enclosed
- * by this GeoArea, then WITHIN should be returned.
- *
- * It is permissible to return OVERLAPS instead of WITHIN if the shape
- * intersects with the area at even a single point. So, a circle inscribed in
- * a rectangle could return either OVERLAPS or WITHIN, depending on
- * implementation. It is not permissible to return CONTAINS or DISJOINT
- * in this circumstance, however.
- *
- * Similarly, it is permissible to return OVERLAPS instead of CONTAINS
- * under conditions where the shape consists of multiple independent overlapping
- * subshapes, and the area overlaps one of the subshapes. It is not permissible
- * to return WITHIN or DISJOINT in this circumstance, however.
- *
- * @param shape is the shape to consider.
- * @return the relationship, from the perspective of the shape.
- */
- public int getRelationship(GeoShape shape);
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoAreaFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoAreaFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoAreaFactory.java
deleted file mode 100755
index 24dd211..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoAreaFactory.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Factory for {@link org.apache.lucene.geo3d.GeoArea}.
- *
- * @lucene.experimental
- */
-public class GeoAreaFactory {
- private GeoAreaFactory() {
- }
-
- /**
- * Create a GeoArea of the right kind given the specified bounds.
- * @param planetModel is the planet model
- * @param topLat is the top latitude
- * @param bottomLat is the bottom latitude
- * @param leftLon is the left longitude
- * @param rightLon is the right longitude
- * @return a GeoArea corresponding to what was specified.
- */
- public static GeoArea makeGeoArea(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, final double rightLon) {
- return GeoBBoxFactory.makeGeoBBox(planetModel, topLat, bottomLat, leftLon, rightLon);
- }
-
- /**
- * Create a GeoArea of the right kind given (x,y,z) bounds.
- * @param planetModel is the planet model
- * @param minX is the min X boundary
- * @param maxX is the max X boundary
- * @param minY is the min Y boundary
- * @param maxY is the max Y boundary
- * @param minZ is the min Z boundary
- * @param maxZ is the max Z boundary
- */
- public static GeoArea makeGeoArea(final PlanetModel planetModel, final double minX, final double maxX, final double minY, final double maxY, final double minZ, final double maxZ) {
- return XYZSolidFactory.makeXYZSolid(planetModel, minX, maxX, minY, maxY, minZ, maxZ);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBox.java
deleted file mode 100755
index 10a2388..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBox.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * All bounding box shapes have this interface in common.
- * This describes methods that bounding boxes have above and beyond
- * GeoMembershipShape's.
- *
- * @lucene.experimental
- */
-public interface GeoBBox extends GeoMembershipShape, GeoSizeable, GeoArea {
-
- /**
- * Expand box by specified angle.
- *
- * @param angle is the angle amount to expand the GeoBBox by.
- * @return a new GeoBBox.
- */
- public GeoBBox expand(double angle);
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBoxFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBoxFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBoxFactory.java
deleted file mode 100755
index 9a02ab9..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBBoxFactory.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Factory for {@link org.apache.lucene.geo3d.GeoBBox}.
- *
- * @lucene.experimental
- */
-public class GeoBBoxFactory {
- private GeoBBoxFactory() {
- }
-
- /**
- * Create a geobbox of the right kind given the specified bounds.
- *
- * @param planetModel is the planet model
- * @param topLat is the top latitude
- * @param bottomLat is the bottom latitude
- * @param leftLon is the left longitude
- * @param rightLon is the right longitude
- * @return a GeoBBox corresponding to what was specified.
- */
- public static GeoBBox makeGeoBBox(final PlanetModel planetModel, double topLat, double bottomLat, double leftLon, double rightLon) {
- //System.err.println("Making rectangle for topLat="+topLat*180.0/Math.PI+", bottomLat="+bottomLat*180.0/Math.PI+", leftLon="+leftLon*180.0/Math.PI+", rightlon="+rightLon*180.0/Math.PI);
- if (topLat > Math.PI * 0.5)
- topLat = Math.PI * 0.5;
- if (bottomLat < -Math.PI * 0.5)
- bottomLat = -Math.PI * 0.5;
- if (leftLon < -Math.PI)
- leftLon = -Math.PI;
- if (rightLon > Math.PI)
- rightLon = Math.PI;
- if (Math.abs(leftLon + Math.PI) < Vector.MINIMUM_RESOLUTION && Math.abs(rightLon - Math.PI) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION && Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
- return new GeoWorld(planetModel);
- if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION || Math.abs(topLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
- return new GeoDegeneratePoint(planetModel, topLat, 0.0);
- return new GeoDegenerateLatitudeZone(planetModel, topLat);
- }
- if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
- return new GeoNorthLatitudeZone(planetModel, bottomLat);
- else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION)
- return new GeoSouthLatitudeZone(planetModel, topLat);
- return new GeoLatitudeZone(planetModel, topLat, bottomLat);
- }
- //System.err.println(" not latitude zone");
- double extent = rightLon - leftLon;
- if (extent < 0.0)
- extent += Math.PI * 2.0;
- if (topLat == Math.PI * 0.5 && bottomLat == -Math.PI * 0.5) {
- if (Math.abs(leftLon - rightLon) < Vector.MINIMUM_RESOLUTION)
- return new GeoDegenerateLongitudeSlice(planetModel, leftLon);
-
- if (extent >= Math.PI)
- return new GeoWideLongitudeSlice(planetModel, leftLon, rightLon);
-
- return new GeoLongitudeSlice(planetModel, leftLon, rightLon);
- }
- //System.err.println(" not longitude slice");
- if (Math.abs(leftLon - rightLon) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION)
- return new GeoDegeneratePoint(planetModel, topLat, leftLon);
- return new GeoDegenerateVerticalLine(planetModel, topLat, bottomLat, leftLon);
- }
- //System.err.println(" not vertical line");
- if (extent >= Math.PI) {
- if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION) {
- //System.err.println(" wide degenerate line");
- return new GeoWideDegenerateHorizontalLine(planetModel, topLat, leftLon, rightLon);
- }
- if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
- return new GeoWideNorthRectangle(planetModel, bottomLat, leftLon, rightLon);
- } else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
- return new GeoWideSouthRectangle(planetModel, topLat, leftLon, rightLon);
- }
- //System.err.println(" wide rect");
- return new GeoWideRectangle(planetModel, topLat, bottomLat, leftLon, rightLon);
- }
- if (Math.abs(topLat - bottomLat) < Vector.MINIMUM_RESOLUTION) {
- if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION || Math.abs(topLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
- return new GeoDegeneratePoint(planetModel, topLat, 0.0);
- }
- //System.err.println(" horizontal line");
- return new GeoDegenerateHorizontalLine(planetModel, topLat, leftLon, rightLon);
- }
- if (Math.abs(topLat - Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
- return new GeoNorthRectangle(planetModel, bottomLat, leftLon, rightLon);
- } else if (Math.abs(bottomLat + Math.PI * 0.5) < Vector.MINIMUM_RESOLUTION) {
- return new GeoSouthRectangle(planetModel, topLat, leftLon, rightLon);
- }
- //System.err.println(" rectangle");
- return new GeoRectangle(planetModel, topLat, bottomLat, leftLon, rightLon);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseBBox.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseBBox.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseBBox.java
deleted file mode 100644
index f40a0a1..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseBBox.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * All bounding box shapes can derive from this base class, which furnishes
- * some common code
- *
- * @lucene.internal
- */
-public abstract class GeoBaseBBox extends GeoBaseMembershipShape implements GeoBBox {
-
- /** Construct, given planet model.
- *@param planetModel is the planet model.
- */
- public GeoBaseBBox(final PlanetModel planetModel) {
- super(planetModel);
- }
-
- // Signals for relationship of edge points to shape
-
- /** All edgepoints inside shape */
- protected final static int ALL_INSIDE = 0;
- /** Some edgepoints inside shape */
- protected final static int SOME_INSIDE = 1;
- /** No edgepoints inside shape */
- protected final static int NONE_INSIDE = 2;
-
- /** Determine the relationship between this BBox and the provided
- * shape's edgepoints.
- *@param path is the shape.
- *@return the relationship.
- */
- protected int isShapeInsideBBox(final GeoShape path) {
- final GeoPoint[] pathPoints = path.getEdgePoints();
- boolean foundOutside = false;
- boolean foundInside = false;
- for (GeoPoint p : pathPoints) {
- if (isWithin(p)) {
- foundInside = true;
- } else {
- foundOutside = true;
- }
- if (foundInside && foundOutside) {
- return SOME_INSIDE;
- }
- }
- if (!foundInside && !foundOutside)
- return NONE_INSIDE;
- if (foundInside && !foundOutside)
- return ALL_INSIDE;
- if (foundOutside && !foundInside)
- return NONE_INSIDE;
- return SOME_INSIDE;
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseCircle.java
deleted file mode 100644
index 8c306d7..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseCircle.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * GeoCircles have all the characteristics of GeoBaseDistanceShapes, plus GeoSizeable.
- *
- * @lucene.experimental
- */
-public abstract class GeoBaseCircle extends GeoBaseDistanceShape implements GeoCircle {
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- */
- public GeoBaseCircle(final PlanetModel planetModel) {
- super(planetModel);
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseDistanceShape.java
deleted file mode 100644
index 1c8306a..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseDistanceShape.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Distance shapes have capabilities of both geohashing and distance
- * computation (which also includes point membership determination).
- *
- * @lucene.experimental
- */
-public abstract class GeoBaseDistanceShape extends GeoBaseMembershipShape implements GeoDistanceShape {
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- */
- public GeoBaseDistanceShape(final PlanetModel planetModel) {
- super(planetModel);
- }
-
- @Override
- public boolean isWithin(Vector point) {
- return isWithin(point.x, point.y, point.z);
- }
-
- @Override
- public double computeDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
- return computeDistance(distanceStyle, point.x, point.y, point.z);
- }
-
- @Override
- public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (!isWithin(x,y,z)) {
- return Double.MAX_VALUE;
- }
- return distance(distanceStyle, x, y, z);
- }
-
- /** Called by a {@code computeDistance} method if X/Y/Z is not within this shape. */
- protected abstract double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseMembershipShape.java
deleted file mode 100644
index a6bba8f..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseMembershipShape.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Membership shapes have capabilities of both geohashing and membership
- * determination. This is a useful baseclass for them.
- *
- * @lucene.experimental
- */
-public abstract class GeoBaseMembershipShape extends GeoBaseShape implements GeoMembershipShape {
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- */
- public GeoBaseMembershipShape(final PlanetModel planetModel) {
- super(planetModel);
- }
-
- @Override
- public boolean isWithin(Vector point) {
- return isWithin(point.x, point.y, point.z);
- }
-
- @Override
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
- return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
- }
-
- @Override
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (isWithin(x,y,z)) {
- return 0.0;
- }
- return outsideDistance(distanceStyle, x,y,z);
- }
-
- /** Called by a {@code computeOutsideDistance} method if X/Y/Z is not within this shape. */
- protected abstract double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBasePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBasePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBasePolygon.java
deleted file mode 100644
index 50ad0dc..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBasePolygon.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * GeoBasePolygon objects are the base class of most GeoPolygon objects.
- *
- * @lucene.experimental
- */
-public abstract class GeoBasePolygon extends GeoBaseMembershipShape implements GeoPolygon {
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- */
- public GeoBasePolygon(final PlanetModel planetModel) {
- super(planetModel);
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseShape.java
deleted file mode 100644
index 146cfe8..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoBaseShape.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Base extended shape object.
- *
- * @lucene.internal
- */
-public abstract class GeoBaseShape extends BasePlanetObject implements GeoShape {
-
- /** Constructor.
- *@param planetModel is the planet model to use.
- */
- public GeoBaseShape(final PlanetModel planetModel) {
- super(planetModel);
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- if (isWithin(planetModel.NORTH_POLE)) {
- bounds.noTopLatitudeBound().noLongitudeBound()
- .addPoint(planetModel.NORTH_POLE);
- }
- if (isWithin(planetModel.SOUTH_POLE)) {
- bounds.noBottomLatitudeBound().noLongitudeBound()
- .addPoint(planetModel.SOUTH_POLE);
- }
- if (isWithin(planetModel.MIN_X_POLE)) {
- bounds.addPoint(planetModel.MIN_X_POLE);
- }
- if (isWithin(planetModel.MAX_X_POLE)) {
- bounds.addPoint(planetModel.MAX_X_POLE);
- }
- if (isWithin(planetModel.MIN_Y_POLE)) {
- bounds.addPoint(planetModel.MIN_Y_POLE);
- }
- if (isWithin(planetModel.MAX_Y_POLE)) {
- bounds.addPoint(planetModel.MAX_Y_POLE);
- }
- }
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircle.java
deleted file mode 100755
index 154cdc4..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircle.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Interface describing circular area with a center and radius.
- *
- * @lucene.experimental
- */
-public interface GeoCircle extends GeoDistanceShape, GeoSizeable {
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircleFactory.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircleFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircleFactory.java
deleted file mode 100644
index 2bb8ffc..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCircleFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * Class which constructs a GeoCircle representing an arbitrary circle.
- *
- * @lucene.experimental
- */
-public class GeoCircleFactory {
- private GeoCircleFactory() {
- }
-
- /**
- * Create a GeoCircle of the right kind given the specified bounds.
- * @param planetModel is the planet model.
- * @param latitude is the center latitude.
- * @param longitude is the center longitude.
- * @param radius is the radius 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_RESOLUTION) {
- return new GeoDegeneratePoint(planetModel, latitude, longitude);
- }
- return new GeoStandardCircle(planetModel, latitude, longitude, radius);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositeMembershipShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositeMembershipShape.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositeMembershipShape.java
deleted file mode 100755
index 25bdda0..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositeMembershipShape.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * GeoComposite is a set of GeoMembershipShape's, treated as a unit.
- *
- * @lucene.experimental
- */
-public class GeoCompositeMembershipShape implements GeoMembershipShape {
- /** The list of shapes. */
- protected final List<GeoMembershipShape> shapes = new ArrayList<GeoMembershipShape>();
-
- /** Constructor.
- */
- public GeoCompositeMembershipShape() {
- }
-
- /**
- * Add a shape to the composite.
- *@param shape is the shape to add.
- */
- public void addShape(final GeoMembershipShape shape) {
- shapes.add(shape);
- }
-
- @Override
- public boolean isWithin(final Vector point) {
- return isWithin(point.x, point.y, point.z);
- }
-
- @Override
- public boolean isWithin(final double x, final double y, final double z) {
- for (GeoMembershipShape shape : shapes) {
- if (shape.isWithin(x, y, z))
- return true;
- }
- return false;
- }
-
- @Override
- public GeoPoint[] getEdgePoints() {
- return shapes.get(0).getEdgePoints();
- }
-
- @Override
- public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
- for (GeoMembershipShape shape : shapes) {
- if (shape.intersects(p, notablePoints, bounds))
- return true;
- }
- return false;
- }
-
- @Override
- public void getBounds(Bounds bounds) {
- for (GeoMembershipShape shape : shapes) {
- shape.getBounds(bounds);
- }
- }
-
- @Override
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final GeoPoint point) {
- return computeOutsideDistance(distanceStyle, point.x, point.y, point.z);
- }
-
- @Override
- public double computeOutsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
- if (isWithin(x,y,z))
- return 0.0;
- double distance = Double.MAX_VALUE;
- for (GeoMembershipShape shape : shapes) {
- final double normalDistance = shape.computeOutsideDistance(distanceStyle, x, y, z);
- if (normalDistance < distance) {
- distance = normalDistance;
- }
- }
- return distance;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof GeoCompositeMembershipShape))
- return false;
- GeoCompositeMembershipShape other = (GeoCompositeMembershipShape) o;
-
- return super.equals(o) && shapes.equals(other.shapes);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode() * 31 + shapes.hashCode();//TODO cache
- }
-
- @Override
- public String toString() {
- return "GeoCompositeMembershipShape: {" + shapes + '}';
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositePolygon.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositePolygon.java
deleted file mode 100644
index b537590..0000000
--- a/lucene/spatial3d/src/java/org/apache/lucene/geo3d/GeoCompositePolygon.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-/**
- * GeoCompositePolygon is a specific implementation of GeoMembershipShape, which implements GeoPolygon explicitly.
- *
- * @lucene.experimental
- */
-public class GeoCompositePolygon extends GeoCompositeMembershipShape implements GeoPolygon {
- /** Constructor.
- */
- public GeoCompositePolygon() {
- }
-
-}
-
[09/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/PlaneTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/PlaneTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/PlaneTest.java
deleted file mode 100644
index 2ac3856..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/PlaneTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Test basic plane functionality.
- */
-public class PlaneTest {
-
-
- @Test
- public void testIdenticalPlanes() {
- final GeoPoint p = new GeoPoint(PlanetModel.SPHERE, 0.123, -0.456);
- final Plane plane1 = new Plane(p, 0.0);
- final Plane plane2 = new Plane(p, 0.0);
- assertTrue(plane1.isNumericallyIdentical(plane2));
- final Plane plane3 = new Plane(p, 0.1);
- assertFalse(plane1.isNumericallyIdentical(plane3));
- final Vector v1 = new Vector(0.1, -0.732, 0.9);
- final double constant = 0.432;
- final Vector v2 = new Vector(v1.x * constant, v1.y * constant, v1.z * constant);
- final Plane p1 = new Plane(v1, 0.2);
- final Plane p2 = new Plane(v2, 0.2 * constant);
- assertTrue(p1.isNumericallyIdentical(p2));
- }
-
- @Test
- public void testInterpolation() {
- // [X=0.35168818443386646, Y=-0.19637966197066342, Z=0.9152870857244183],
- // [X=0.5003343189532654, Y=0.522128543226148, Z=0.6906861469771293],
-
- final GeoPoint start = new GeoPoint(0.35168818443386646, -0.19637966197066342, 0.9152870857244183);
- final GeoPoint end = new GeoPoint(0.5003343189532654, 0.522128543226148, 0.6906861469771293);
-
- // [A=-0.6135342247741855, B=0.21504338363863665, C=0.28188192383666794, D=0.0, side=-1.0] internal? false;
- final Plane p = new Plane(-0.6135342247741855, 0.21504338363863665, 0.28188192383666794, 0.0);
-
- final GeoPoint[] points = p.interpolate(start, end, new double[]{0.25, 0.50, 0.75});
-
- for (GeoPoint point : points) {
- assertTrue(p.evaluateIsZero(point));
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java
deleted file mode 100644
index 17a4075..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/TestGeo3DPoint.java
+++ /dev/null
@@ -1,801 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.lucene.codecs.Codec;
-import org.apache.lucene.codecs.FilterCodec;
-import org.apache.lucene.codecs.PointsFormat;
-import org.apache.lucene.codecs.PointsReader;
-import org.apache.lucene.codecs.PointsWriter;
-import org.apache.lucene.codecs.lucene60.Lucene60PointsReader;
-import org.apache.lucene.codecs.lucene60.Lucene60PointsWriter;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.NumericDocValuesField;
-import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.IndexWriterConfig;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.MultiDocValues;
-import org.apache.lucene.index.NumericDocValues;
-import org.apache.lucene.index.SegmentReadState;
-import org.apache.lucene.index.SegmentWriteState;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.SimpleCollector;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.MockDirectoryWrapper;
-import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.IOUtils;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
-import org.junit.BeforeClass;
-
-import com.carrotsearch.randomizedtesting.generators.RandomInts;
-
-public class TestGeo3DPoint extends LuceneTestCase {
-
- private static boolean smallBBox;
-
- @BeforeClass
- public static void beforeClass() {
- smallBBox = random().nextBoolean();
- if (VERBOSE) {
- System.err.println("TEST: smallBBox=" + smallBBox);
- }
- }
-
- private static Codec getCodec() {
- if (Codec.getDefault().getName().equals("Lucene60")) {
- int maxPointsInLeafNode = TestUtil.nextInt(random(), 16, 2048);
- double maxMBSortInHeap = 3.0 + (3*random().nextDouble());
- if (VERBOSE) {
- System.out.println("TEST: using Lucene60PointsFormat with maxPointsInLeafNode=" + maxPointsInLeafNode + " and maxMBSortInHeap=" + maxMBSortInHeap);
- }
-
- return new FilterCodec("Lucene60", Codec.getDefault()) {
- @Override
- public PointsFormat pointsFormat() {
- return new PointsFormat() {
- @Override
- public PointsWriter fieldsWriter(SegmentWriteState writeState) throws IOException {
- return new Lucene60PointsWriter(writeState, maxPointsInLeafNode, maxMBSortInHeap);
- }
-
- @Override
- public PointsReader fieldsReader(SegmentReadState readState) throws IOException {
- return new Lucene60PointsReader(readState);
- }
- };
- }
- };
- } else {
- return Codec.getDefault();
- }
- }
-
- public void testBasic() throws Exception {
- Directory dir = getDirectory();
- IndexWriterConfig iwc = newIndexWriterConfig();
- iwc.setCodec(getCodec());
- IndexWriter w = new IndexWriter(dir, iwc);
- Document doc = new Document();
- doc.add(new Geo3DPoint("field", toRadians(50.7345267), toRadians(-97.5303555)));
- w.addDocument(doc);
- IndexReader r = DirectoryReader.open(w);
- // We can't wrap with "exotic" readers because the query must see the BKD3DDVFormat:
- IndexSearcher s = newSearcher(r, false);
- assertEquals(1, s.search(Geo3DPoint.newShapeQuery("field",
- GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, toRadians(50), toRadians(-97), Math.PI/180.)), 1).totalHits);
- w.close();
- r.close();
- dir.close();
- }
-
- private static double toRadians(double degrees) {
- return Math.PI*(degrees/360.0);
- }
-
- private static PlanetModel getPlanetModel() {
- if (random().nextBoolean()) {
- // Use one of the earth models:
- if (random().nextBoolean()) {
- return PlanetModel.WGS84;
- } else {
- return PlanetModel.SPHERE;
- }
- } else {
- // Make a randomly squashed planet:
- double oblateness = random().nextDouble() * 0.5 - 0.25;
- return new PlanetModel(1.0 + oblateness, 1.0 - oblateness);
- }
- }
-
- private static class Cell {
- static int nextCellID;
-
- final Cell parent;
- final int cellID;
- final int xMinEnc, xMaxEnc;
- final int yMinEnc, yMaxEnc;
- final int zMinEnc, zMaxEnc;
- final int splitCount;
-
- public Cell(Cell parent,
- int xMinEnc, int xMaxEnc,
- int yMinEnc, int yMaxEnc,
- int zMinEnc, int zMaxEnc,
- int splitCount) {
- this.parent = parent;
- this.xMinEnc = xMinEnc;
- this.xMaxEnc = xMaxEnc;
- this.yMinEnc = yMinEnc;
- this.yMaxEnc = yMaxEnc;
- this.zMinEnc = zMinEnc;
- this.zMaxEnc = zMaxEnc;
- this.cellID = nextCellID++;
- this.splitCount = splitCount;
- }
-
- /** Returns true if the quantized point lies within this cell, inclusive on all bounds. */
- public boolean contains(double planetMax, GeoPoint point) {
- int docX = Geo3DUtil.encodeValue(planetMax, point.x);
- int docY = Geo3DUtil.encodeValue(planetMax, point.y);
- int docZ = Geo3DUtil.encodeValue(planetMax, point.z);
-
- return docX >= xMinEnc && docX <= xMaxEnc &&
- docY >= yMinEnc && docY <= yMaxEnc &&
- docZ >= zMinEnc && docZ <= zMaxEnc;
- }
-
- @Override
- public String toString() {
- return "cell=" + cellID + (parent == null ? "" : " parentCellID=" + parent.cellID) + " x: " + xMinEnc + " TO " + xMaxEnc + ", y: " + yMinEnc + " TO " + yMaxEnc + ", z: " + zMinEnc + " TO " + zMaxEnc + ", splits: " + splitCount;
- }
- }
-
- private static GeoPoint quantize(double planetMax, GeoPoint point) {
- return new GeoPoint(Geo3DUtil.decodeValueCenter(planetMax, Geo3DUtil.encodeValue(planetMax, point.x)),
- Geo3DUtil.decodeValueCenter(planetMax, Geo3DUtil.encodeValue(planetMax, point.y)),
- Geo3DUtil.decodeValueCenter(planetMax, Geo3DUtil.encodeValue(planetMax, point.z)));
- }
-
- /** Tests consistency of GeoArea.getRelationship vs GeoShape.isWithin */
- public void testGeo3DRelations() throws Exception {
-
- PlanetModel planetModel = getPlanetModel();
-
- int numDocs = atLeast(1000);
- if (VERBOSE) {
- System.out.println("TEST: " + numDocs + " docs");
- }
-
- GeoPoint[] docs = new GeoPoint[numDocs];
- for(int docID=0;docID<numDocs;docID++) {
- docs[docID] = new GeoPoint(planetModel, toRadians(randomLat()), toRadians(randomLon()));
- if (VERBOSE) {
- System.out.println(" doc=" + docID + ": " + docs[docID]);
- }
- }
-
- double planetMax = planetModel.getMaximumMagnitude();
-
- int iters = atLeast(10);
-
- int recurseDepth = RandomInts.randomIntBetween(random(), 5, 15);
-
- iters = atLeast(50);
-
- for(int iter=0;iter<iters;iter++) {
- GeoShape shape = randomShape(planetModel);
-
- StringWriter sw = new StringWriter();
- PrintWriter log = new PrintWriter(sw, true);
-
- if (VERBOSE) {
- log.println("TEST: iter=" + iter + " shape=" + shape);
- }
-
- XYZBounds bounds = new XYZBounds();
- shape.getBounds(bounds);
-
- // Start with the root cell that fully contains the shape:
- Cell root = new Cell(null,
- Geo3DUtil.encodeValueLenient(planetMax, bounds.getMinimumX()),
- Geo3DUtil.encodeValueLenient(planetMax, bounds.getMaximumX()),
- Geo3DUtil.encodeValueLenient(planetMax, bounds.getMinimumY()),
- Geo3DUtil.encodeValueLenient(planetMax, bounds.getMaximumY()),
- Geo3DUtil.encodeValueLenient(planetMax, bounds.getMinimumZ()),
- Geo3DUtil.encodeValueLenient(planetMax, bounds.getMaximumZ()),
- 0);
-
- if (VERBOSE) {
- log.println(" root cell: " + root);
- }
-
- List<Cell> queue = new ArrayList<>();
- queue.add(root);
- Set<Integer> hits = new HashSet<>();
-
- while (queue.size() > 0) {
- Cell cell = queue.get(queue.size()-1);
- queue.remove(queue.size()-1);
- if (VERBOSE) {
- log.println(" cycle: " + cell + " queue.size()=" + queue.size());
- }
-
- if (random().nextInt(10) == 7 || cell.splitCount > recurseDepth) {
- if (VERBOSE) {
- log.println(" leaf");
- }
- // Leaf cell: brute force check all docs that fall within this cell:
- for(int docID=0;docID<numDocs;docID++) {
- GeoPoint point = docs[docID];
- if (cell.contains(planetMax, point)) {
- if (shape.isWithin(quantize(planetMax, point))) {
- if (VERBOSE) {
- log.println(" check doc=" + docID + ": match!");
- }
- hits.add(docID);
- } else {
- if (VERBOSE) {
- log.println(" check doc=" + docID + ": no match");
- }
- }
- }
- }
- } else {
-
- GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(planetModel,
- Geo3DUtil.decodeValueMin(planetMax, cell.xMinEnc), Geo3DUtil.decodeValueMax(planetMax, cell.xMaxEnc),
- Geo3DUtil.decodeValueMin(planetMax, cell.yMinEnc), Geo3DUtil.decodeValueMax(planetMax, cell.yMaxEnc),
- Geo3DUtil.decodeValueMin(planetMax, cell.zMinEnc), Geo3DUtil.decodeValueMax(planetMax, cell.zMaxEnc));
-
- if (VERBOSE) {
- log.println(" minx="+Geo3DUtil.decodeValueMin(planetMax, cell.xMinEnc)+" maxx="+Geo3DUtil.decodeValueMax(planetMax, cell.xMaxEnc)+
- " miny="+Geo3DUtil.decodeValueMin(planetMax, cell.yMinEnc)+" maxy="+Geo3DUtil.decodeValueMax(planetMax, cell.yMaxEnc)+
- " minz="+Geo3DUtil.decodeValueMin(planetMax, cell.zMinEnc)+" maxz="+Geo3DUtil.decodeValueMax(planetMax, cell.zMaxEnc));
- }
-
- switch (xyzSolid.getRelationship(shape)) {
- case GeoArea.CONTAINS:
- // Shape fully contains the cell: blindly add all docs in this cell:
- if (VERBOSE) {
- log.println(" GeoArea.CONTAINS: now addAll");
- }
- for(int docID=0;docID<numDocs;docID++) {
- if (cell.contains(planetMax, docs[docID])) {
- if (VERBOSE) {
- log.println(" addAll doc=" + docID);
- }
- hits.add(docID);
- }
- }
- continue;
- case GeoArea.OVERLAPS:
- if (VERBOSE) {
- log.println(" GeoArea.OVERLAPS: keep splitting");
- }
- // They do overlap but neither contains the other:
- //log.println(" crosses1");
- break;
- case GeoArea.WITHIN:
- if (VERBOSE) {
- log.println(" GeoArea.WITHIN: keep splitting");
- }
- // Cell fully contains the shape:
- //log.println(" crosses2");
- break;
- case GeoArea.DISJOINT:
- // They do not overlap at all: don't recurse on this cell
- //log.println(" outside");
- if (VERBOSE) {
- log.println(" GeoArea.DISJOINT: drop this cell");
- for(int docID=0;docID<numDocs;docID++) {
- if (cell.contains(planetMax, docs[docID])) {
- if (VERBOSE) {
- log.println(" skip doc=" + docID);
- }
- }
- }
- }
- continue;
- default:
- assert false;
- }
-
- // Randomly split:
- switch(random().nextInt(3)) {
-
- case 0:
- // Split on X:
- {
- int splitValue = RandomInts.randomIntBetween(random(), cell.xMinEnc, cell.xMaxEnc);
- if (VERBOSE) {
- log.println(" now split on x=" + splitValue);
- }
- Cell cell1 = new Cell(cell,
- cell.xMinEnc, splitValue,
- cell.yMinEnc, cell.yMaxEnc,
- cell.zMinEnc, cell.zMaxEnc,
- cell.splitCount+1);
- Cell cell2 = new Cell(cell,
- splitValue, cell.xMaxEnc,
- cell.yMinEnc, cell.yMaxEnc,
- cell.zMinEnc, cell.zMaxEnc,
- cell.splitCount+1);
- if (VERBOSE) {
- log.println(" split cell1: " + cell1);
- log.println(" split cell2: " + cell2);
- }
- queue.add(cell1);
- queue.add(cell2);
- }
- break;
-
- case 1:
- // Split on Y:
- {
- int splitValue = RandomInts.randomIntBetween(random(), cell.yMinEnc, cell.yMaxEnc);
- if (VERBOSE) {
- log.println(" now split on y=" + splitValue);
- }
- Cell cell1 = new Cell(cell,
- cell.xMinEnc, cell.xMaxEnc,
- cell.yMinEnc, splitValue,
- cell.zMinEnc, cell.zMaxEnc,
- cell.splitCount+1);
- Cell cell2 = new Cell(cell,
- cell.xMinEnc, cell.xMaxEnc,
- splitValue, cell.yMaxEnc,
- cell.zMinEnc, cell.zMaxEnc,
- cell.splitCount+1);
- if (VERBOSE) {
- log.println(" split cell1: " + cell1);
- log.println(" split cell2: " + cell2);
- }
- queue.add(cell1);
- queue.add(cell2);
- }
- break;
-
- case 2:
- // Split on Z:
- {
- int splitValue = RandomInts.randomIntBetween(random(), cell.zMinEnc, cell.zMaxEnc);
- if (VERBOSE) {
- log.println(" now split on z=" + splitValue);
- }
- Cell cell1 = new Cell(cell,
- cell.xMinEnc, cell.xMaxEnc,
- cell.yMinEnc, cell.yMaxEnc,
- cell.zMinEnc, splitValue,
- cell.splitCount+1);
- Cell cell2 = new Cell(cell,
- cell.xMinEnc, cell.xMaxEnc,
- cell.yMinEnc, cell.yMaxEnc,
- splitValue, cell.zMaxEnc,
- cell.splitCount+1);
- if (VERBOSE) {
- log.println(" split cell1: " + cell1);
- log.println(" split cell2: " + cell2);
- }
- queue.add(cell1);
- queue.add(cell2);
- }
- break;
- }
- }
- }
-
- if (VERBOSE) {
- log.println(" " + hits.size() + " hits");
- }
-
- // Done matching, now verify:
- boolean fail = false;
- for(int docID=0;docID<numDocs;docID++) {
- GeoPoint point = docs[docID];
- GeoPoint quantized = quantize(planetMax, point);
- boolean expected = shape.isWithin(quantized);
-
- if (expected != shape.isWithin(point)) {
- // Quantization changed the result; skip testing this doc:
- continue;
- }
-
- boolean actual = hits.contains(docID);
- if (actual != expected) {
- if (actual) {
- log.println("doc=" + docID + " matched but should not");
- } else {
- log.println("doc=" + docID + " did not match but should");
- }
- log.println(" point=" + docs[docID]);
- log.println(" quantized=" + quantize(planetMax, docs[docID]));
- fail = true;
- }
- }
-
- if (fail) {
- System.out.print(sw.toString());
- fail("invalid hits for shape=" + shape);
- }
- }
- }
-
- public void testRandomTiny() throws Exception {
- // Make sure single-leaf-node case is OK:
- doTestRandom(10);
- }
-
- public void testRandomMedium() throws Exception {
- doTestRandom(10000);
- }
-
- @Nightly
- public void testRandomBig() throws Exception {
- doTestRandom(200000);
- }
-
- private void doTestRandom(int count) throws Exception {
- int numPoints = atLeast(count);
-
- if (VERBOSE) {
- System.err.println("TEST: numPoints=" + numPoints);
- }
-
- double[] lats = new double[numPoints];
- double[] lons = new double[numPoints];
-
- boolean haveRealDoc = false;
-
- for (int docID=0;docID<numPoints;docID++) {
- int x = random().nextInt(20);
- if (x == 17) {
- // Some docs don't have a point:
- lats[docID] = Double.NaN;
- if (VERBOSE) {
- System.err.println(" doc=" + docID + " is missing");
- }
- continue;
- }
-
- if (docID > 0 && x < 3 && haveRealDoc) {
- int oldDocID;
- while (true) {
- oldDocID = random().nextInt(docID);
- if (Double.isNaN(lats[oldDocID]) == false) {
- break;
- }
- }
-
- if (x == 0) {
- // Identical lat to old point
- lats[docID] = lats[oldDocID];
- lons[docID] = toRadians(randomLon());
- if (VERBOSE) {
- System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID] + " (same lat as doc=" + oldDocID + ")");
- }
- } else if (x == 1) {
- // Identical lon to old point
- lats[docID] = toRadians(randomLat());
- lons[docID] = lons[oldDocID];
- if (VERBOSE) {
- System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID] + " (same lon as doc=" + oldDocID + ")");
- }
- } else {
- assert x == 2;
- // Fully identical point:
- lats[docID] = lats[oldDocID];
- lons[docID] = lons[oldDocID];
- if (VERBOSE) {
- System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID] + " (same lat/lon as doc=" + oldDocID + ")");
- }
- }
- } else {
- lats[docID] = toRadians(randomLat());
- lons[docID] = toRadians(randomLon());
- haveRealDoc = true;
- if (VERBOSE) {
- System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID]);
- }
- }
- }
-
- verify(lats, lons);
- }
-
- private static double randomLat() {
- if (smallBBox) {
- return 2.0 * (random().nextDouble()-0.5);
- } else {
- return -90 + 180.0 * random().nextDouble();
- }
- }
-
- private static double randomLon() {
- if (smallBBox) {
- return 2.0 * (random().nextDouble()-0.5);
- } else {
- return -180 + 360.0 * random().nextDouble();
- }
- }
-
- // Poached from Geo3dRptTest.randomShape:
- private static GeoShape randomShape(PlanetModel planetModel) {
- while (true) {
- final int shapeType = random().nextInt(4);
- switch (shapeType) {
- case 0: {
- // Polygons
- final int vertexCount = random().nextInt(3) + 3;
- final List<GeoPoint> geoPoints = new ArrayList<>();
- while (geoPoints.size() < vertexCount) {
- final GeoPoint gPt = new GeoPoint(planetModel, toRadians(randomLat()), toRadians(randomLon()));
- geoPoints.add(gPt);
- }
- final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
- try {
- return GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints, convexPointIndex);
- } catch (IllegalArgumentException e) {
- // This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where
- // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
- continue;
- }
- }
-
- case 1: {
- // Circles
-
- double lat = toRadians(randomLat());
- double lon = toRadians(randomLon());
-
- double angle;
- if (smallBBox) {
- angle = random().nextDouble() * Math.PI/360.0;
- } else {
- angle = random().nextDouble() * Math.PI/2.0;
- }
-
- try {
- return GeoCircleFactory.makeGeoCircle(planetModel, lat, lon, angle);
- } catch (IllegalArgumentException iae) {
- // angle is too small; try again:
- continue;
- }
- }
-
- case 2: {
- // Rectangles
- double lat0 = toRadians(randomLat());
- double lat1 = toRadians(randomLat());
- if (lat1 < lat0) {
- double x = lat0;
- lat0 = lat1;
- lat1 = x;
- }
- double lon0 = toRadians(randomLon());
- double lon1 = toRadians(randomLon());
- if (lon1 < lon0) {
- double x = lon0;
- lon0 = lon1;
- lon1 = x;
- }
-
- return GeoBBoxFactory.makeGeoBBox(planetModel, lat1, lat0, lon0, lon1);
- }
-
- case 3: {
- // Paths
- final int pointCount = random().nextInt(5) + 1;
- final double width = toRadians(random().nextInt(89)+1);
- try {
- final GeoPath path = new GeoPath(planetModel, width);
- for (int i = 0; i < pointCount; i++) {
- path.addPoint(toRadians(randomLat()), toRadians(randomLon()));
- }
- path.done();
- return path;
- } catch (IllegalArgumentException e) {
- // This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where
- // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
- continue;
- }
- }
-
- default:
- throw new IllegalStateException("Unexpected shape type");
- }
- }
- }
-
- private static void verify(double[] lats, double[] lons) throws Exception {
- IndexWriterConfig iwc = newIndexWriterConfig();
-
- // Else we can get O(N^2) merging:
- int mbd = iwc.getMaxBufferedDocs();
- if (mbd != -1 && mbd < lats.length/100) {
- iwc.setMaxBufferedDocs(lats.length/100);
- }
- iwc.setCodec(getCodec());
- Directory dir;
- if (lats.length > 100000) {
- dir = newFSDirectory(createTempDir("TestBKDTree"));
- } else {
- dir = getDirectory();
- }
- Set<Integer> deleted = new HashSet<>();
- // RandomIndexWriter is too slow here:
- IndexWriter w = new IndexWriter(dir, iwc);
- for(int id=0;id<lats.length;id++) {
- Document doc = new Document();
- doc.add(newStringField("id", ""+id, Field.Store.NO));
- doc.add(new NumericDocValuesField("id", id));
- if (Double.isNaN(lats[id]) == false) {
- doc.add(new Geo3DPoint("point", lats[id], lons[id]));
- }
- w.addDocument(doc);
- if (id > 0 && random().nextInt(100) == 42) {
- int idToDelete = random().nextInt(id);
- w.deleteDocuments(new Term("id", ""+idToDelete));
- deleted.add(idToDelete);
- if (VERBOSE) {
- System.err.println(" delete id=" + idToDelete);
- }
- }
- }
- if (random().nextBoolean()) {
- w.forceMerge(1);
- }
- final IndexReader r = DirectoryReader.open(w);
- w.close();
-
- // We can't wrap with "exotic" readers because the geo3d query must see the Geo3DDVFormat:
- IndexSearcher s = newSearcher(r, false);
-
- int numThreads = TestUtil.nextInt(random(), 2, 5);
-
- List<Thread> threads = new ArrayList<>();
- final int iters = atLeast(100);
-
- final CountDownLatch startingGun = new CountDownLatch(1);
- final AtomicBoolean failed = new AtomicBoolean();
-
- for(int i=0;i<numThreads;i++) {
- Thread thread = new Thread() {
- @Override
- public void run() {
- try {
- _run();
- } catch (Exception e) {
- failed.set(true);
- throw new RuntimeException(e);
- }
- }
-
- private void _run() throws Exception {
- startingGun.await();
-
- NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id");
-
- for (int iter=0;iter<iters && failed.get() == false;iter++) {
-
- GeoShape shape = randomShape(PlanetModel.WGS84);
-
- if (VERBOSE) {
- System.err.println("\n" + Thread.currentThread() + ": TEST: iter=" + iter + " shape="+shape);
- }
-
- Query query = Geo3DPoint.newShapeQuery("point", shape);
-
- if (VERBOSE) {
- System.err.println(" using query: " + query);
- }
-
- final FixedBitSet hits = new FixedBitSet(r.maxDoc());
-
- s.search(query, new SimpleCollector() {
-
- private int docBase;
-
- @Override
- public boolean needsScores() {
- return false;
- }
-
- @Override
- protected void doSetNextReader(LeafReaderContext context) throws IOException {
- docBase = context.docBase;
- }
-
- @Override
- public void collect(int doc) {
- hits.set(docBase+doc);
- }
- });
-
- if (VERBOSE) {
- System.err.println(" hitCount: " + hits.cardinality());
- }
-
- for(int docID=0;docID<r.maxDoc();docID++) {
- int id = (int) docIDToID.get(docID);
- if (Double.isNaN(lats[id]) == false) {
-
- // Accurate point:
- GeoPoint point1 = new GeoPoint(PlanetModel.WGS84, lats[id], lons[id]);
-
- // Quantized point (32 bits per dim):
- GeoPoint point2 = quantize(PlanetModel.WGS84.getMaximumMagnitude(), point1);
-
- if (shape.isWithin(point1) != shape.isWithin(point2)) {
- if (VERBOSE) {
- System.out.println(" skip checking docID=" + docID + " quantization changed the expected result from " + shape.isWithin(point1) + " to " + shape.isWithin(point2));
- }
- continue;
- }
-
- boolean expected = ((deleted.contains(id) == false) && shape.isWithin(point2));
- if (hits.get(docID) != expected) {
- fail(Thread.currentThread().getName() + ": iter=" + iter + " id=" + id + " docID=" + docID + " lat=" + lats[id] + " lon=" + lons[id] + " expected " + expected + " but got: " + hits.get(docID) + " deleted?=" + deleted.contains(id) + "\n point1=" + point1 + ", iswithin="+shape.isWithin(point1)+"\n point2=" + point2 + ", iswithin="+shape.isWithin(point2) + "\n query=" + query);
- }
- } else {
- assertFalse(hits.get(docID));
- }
-
- }
- }
- }
- };
- thread.setName("T" + i);
- thread.start();
- threads.add(thread);
- }
- startingGun.countDown();
- for(Thread thread : threads) {
- thread.join();
- }
- IOUtils.close(r, dir);
- }
-
- public void testToString() {
- Geo3DPoint point = new Geo3DPoint("point", toRadians(44.244272), toRadians(7.769736));
- assertEquals("Geo3DPoint <point: x=0.9248467864160119 y=0.06280434265368656 z=0.37682349005486243>", point.toString());
- }
-
- public void testShapeQueryToString() {
- assertEquals("PointInGeo3DShapeQuery: field=point: Shape: GeoStandardCircle: {planetmodel=PlanetModel.WGS84, center=[lat=0.3861041107739683, lon=0.06780373760536706], radius=0.1(5.729577951308232)}",
- Geo3DPoint.newShapeQuery("point", GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, toRadians(44.244272), toRadians(7.769736), 0.1)).toString());
- }
-
- private static Directory getDirectory() {
- return newDirectory();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/geo3d/XYZSolidTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/XYZSolidTest.java b/lucene/spatial3d/src/test/org/apache/lucene/geo3d/XYZSolidTest.java
deleted file mode 100644
index 876a525..0000000
--- a/lucene/spatial3d/src/test/org/apache/lucene/geo3d/XYZSolidTest.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.geo3d;
-
-import org.apache.lucene.util.LuceneTestCase;
-import org.junit.Test;
-
-public class XYZSolidTest extends LuceneTestCase {
-
- @Test
- public void testNonDegenerateRelationships() {
- XYZSolid s;
- GeoShape shape;
- // Something bigger than the world
- s = new StandardXYZSolid(PlanetModel.SPHERE, -2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
- // Any shape, except whole world, should be within.
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.WITHIN, s.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- // An XYZSolid represents a surface shape, which when larger than the world is in fact
- // the entire world, so it should overlap the world.
- assertEquals(GeoArea.OVERLAPS, s.getRelationship(shape));
-
- // Something overlapping the world on only one side
- s = new StandardXYZSolid(PlanetModel.SPHERE, -2.0, 0.0, -2.0, 2.0, -2.0, 2.0);
- // Some things should be disjoint...
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
- // And, some things should be within...
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
- assertEquals(GeoArea.WITHIN, s.getRelationship(shape));
- // And, some things should overlap.
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.OVERLAPS, s.getRelationship(shape));
-
- // Partial world should be contained by GeoWorld object...
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, s.getRelationship(shape));
-
- // Something inside the world
- s = new StandardXYZSolid(PlanetModel.SPHERE, -0.1, 0.1, -0.1, 0.1, -0.1, 0.1);
- // All shapes should be disjoint
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
-
- }
-
- @Test
- public void testDegenerateRelationships() {
- GeoArea solid;
- GeoShape shape;
-
- // Basic test of the factory method - non-degenerate
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, -2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
- // Any shape, except whole world, should be within.
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.WITHIN, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- // An XYZSolid represents a surface shape, which when larger than the world is in fact
- // the entire world, so it should overlap the world.
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
-
- // Build a degenerate point, not on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
- // disjoint with everything?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a degenerate point that IS on the sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0);
- // inside everything that it touches?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape degenerate in (x,y), which has no points on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -0.1, 0.1);
- // disjoint with everything?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape degenerate in (x,y) which has one point on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -0.1, 1.1);
- // inside everything that it touches?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape degenerate in (x,y) which has two points on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -1.1, 1.1);
- // inside everything that it touches?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
-
- // Build a shape degenerate in (x,z), which has no points on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, 0.0, 0.0);
- // disjoint with everything?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape degenerate in (x,z) which has one point on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 1.1, 0.0, 0.0);
- // inside everything that it touches?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape degenerate in (x,y) which has two points on sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -1.1, 1.1, 0.0, 0.0);
- // inside everything that it touches?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
-
- // MHL for y-z check
-
- // Build a shape that is degenerate in x, which has zero points intersecting sphere
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, -0.1, 0.1);
- // disjoint with everything?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape that is degenerate in x, which has zero points intersecting sphere, second variation
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, 1.1, 1.2);
- // disjoint with everything?
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
-
- // Build a shape that is disjoint in X but intersects sphere in a complete circle
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -1.1, 1.1, -1.1, 1.1);
- // inside everything that it touches?
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
-
- // Build a shape that is disjoint in X but intersects sphere in a half circle in Y
- solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 1.1, -1.1, 1.1);
- // inside everything that it touches?
- shape = new GeoWorld(PlanetModel.SPHERE);
- assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
- assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
- shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
- assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
-
- // MHL for degenerate Y
- // MHL for degenerate Z
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
new file mode 100644
index 0000000..a4d8ed1
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
@@ -0,0 +1,810 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.FilterCodec;
+import org.apache.lucene.codecs.PointsFormat;
+import org.apache.lucene.codecs.PointsReader;
+import org.apache.lucene.codecs.PointsWriter;
+import org.apache.lucene.codecs.lucene60.Lucene60PointsReader;
+import org.apache.lucene.codecs.lucene60.Lucene60PointsWriter;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.spatial3d.geom.GeoArea;
+import org.apache.lucene.spatial3d.geom.GeoAreaFactory;
+import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
+import org.apache.lucene.spatial3d.geom.GeoCircleFactory;
+import org.apache.lucene.spatial3d.geom.GeoPath;
+import org.apache.lucene.spatial3d.geom.GeoPoint;
+import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
+import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.PlanetModel;
+import org.apache.lucene.spatial3d.geom.XYZBounds;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.SegmentReadState;
+import org.apache.lucene.index.SegmentWriteState;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.SimpleCollector;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.FixedBitSet;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+import org.junit.BeforeClass;
+
+import com.carrotsearch.randomizedtesting.generators.RandomInts;
+
+public class TestGeo3DPoint extends LuceneTestCase {
+
+ private static boolean smallBBox;
+
+ @BeforeClass
+ public static void beforeClass() {
+ smallBBox = random().nextBoolean();
+ if (VERBOSE) {
+ System.err.println("TEST: smallBBox=" + smallBBox);
+ }
+ }
+
+ private static Codec getCodec() {
+ if (Codec.getDefault().getName().equals("Lucene60")) {
+ int maxPointsInLeafNode = TestUtil.nextInt(random(), 16, 2048);
+ double maxMBSortInHeap = 3.0 + (3*random().nextDouble());
+ if (VERBOSE) {
+ System.out.println("TEST: using Lucene60PointsFormat with maxPointsInLeafNode=" + maxPointsInLeafNode + " and maxMBSortInHeap=" + maxMBSortInHeap);
+ }
+
+ return new FilterCodec("Lucene60", Codec.getDefault()) {
+ @Override
+ public PointsFormat pointsFormat() {
+ return new PointsFormat() {
+ @Override
+ public PointsWriter fieldsWriter(SegmentWriteState writeState) throws IOException {
+ return new Lucene60PointsWriter(writeState, maxPointsInLeafNode, maxMBSortInHeap);
+ }
+
+ @Override
+ public PointsReader fieldsReader(SegmentReadState readState) throws IOException {
+ return new Lucene60PointsReader(readState);
+ }
+ };
+ }
+ };
+ } else {
+ return Codec.getDefault();
+ }
+ }
+
+ public void testBasic() throws Exception {
+ Directory dir = getDirectory();
+ IndexWriterConfig iwc = newIndexWriterConfig();
+ iwc.setCodec(getCodec());
+ IndexWriter w = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ doc.add(new Geo3DPoint("field", toRadians(50.7345267), toRadians(-97.5303555)));
+ w.addDocument(doc);
+ IndexReader r = DirectoryReader.open(w);
+ // We can't wrap with "exotic" readers because the query must see the BKD3DDVFormat:
+ IndexSearcher s = newSearcher(r, false);
+ assertEquals(1, s.search(Geo3DPoint.newShapeQuery("field",
+ GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, toRadians(50), toRadians(-97), Math.PI/180.)), 1).totalHits);
+ w.close();
+ r.close();
+ dir.close();
+ }
+
+ private static double toRadians(double degrees) {
+ return Math.PI*(degrees/360.0);
+ }
+
+ private static PlanetModel getPlanetModel() {
+ if (random().nextBoolean()) {
+ // Use one of the earth models:
+ if (random().nextBoolean()) {
+ return PlanetModel.WGS84;
+ } else {
+ return PlanetModel.SPHERE;
+ }
+ } else {
+ // Make a randomly squashed planet:
+ double oblateness = random().nextDouble() * 0.5 - 0.25;
+ return new PlanetModel(1.0 + oblateness, 1.0 - oblateness);
+ }
+ }
+
+ private static class Cell {
+ static int nextCellID;
+
+ final Cell parent;
+ final int cellID;
+ final int xMinEnc, xMaxEnc;
+ final int yMinEnc, yMaxEnc;
+ final int zMinEnc, zMaxEnc;
+ final int splitCount;
+
+ public Cell(Cell parent,
+ int xMinEnc, int xMaxEnc,
+ int yMinEnc, int yMaxEnc,
+ int zMinEnc, int zMaxEnc,
+ int splitCount) {
+ this.parent = parent;
+ this.xMinEnc = xMinEnc;
+ this.xMaxEnc = xMaxEnc;
+ this.yMinEnc = yMinEnc;
+ this.yMaxEnc = yMaxEnc;
+ this.zMinEnc = zMinEnc;
+ this.zMaxEnc = zMaxEnc;
+ this.cellID = nextCellID++;
+ this.splitCount = splitCount;
+ }
+
+ /** Returns true if the quantized point lies within this cell, inclusive on all bounds. */
+ public boolean contains(double planetMax, GeoPoint point) {
+ int docX = Geo3DUtil.encodeValue(planetMax, point.x);
+ int docY = Geo3DUtil.encodeValue(planetMax, point.y);
+ int docZ = Geo3DUtil.encodeValue(planetMax, point.z);
+
+ return docX >= xMinEnc && docX <= xMaxEnc &&
+ docY >= yMinEnc && docY <= yMaxEnc &&
+ docZ >= zMinEnc && docZ <= zMaxEnc;
+ }
+
+ @Override
+ public String toString() {
+ return "cell=" + cellID + (parent == null ? "" : " parentCellID=" + parent.cellID) + " x: " + xMinEnc + " TO " + xMaxEnc + ", y: " + yMinEnc + " TO " + yMaxEnc + ", z: " + zMinEnc + " TO " + zMaxEnc + ", splits: " + splitCount;
+ }
+ }
+
+ private static GeoPoint quantize(double planetMax, GeoPoint point) {
+ return new GeoPoint(Geo3DUtil.decodeValueCenter(planetMax, Geo3DUtil.encodeValue(planetMax, point.x)),
+ Geo3DUtil.decodeValueCenter(planetMax, Geo3DUtil.encodeValue(planetMax, point.y)),
+ Geo3DUtil.decodeValueCenter(planetMax, Geo3DUtil.encodeValue(planetMax, point.z)));
+ }
+
+ /** Tests consistency of GeoArea.getRelationship vs GeoShape.isWithin */
+ public void testGeo3DRelations() throws Exception {
+
+ PlanetModel planetModel = getPlanetModel();
+
+ int numDocs = atLeast(1000);
+ if (VERBOSE) {
+ System.out.println("TEST: " + numDocs + " docs");
+ }
+
+ GeoPoint[] docs = new GeoPoint[numDocs];
+ for(int docID=0;docID<numDocs;docID++) {
+ docs[docID] = new GeoPoint(planetModel, toRadians(randomLat()), toRadians(randomLon()));
+ if (VERBOSE) {
+ System.out.println(" doc=" + docID + ": " + docs[docID]);
+ }
+ }
+
+ double planetMax = planetModel.getMaximumMagnitude();
+
+ int iters = atLeast(10);
+
+ int recurseDepth = RandomInts.randomIntBetween(random(), 5, 15);
+
+ iters = atLeast(50);
+
+ for(int iter=0;iter<iters;iter++) {
+ GeoShape shape = randomShape(planetModel);
+
+ StringWriter sw = new StringWriter();
+ PrintWriter log = new PrintWriter(sw, true);
+
+ if (VERBOSE) {
+ log.println("TEST: iter=" + iter + " shape=" + shape);
+ }
+
+ XYZBounds bounds = new XYZBounds();
+ shape.getBounds(bounds);
+
+ // Start with the root cell that fully contains the shape:
+ Cell root = new Cell(null,
+ Geo3DUtil.encodeValueLenient(planetMax, bounds.getMinimumX()),
+ Geo3DUtil.encodeValueLenient(planetMax, bounds.getMaximumX()),
+ Geo3DUtil.encodeValueLenient(planetMax, bounds.getMinimumY()),
+ Geo3DUtil.encodeValueLenient(planetMax, bounds.getMaximumY()),
+ Geo3DUtil.encodeValueLenient(planetMax, bounds.getMinimumZ()),
+ Geo3DUtil.encodeValueLenient(planetMax, bounds.getMaximumZ()),
+ 0);
+
+ if (VERBOSE) {
+ log.println(" root cell: " + root);
+ }
+
+ List<Cell> queue = new ArrayList<>();
+ queue.add(root);
+ Set<Integer> hits = new HashSet<>();
+
+ while (queue.size() > 0) {
+ Cell cell = queue.get(queue.size()-1);
+ queue.remove(queue.size()-1);
+ if (VERBOSE) {
+ log.println(" cycle: " + cell + " queue.size()=" + queue.size());
+ }
+
+ if (random().nextInt(10) == 7 || cell.splitCount > recurseDepth) {
+ if (VERBOSE) {
+ log.println(" leaf");
+ }
+ // Leaf cell: brute force check all docs that fall within this cell:
+ for(int docID=0;docID<numDocs;docID++) {
+ GeoPoint point = docs[docID];
+ if (cell.contains(planetMax, point)) {
+ if (shape.isWithin(quantize(planetMax, point))) {
+ if (VERBOSE) {
+ log.println(" check doc=" + docID + ": match!");
+ }
+ hits.add(docID);
+ } else {
+ if (VERBOSE) {
+ log.println(" check doc=" + docID + ": no match");
+ }
+ }
+ }
+ }
+ } else {
+
+ GeoArea xyzSolid = GeoAreaFactory.makeGeoArea(planetModel,
+ Geo3DUtil.decodeValueMin(planetMax, cell.xMinEnc), Geo3DUtil.decodeValueMax(planetMax, cell.xMaxEnc),
+ Geo3DUtil.decodeValueMin(planetMax, cell.yMinEnc), Geo3DUtil.decodeValueMax(planetMax, cell.yMaxEnc),
+ Geo3DUtil.decodeValueMin(planetMax, cell.zMinEnc), Geo3DUtil.decodeValueMax(planetMax, cell.zMaxEnc));
+
+ if (VERBOSE) {
+ log.println(" minx="+Geo3DUtil.decodeValueMin(planetMax, cell.xMinEnc)+" maxx="+Geo3DUtil.decodeValueMax(planetMax, cell.xMaxEnc)+
+ " miny="+Geo3DUtil.decodeValueMin(planetMax, cell.yMinEnc)+" maxy="+Geo3DUtil.decodeValueMax(planetMax, cell.yMaxEnc)+
+ " minz="+Geo3DUtil.decodeValueMin(planetMax, cell.zMinEnc)+" maxz="+Geo3DUtil.decodeValueMax(planetMax, cell.zMaxEnc));
+ }
+
+ switch (xyzSolid.getRelationship(shape)) {
+ case GeoArea.CONTAINS:
+ // Shape fully contains the cell: blindly add all docs in this cell:
+ if (VERBOSE) {
+ log.println(" GeoArea.CONTAINS: now addAll");
+ }
+ for(int docID=0;docID<numDocs;docID++) {
+ if (cell.contains(planetMax, docs[docID])) {
+ if (VERBOSE) {
+ log.println(" addAll doc=" + docID);
+ }
+ hits.add(docID);
+ }
+ }
+ continue;
+ case GeoArea.OVERLAPS:
+ if (VERBOSE) {
+ log.println(" GeoArea.OVERLAPS: keep splitting");
+ }
+ // They do overlap but neither contains the other:
+ //log.println(" crosses1");
+ break;
+ case GeoArea.WITHIN:
+ if (VERBOSE) {
+ log.println(" GeoArea.WITHIN: keep splitting");
+ }
+ // Cell fully contains the shape:
+ //log.println(" crosses2");
+ break;
+ case GeoArea.DISJOINT:
+ // They do not overlap at all: don't recurse on this cell
+ //log.println(" outside");
+ if (VERBOSE) {
+ log.println(" GeoArea.DISJOINT: drop this cell");
+ for(int docID=0;docID<numDocs;docID++) {
+ if (cell.contains(planetMax, docs[docID])) {
+ if (VERBOSE) {
+ log.println(" skip doc=" + docID);
+ }
+ }
+ }
+ }
+ continue;
+ default:
+ assert false;
+ }
+
+ // Randomly split:
+ switch(random().nextInt(3)) {
+
+ case 0:
+ // Split on X:
+ {
+ int splitValue = RandomInts.randomIntBetween(random(), cell.xMinEnc, cell.xMaxEnc);
+ if (VERBOSE) {
+ log.println(" now split on x=" + splitValue);
+ }
+ Cell cell1 = new Cell(cell,
+ cell.xMinEnc, splitValue,
+ cell.yMinEnc, cell.yMaxEnc,
+ cell.zMinEnc, cell.zMaxEnc,
+ cell.splitCount+1);
+ Cell cell2 = new Cell(cell,
+ splitValue, cell.xMaxEnc,
+ cell.yMinEnc, cell.yMaxEnc,
+ cell.zMinEnc, cell.zMaxEnc,
+ cell.splitCount+1);
+ if (VERBOSE) {
+ log.println(" split cell1: " + cell1);
+ log.println(" split cell2: " + cell2);
+ }
+ queue.add(cell1);
+ queue.add(cell2);
+ }
+ break;
+
+ case 1:
+ // Split on Y:
+ {
+ int splitValue = RandomInts.randomIntBetween(random(), cell.yMinEnc, cell.yMaxEnc);
+ if (VERBOSE) {
+ log.println(" now split on y=" + splitValue);
+ }
+ Cell cell1 = new Cell(cell,
+ cell.xMinEnc, cell.xMaxEnc,
+ cell.yMinEnc, splitValue,
+ cell.zMinEnc, cell.zMaxEnc,
+ cell.splitCount+1);
+ Cell cell2 = new Cell(cell,
+ cell.xMinEnc, cell.xMaxEnc,
+ splitValue, cell.yMaxEnc,
+ cell.zMinEnc, cell.zMaxEnc,
+ cell.splitCount+1);
+ if (VERBOSE) {
+ log.println(" split cell1: " + cell1);
+ log.println(" split cell2: " + cell2);
+ }
+ queue.add(cell1);
+ queue.add(cell2);
+ }
+ break;
+
+ case 2:
+ // Split on Z:
+ {
+ int splitValue = RandomInts.randomIntBetween(random(), cell.zMinEnc, cell.zMaxEnc);
+ if (VERBOSE) {
+ log.println(" now split on z=" + splitValue);
+ }
+ Cell cell1 = new Cell(cell,
+ cell.xMinEnc, cell.xMaxEnc,
+ cell.yMinEnc, cell.yMaxEnc,
+ cell.zMinEnc, splitValue,
+ cell.splitCount+1);
+ Cell cell2 = new Cell(cell,
+ cell.xMinEnc, cell.xMaxEnc,
+ cell.yMinEnc, cell.yMaxEnc,
+ splitValue, cell.zMaxEnc,
+ cell.splitCount+1);
+ if (VERBOSE) {
+ log.println(" split cell1: " + cell1);
+ log.println(" split cell2: " + cell2);
+ }
+ queue.add(cell1);
+ queue.add(cell2);
+ }
+ break;
+ }
+ }
+ }
+
+ if (VERBOSE) {
+ log.println(" " + hits.size() + " hits");
+ }
+
+ // Done matching, now verify:
+ boolean fail = false;
+ for(int docID=0;docID<numDocs;docID++) {
+ GeoPoint point = docs[docID];
+ GeoPoint quantized = quantize(planetMax, point);
+ boolean expected = shape.isWithin(quantized);
+
+ if (expected != shape.isWithin(point)) {
+ // Quantization changed the result; skip testing this doc:
+ continue;
+ }
+
+ boolean actual = hits.contains(docID);
+ if (actual != expected) {
+ if (actual) {
+ log.println("doc=" + docID + " matched but should not");
+ } else {
+ log.println("doc=" + docID + " did not match but should");
+ }
+ log.println(" point=" + docs[docID]);
+ log.println(" quantized=" + quantize(planetMax, docs[docID]));
+ fail = true;
+ }
+ }
+
+ if (fail) {
+ System.out.print(sw.toString());
+ fail("invalid hits for shape=" + shape);
+ }
+ }
+ }
+
+ public void testRandomTiny() throws Exception {
+ // Make sure single-leaf-node case is OK:
+ doTestRandom(10);
+ }
+
+ public void testRandomMedium() throws Exception {
+ doTestRandom(10000);
+ }
+
+ @Nightly
+ public void testRandomBig() throws Exception {
+ doTestRandom(200000);
+ }
+
+ private void doTestRandom(int count) throws Exception {
+ int numPoints = atLeast(count);
+
+ if (VERBOSE) {
+ System.err.println("TEST: numPoints=" + numPoints);
+ }
+
+ double[] lats = new double[numPoints];
+ double[] lons = new double[numPoints];
+
+ boolean haveRealDoc = false;
+
+ for (int docID=0;docID<numPoints;docID++) {
+ int x = random().nextInt(20);
+ if (x == 17) {
+ // Some docs don't have a point:
+ lats[docID] = Double.NaN;
+ if (VERBOSE) {
+ System.err.println(" doc=" + docID + " is missing");
+ }
+ continue;
+ }
+
+ if (docID > 0 && x < 3 && haveRealDoc) {
+ int oldDocID;
+ while (true) {
+ oldDocID = random().nextInt(docID);
+ if (Double.isNaN(lats[oldDocID]) == false) {
+ break;
+ }
+ }
+
+ if (x == 0) {
+ // Identical lat to old point
+ lats[docID] = lats[oldDocID];
+ lons[docID] = toRadians(randomLon());
+ if (VERBOSE) {
+ System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID] + " (same lat as doc=" + oldDocID + ")");
+ }
+ } else if (x == 1) {
+ // Identical lon to old point
+ lats[docID] = toRadians(randomLat());
+ lons[docID] = lons[oldDocID];
+ if (VERBOSE) {
+ System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID] + " (same lon as doc=" + oldDocID + ")");
+ }
+ } else {
+ assert x == 2;
+ // Fully identical point:
+ lats[docID] = lats[oldDocID];
+ lons[docID] = lons[oldDocID];
+ if (VERBOSE) {
+ System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID] + " (same lat/lon as doc=" + oldDocID + ")");
+ }
+ }
+ } else {
+ lats[docID] = toRadians(randomLat());
+ lons[docID] = toRadians(randomLon());
+ haveRealDoc = true;
+ if (VERBOSE) {
+ System.err.println(" doc=" + docID + " lat=" + lats[docID] + " lon=" + lons[docID]);
+ }
+ }
+ }
+
+ verify(lats, lons);
+ }
+
+ private static double randomLat() {
+ if (smallBBox) {
+ return 2.0 * (random().nextDouble()-0.5);
+ } else {
+ return -90 + 180.0 * random().nextDouble();
+ }
+ }
+
+ private static double randomLon() {
+ if (smallBBox) {
+ return 2.0 * (random().nextDouble()-0.5);
+ } else {
+ return -180 + 360.0 * random().nextDouble();
+ }
+ }
+
+ // Poached from Geo3dRptTest.randomShape:
+ private static GeoShape randomShape(PlanetModel planetModel) {
+ while (true) {
+ final int shapeType = random().nextInt(4);
+ switch (shapeType) {
+ case 0: {
+ // Polygons
+ final int vertexCount = random().nextInt(3) + 3;
+ final List<GeoPoint> geoPoints = new ArrayList<>();
+ while (geoPoints.size() < vertexCount) {
+ final GeoPoint gPt = new GeoPoint(planetModel, toRadians(randomLat()), toRadians(randomLon()));
+ geoPoints.add(gPt);
+ }
+ final int convexPointIndex = random().nextInt(vertexCount); //If we get this wrong, hopefully we get IllegalArgumentException
+ try {
+ return GeoPolygonFactory.makeGeoPolygon(planetModel, geoPoints, convexPointIndex);
+ } catch (IllegalArgumentException e) {
+ // This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where
+ // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+ continue;
+ }
+ }
+
+ case 1: {
+ // Circles
+
+ double lat = toRadians(randomLat());
+ double lon = toRadians(randomLon());
+
+ double angle;
+ if (smallBBox) {
+ angle = random().nextDouble() * Math.PI/360.0;
+ } else {
+ angle = random().nextDouble() * Math.PI/2.0;
+ }
+
+ try {
+ return GeoCircleFactory.makeGeoCircle(planetModel, lat, lon, angle);
+ } catch (IllegalArgumentException iae) {
+ // angle is too small; try again:
+ continue;
+ }
+ }
+
+ case 2: {
+ // Rectangles
+ double lat0 = toRadians(randomLat());
+ double lat1 = toRadians(randomLat());
+ if (lat1 < lat0) {
+ double x = lat0;
+ lat0 = lat1;
+ lat1 = x;
+ }
+ double lon0 = toRadians(randomLon());
+ double lon1 = toRadians(randomLon());
+ if (lon1 < lon0) {
+ double x = lon0;
+ lon0 = lon1;
+ lon1 = x;
+ }
+
+ return GeoBBoxFactory.makeGeoBBox(planetModel, lat1, lat0, lon0, lon1);
+ }
+
+ case 3: {
+ // Paths
+ final int pointCount = random().nextInt(5) + 1;
+ final double width = toRadians(random().nextInt(89)+1);
+ try {
+ final GeoPath path = new GeoPath(planetModel, width);
+ for (int i = 0; i < pointCount; i++) {
+ path.addPoint(toRadians(randomLat()), toRadians(randomLon()));
+ }
+ path.done();
+ return path;
+ } catch (IllegalArgumentException e) {
+ // This is what happens when we create a shape that is invalid. Although it is conceivable that there are cases where
+ // the exception is thrown incorrectly, we aren't going to be able to do that in this random test.
+ continue;
+ }
+ }
+
+ default:
+ throw new IllegalStateException("Unexpected shape type");
+ }
+ }
+ }
+
+ private static void verify(double[] lats, double[] lons) throws Exception {
+ IndexWriterConfig iwc = newIndexWriterConfig();
+
+ // Else we can get O(N^2) merging:
+ int mbd = iwc.getMaxBufferedDocs();
+ if (mbd != -1 && mbd < lats.length/100) {
+ iwc.setMaxBufferedDocs(lats.length/100);
+ }
+ iwc.setCodec(getCodec());
+ Directory dir;
+ if (lats.length > 100000) {
+ dir = newFSDirectory(createTempDir("TestBKDTree"));
+ } else {
+ dir = getDirectory();
+ }
+ Set<Integer> deleted = new HashSet<>();
+ // RandomIndexWriter is too slow here:
+ IndexWriter w = new IndexWriter(dir, iwc);
+ for(int id=0;id<lats.length;id++) {
+ Document doc = new Document();
+ doc.add(newStringField("id", ""+id, Field.Store.NO));
+ doc.add(new NumericDocValuesField("id", id));
+ if (Double.isNaN(lats[id]) == false) {
+ doc.add(new Geo3DPoint("point", lats[id], lons[id]));
+ }
+ w.addDocument(doc);
+ if (id > 0 && random().nextInt(100) == 42) {
+ int idToDelete = random().nextInt(id);
+ w.deleteDocuments(new Term("id", ""+idToDelete));
+ deleted.add(idToDelete);
+ if (VERBOSE) {
+ System.err.println(" delete id=" + idToDelete);
+ }
+ }
+ }
+ if (random().nextBoolean()) {
+ w.forceMerge(1);
+ }
+ final IndexReader r = DirectoryReader.open(w);
+ w.close();
+
+ // We can't wrap with "exotic" readers because the geo3d query must see the Geo3DDVFormat:
+ IndexSearcher s = newSearcher(r, false);
+
+ int numThreads = TestUtil.nextInt(random(), 2, 5);
+
+ List<Thread> threads = new ArrayList<>();
+ final int iters = atLeast(100);
+
+ final CountDownLatch startingGun = new CountDownLatch(1);
+ final AtomicBoolean failed = new AtomicBoolean();
+
+ for(int i=0;i<numThreads;i++) {
+ Thread thread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ _run();
+ } catch (Exception e) {
+ failed.set(true);
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void _run() throws Exception {
+ startingGun.await();
+
+ NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id");
+
+ for (int iter=0;iter<iters && failed.get() == false;iter++) {
+
+ GeoShape shape = randomShape(PlanetModel.WGS84);
+
+ if (VERBOSE) {
+ System.err.println("\n" + Thread.currentThread() + ": TEST: iter=" + iter + " shape="+shape);
+ }
+
+ Query query = Geo3DPoint.newShapeQuery("point", shape);
+
+ if (VERBOSE) {
+ System.err.println(" using query: " + query);
+ }
+
+ final FixedBitSet hits = new FixedBitSet(r.maxDoc());
+
+ s.search(query, new SimpleCollector() {
+
+ private int docBase;
+
+ @Override
+ public boolean needsScores() {
+ return false;
+ }
+
+ @Override
+ protected void doSetNextReader(LeafReaderContext context) throws IOException {
+ docBase = context.docBase;
+ }
+
+ @Override
+ public void collect(int doc) {
+ hits.set(docBase+doc);
+ }
+ });
+
+ if (VERBOSE) {
+ System.err.println(" hitCount: " + hits.cardinality());
+ }
+
+ for(int docID=0;docID<r.maxDoc();docID++) {
+ int id = (int) docIDToID.get(docID);
+ if (Double.isNaN(lats[id]) == false) {
+
+ // Accurate point:
+ GeoPoint point1 = new GeoPoint(PlanetModel.WGS84, lats[id], lons[id]);
+
+ // Quantized point (32 bits per dim):
+ GeoPoint point2 = quantize(PlanetModel.WGS84.getMaximumMagnitude(), point1);
+
+ if (shape.isWithin(point1) != shape.isWithin(point2)) {
+ if (VERBOSE) {
+ System.out.println(" skip checking docID=" + docID + " quantization changed the expected result from " + shape.isWithin(point1) + " to " + shape.isWithin(point2));
+ }
+ continue;
+ }
+
+ boolean expected = ((deleted.contains(id) == false) && shape.isWithin(point2));
+ if (hits.get(docID) != expected) {
+ fail(Thread.currentThread().getName() + ": iter=" + iter + " id=" + id + " docID=" + docID + " lat=" + lats[id] + " lon=" + lons[id] + " expected " + expected + " but got: " + hits.get(docID) + " deleted?=" + deleted.contains(id) + "\n point1=" + point1 + ", iswithin="+shape.isWithin(point1)+"\n point2=" + point2 + ", iswithin="+shape.isWithin(point2) + "\n query=" + query);
+ }
+ } else {
+ assertFalse(hits.get(docID));
+ }
+
+ }
+ }
+ }
+ };
+ thread.setName("T" + i);
+ thread.start();
+ threads.add(thread);
+ }
+ startingGun.countDown();
+ for(Thread thread : threads) {
+ thread.join();
+ }
+ IOUtils.close(r, dir);
+ }
+
+ public void testToString() {
+ Geo3DPoint point = new Geo3DPoint("point", toRadians(44.244272), toRadians(7.769736));
+ assertEquals("Geo3DPoint <point: x=0.9248467864160119 y=0.06280434265368656 z=0.37682349005486243>", point.toString());
+ }
+
+ public void testShapeQueryToString() {
+ assertEquals("PointInGeo3DShapeQuery: field=point: Shape: GeoStandardCircle: {planetmodel=PlanetModel.WGS84, center=[lat=0.3861041107739683, lon=0.06780373760536706], radius=0.1(5.729577951308232)}",
+ Geo3DPoint.newShapeQuery("point", GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, toRadians(44.244272), toRadians(7.769736), 0.1)).toString());
+ }
+
+ private static Directory getDirectory() {
+ return newDirectory();
+ }
+}
[14/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
new file mode 100755
index 0000000..1420c11
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoRectangle.java
@@ -0,0 +1,288 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box limited on four sides (top lat, bottom lat, left lon, right lon).
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * GeoWideRectangle.
+ *
+ * @lucene.internal
+ */
+public class GeoRectangle extends GeoBaseBBox {
+ /** The top latitude of the rect */
+ protected final double topLat;
+ /** The bottom latitude of the rect */
+ protected final double bottomLat;
+ /** The left longitude of the rect */
+ protected final double leftLon;
+ /** The right longitude of the rect */
+ protected final double rightLon;
+ /** The cosine of a middle latitude */
+ protected final double cosMiddleLat;
+
+ /** The upper left hand corner point */
+ protected final GeoPoint ULHC;
+ /** The upper right hand corner point */
+ protected final GeoPoint URHC;
+ /** The lower right hand corner point */
+ protected final GeoPoint LRHC;
+ /** The lower left hand corner point */
+ protected final GeoPoint LLHC;
+
+ /** The top plane */
+ protected final SidedPlane topPlane;
+ /** The bottom plane */
+ protected final SidedPlane bottomPlane;
+ /** The left plane */
+ protected final SidedPlane leftPlane;
+ /** The right plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for the top plane */
+ protected final GeoPoint[] topPlanePoints;
+ /** Notable points for the bottom plane */
+ protected final GeoPoint[] bottomPlanePoints;
+ /** Notable points for the left plane */
+ protected final GeoPoint[] leftPlanePoints;
+ /** Notable points for the right plane */
+ protected final GeoPoint[] rightPlanePoints;
+
+ /** Center point */
+ protected final GeoPoint centerPoint;
+
+ /** Edge point for this rectangle */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *@param planetModel is the planet model.
+ *@param topLat is the top latitude.
+ *@param bottomLat is the bottom latitude.
+ *@param leftLon is the left longitude.
+ *@param rightLon is the right longitude.
+ */
+ public GeoRectangle(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top latitude out of range");
+ if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (topLat < bottomLat)
+ throw new IllegalArgumentException("Top latitude less than bottom latitude");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent > Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too great");
+
+ this.topLat = topLat;
+ this.bottomLat = bottomLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ final double sinBottomLat = Math.sin(bottomLat);
+ final double cosBottomLat = Math.cos(bottomLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the four points
+ this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
+ this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
+ this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
+ this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
+
+ final double middleLat = (topLat + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+
+ this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+ this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
+ this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC, LLHC};
+ this.rightPlanePoints = new GeoPoint[]{URHC, LRHC};
+
+ this.edgePoints = new GeoPoint[]{ULHC};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = bottomLat - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z) &&
+ bottomPlane.isWithin(x, y, z) &&
+ leftPlane.isWithin(x, y, z) &&
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double topAngle = centerPoint.arcDistance(URHC);
+ final double bottomAngle = centerPoint.arcDistance(LLHC);
+ return Math.max(centerAngle, Math.max(topAngle, bottomAngle));
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, leftPlane, rightPlane) ||
+ p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, leftPlane, rightPlane) ||
+ p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane, bottomPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane, bottomPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.addHorizontalPlane(planetModel, topLat, topPlane, bottomPlane, leftPlane, rightPlane)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane, bottomPlane, leftPlane)
+ .addHorizontalPlane(planetModel, bottomLat, bottomPlane, topPlane, leftPlane, rightPlane)
+ .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane, bottomPlane, rightPlane)
+ .addPoint(ULHC).addPoint(URHC).addPoint(LLHC).addPoint(LRHC);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(ULHC);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane, topPlanePoints, bottomPlane, leftPlane, rightPlane) ||
+ path.intersects(bottomPlane, bottomPlanePoints, topPlane, leftPlane, rightPlane) ||
+ path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane, rightPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane, bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, leftPlane, rightPlane);
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, leftPlane, rightPlane);
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, topPlane, bottomPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ Math.min(topDistance, bottomDistance),
+ Math.min(leftDistance, rightDistance)),
+ Math.min(
+ Math.min(ULHCDistance, URHCDistance),
+ Math.min(LRHCDistance, LLHCDistance)));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoRectangle))
+ return false;
+ GeoRectangle other = (GeoRectangle) o;
+ return super.equals(other) && other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + ULHC.hashCode();
+ result = 31 * result + LRHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoShape.java
new file mode 100755
index 0000000..a2d3947
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoShape.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Generic shape. This describes methods that help GeoAreas figure out
+ * how they interact with a shape, for the purposes of coming up with a
+ * set of geo hash values.
+ *
+ * @lucene.experimental
+ */
+public interface GeoShape extends Membership {
+
+ /**
+ * Return a sample point that is on the outside edge/boundary of the shape.
+ *
+ * @return samples of all edge points from distinct edge sections. Typically one point
+ * is returned, but zero or two are also possible.
+ */
+ public GeoPoint[] getEdgePoints();
+
+ /**
+ * Assess whether a plane, within the provided bounds, intersects
+ * with the shape. Note well that this method is allowed to return "true"
+ * if there are internal edges of a composite shape which intersect the plane.
+ * Doing this can cause getRelationship() for most GeoBBox shapes to return
+ * OVERLAPS rather than the more correct CONTAINS, but that cannot be
+ * helped for some complex shapes that are built out of overlapping parts.
+ *
+ * @param plane is the plane to assess for intersection with the shape's edges or
+ * bounding curves.
+ * @param notablePoints represents the intersections of the plane with the supplied
+ * bounds. These are used to disambiguate when two planes are identical and it needs
+ * to be determined whether any points exist that fulfill all the bounds.
+ * @param bounds are a set of bounds that define an area that an
+ * intersection must be within in order to qualify (provided by a GeoArea).
+ * @return true if there's such an intersection, false if not.
+ */
+ public boolean intersects(final Plane plane, final GeoPoint[] notablePoints, final Membership... bounds);
+
+ /**
+ * Compute bounds for the shape.
+ *
+ * @param bounds is the input bounds object.
+ * The input object will be modified.
+ */
+ public void getBounds(final Bounds bounds);
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSizeable.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSizeable.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSizeable.java
new file mode 100755
index 0000000..3c7e2ef
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSizeable.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Some shapes can compute radii of a geocircle in which they are inscribed.
+ *
+ * @lucene.experimental
+ */
+public interface GeoSizeable {
+ /**
+ * Returns the radius of a circle into which the GeoSizeable area can
+ * be inscribed.
+ *
+ * @return the radius.
+ */
+ public double getRadius();
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ public GeoPoint getCenter();
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
new file mode 100644
index 0000000..a1d8967
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthLatitudeZone.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * This GeoBBox represents an area rectangle limited only in north latitude.
+ *
+ * @lucene.internal
+ */
+public class GeoSouthLatitudeZone extends GeoBaseBBox {
+ /** The top latitude of the zone */
+ protected final double topLat;
+ /** The cosine of the top latitude of the zone */
+ protected final double cosTopLat;
+ /** The top plane of the zone */
+ protected final SidedPlane topPlane;
+ /** An interior point of the zone */
+ protected final GeoPoint interiorPoint;
+ /** Notable points for the plane (none) */
+ protected final static GeoPoint[] planePoints = new GeoPoint[0];
+ /** A point on the top boundary */
+ protected final GeoPoint topBoundaryPoint;
+ /** Edge points; a reference to the topBoundaryPoint */
+ protected final GeoPoint[] edgePoints;
+
+ /** Constructor.
+ *@param planetModel is the planet model.
+ *@param topLat is the top latitude of the zone.
+ */
+ public GeoSouthLatitudeZone(final PlanetModel planetModel, final double topLat) {
+ super(planetModel);
+ this.topLat = topLat;
+
+ final double sinTopLat = Math.sin(topLat);
+ this.cosTopLat = Math.cos(topLat);
+
+ // Compute an interior point. Pick one whose lat is between top and bottom.
+ final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.interiorPoint = new GeoPoint(planetModel, sinMiddleLat, 0.0, Math.sqrt(1.0 - sinMiddleLat * sinMiddleLat), 1.0);
+ this.topBoundaryPoint = new GeoPoint(planetModel, sinTopLat, 0.0, Math.sqrt(1.0 - sinTopLat * sinTopLat), 1.0);
+
+ this.topPlane = new SidedPlane(interiorPoint, planetModel, sinTopLat);
+
+ this.edgePoints = new GeoPoint[]{topBoundaryPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, -Math.PI, Math.PI);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // This is a bit tricky. I guess we should interpret this as meaning the angle of a circle that
+ // would contain all the bounding box points, when starting in the "center".
+ if (topLat > 0.0)
+ return Math.PI;
+ double maxCosLat = cosTopLat;
+ return maxCosLat * Math.PI;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return interiorPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, topPlane, notablePoints, planePoints, bounds);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds
+ .addHorizontalPlane(planetModel, topLat, topPlane);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean insideShape = path.isWithin(topBoundaryPoint);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ // Second, the shortcut of seeing whether endpoints are in/out is not going to
+ // work with no area endpoints. So we rely entirely on intersections.
+
+ if (path.intersects(topPlane, planePoints))
+ return OVERLAPS;
+
+ // There is another case for latitude zones only. This is when the boundaries of the shape all fit
+ // within the zone, but the shape includes areas outside the zone crossing a pole.
+ // In this case, the above "overlaps" check is insufficient. We also need to check a point on either boundary
+ // whether it is within the shape. If both such points are within, then CONTAINS is the right answer. If
+ // one such point is within, then OVERLAPS is the right answer.
+
+ if (insideShape)
+ return CONTAINS;
+
+ if (insideRectangle == ALL_INSIDE)
+ return WITHIN;
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(planetModel, topPlane, x,y,z);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoSouthLatitudeZone))
+ return false;
+ GeoSouthLatitudeZone other = (GeoSouthLatitudeZone) o;
+ return super.equals(other) && other.topBoundaryPoint.equals(topBoundaryPoint);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + topBoundaryPoint.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoSouthLatitudeZone: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + ")}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
new file mode 100644
index 0000000..806535e
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoSouthRectangle.java
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box limited on three sides (top lat, left lon, right lon). The
+ * other corner is the south pole.
+ * The left-right maximum extent for this shape is PI; for anything larger, use
+ * {@link GeoWideSouthRectangle}.
+ *
+ * @lucene.internal
+ */
+public class GeoSouthRectangle extends GeoBaseBBox {
+ /** The top latitude of the rect */
+ protected final double topLat;
+ /** The left longitude of the rect */
+ protected final double leftLon;
+ /** The right longitude of the rect */
+ protected final double rightLon;
+ /** The cosine of a middle latitude */
+ protected final double cosMiddleLat;
+ /** The upper left hand corner of the rectangle */
+ protected final GeoPoint ULHC;
+ /** The upper right hand corner of the rectangle */
+ protected final GeoPoint URHC;
+
+ /** The top plane */
+ protected final SidedPlane topPlane;
+ /** The left plane */
+ protected final SidedPlane leftPlane;
+ /** The right plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for the top plane */
+ protected final GeoPoint[] topPlanePoints;
+ /** Notable points for the left plane */
+ protected final GeoPoint[] leftPlanePoints;
+ /** Notable points for the right plane */
+ protected final GeoPoint[] rightPlanePoints;
+
+ /** The center point */
+ protected final GeoPoint centerPoint;
+
+ /** A point on the edge */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}
+ *@param planetModel is the planet model.
+ *@param topLat is the top latitude.
+ *@param leftLon is the left longitude.
+ *@param rightLon is the right longitude.
+ */
+ public GeoSouthRectangle(final PlanetModel planetModel, final double topLat, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent > Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too great");
+
+ this.topLat = topLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the four points
+ this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
+ this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
+
+ final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+
+ this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC, planetModel.SOUTH_POLE};
+ this.rightPlanePoints = new GeoPoint[]{URHC, planetModel.SOUTH_POLE};
+
+ this.edgePoints = new GeoPoint[]{planetModel.SOUTH_POLE};
+
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z) &&
+ leftPlane.isWithin(x, y, z) &&
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double topAngle = centerPoint.arcDistance(URHC);
+ return Math.max(centerAngle, topAngle);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, leftPlane, rightPlane) ||
+ p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, rightPlane, topPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, leftPlane, topPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds
+ .addHorizontalPlane(planetModel, topLat, topPlane, leftPlane, rightPlane)
+ .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane, rightPlane)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane, leftPlane)
+ .addPoint(URHC).addPoint(ULHC).addPoint(planetModel.SOUTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" getrelationship with "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" inside of each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane, topPlanePoints, leftPlane, rightPlane) ||
+ path.intersects(leftPlane, leftPlanePoints, topPlane, rightPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, leftPlane, topPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" shape contains rectangle");
+ return CONTAINS;
+ }
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, leftPlane, rightPlane);
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, rightPlane, topPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, leftPlane, topPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ topDistance,
+ Math.min(leftDistance, rightDistance)),
+ Math.min(ULHCDistance, URHCDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoSouthRectangle))
+ return false;
+ GeoSouthRectangle other = (GeoSouthRectangle) o;
+ return super.equals(other) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + ULHC.hashCode();
+ result = 31 * result + URHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoSouthRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
new file mode 100755
index 0000000..bbf5046
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Circular area with a center and radius.
+ *
+ * @lucene.experimental
+ */
+public class GeoStandardCircle extends GeoBaseCircle {
+ /** Center of circle */
+ protected final GeoPoint center;
+ /** Cutoff angle of circle (not quite the same thing as radius) */
+ protected final double cutoffAngle;
+ /** The plane describing the circle (really an ellipse on a non-spherical world) */
+ protected final SidedPlane circlePlane;
+ /** A point that is on the world and on the circle plane */
+ protected final GeoPoint[] edgePoints;
+ /** Notable points for a circle -- there aren't any */
+ protected static final GeoPoint[] circlePoints = new GeoPoint[0];
+
+ /** Constructor.
+ *@param planetModel is the planet model.
+ *@param lat is the center latitude.
+ *@param lon is the center longitude.
+ *@param cutoffAngle is the cutoff angle for the circle.
+ */
+ public GeoStandardCircle(final PlanetModel planetModel, final double lat, final double lon, final double cutoffAngle) {
+ 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 || cutoffAngle > Math.PI)
+ throw new IllegalArgumentException("Cutoff angle out of bounds");
+ if (cutoffAngle < Vector.MINIMUM_RESOLUTION)
+ throw new IllegalArgumentException("Cutoff angle cannot be effectively zero");
+ this.center = new GeoPoint(planetModel, lat, lon);
+ // In an ellipsoidal world, cutoff distances make no sense, unfortunately. Only membership
+ // can be used to make in/out determination.
+ this.cutoffAngle = cutoffAngle;
+ // Compute two points on the circle, with the right angle from the center. We'll use these
+ // to obtain the perpendicular plane to the circle.
+ double upperLat = lat + cutoffAngle;
+ double upperLon = lon;
+ if (upperLat > Math.PI * 0.5) {
+ upperLon += Math.PI;
+ if (upperLon > Math.PI)
+ upperLon -= 2.0 * Math.PI;
+ upperLat = Math.PI - upperLat;
+ }
+ double lowerLat = lat - cutoffAngle;
+ double lowerLon = lon;
+ if (lowerLat < -Math.PI * 0.5) {
+ lowerLon += Math.PI;
+ if (lowerLon > Math.PI)
+ lowerLon -= 2.0 * Math.PI;
+ lowerLat = -Math.PI - lowerLat;
+ }
+ final GeoPoint upperPoint = new GeoPoint(planetModel, upperLat, upperLon);
+ final GeoPoint lowerPoint = new GeoPoint(planetModel, lowerLat, lowerLon);
+ if (Math.abs(cutoffAngle - Math.PI) < Vector.MINIMUM_RESOLUTION) {
+ // Circle is the whole world
+ this.circlePlane = null;
+ this.edgePoints = new GeoPoint[0];
+ } else {
+ // Construct normal plane
+ final Plane normalPlane = Plane.constructNormalizedZPlane(upperPoint, lowerPoint, center);
+ // Construct a sided plane that goes through the two points and whose normal is in the normalPlane.
+ this.circlePlane = SidedPlane.constructNormalizedPerpendicularSidedPlane(center, normalPlane, upperPoint, lowerPoint);
+ if (circlePlane == null)
+ throw new IllegalArgumentException("Couldn't construct circle plane, probably too small? Cutoff angle = "+cutoffAngle+"; upperPoint = "+upperPoint+"; lowerPoint = "+lowerPoint);
+ final GeoPoint recomputedIntersectionPoint = circlePlane.getSampleIntersectionPoint(planetModel, normalPlane);
+ if (recomputedIntersectionPoint == null)
+ throw new IllegalArgumentException("Couldn't construct intersection point, probably circle too small? Plane = "+circlePlane);
+ this.edgePoints = new GeoPoint[]{recomputedIntersectionPoint};
+ }
+ }
+
+ @Override
+ public double getRadius() {
+ return cutoffAngle;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return center;
+ }
+
+ @Override
+ protected double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(this.center, x, y, z);
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return distanceStyle.computeDistance(planetModel, circlePlane, x, y, z);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ if (circlePlane == null) {
+ return true;
+ }
+ // Fastest way of determining membership
+ return circlePlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ if (circlePlane == null) {
+ return false;
+ }
+ return circlePlane.intersects(planetModel, p, notablePoints, circlePoints, bounds);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ if (circlePlane == null) {
+ // Entire world; should already be covered
+ return;
+ }
+ bounds.addPoint(center);
+ bounds.addPlane(planetModel, circlePlane);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoStandardCircle))
+ return false;
+ GeoStandardCircle other = (GeoStandardCircle) o;
+ return super.equals(other) && other.center.equals(center) && other.cutoffAngle == cutoffAngle;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + center.hashCode();
+ long temp = Double.doubleToLongBits(cutoffAngle);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoStandardCircle: {planetmodel=" + planetModel+", center=" + center + ", radius=" + cutoffAngle + "(" + cutoffAngle * 180.0 / Math.PI + ")}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
new file mode 100644
index 0000000..48a73af
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideDegenerateHorizontalLine.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Degenerate bounding box wider than PI and limited on two sides (left lon, right lon).
+ *
+ * @lucene.internal
+ */
+public class GeoWideDegenerateHorizontalLine extends GeoBaseBBox {
+ /** The latitude of the line */
+ protected final double latitude;
+ /** The left longitude cutoff of the line */
+ protected final double leftLon;
+ /** The right longitude cutoff of the line */
+ protected final double rightLon;
+
+ /** The left end of the line */
+ protected final GeoPoint LHC;
+ /** The right end of the line */
+ protected final GeoPoint RHC;
+
+ /** The plane the line is in */
+ protected final Plane plane;
+ /** The left cutoff plane */
+ protected final SidedPlane leftPlane;
+ /** The right cutoff plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for the line */
+ protected final GeoPoint[] planePoints;
+
+ /** Center point for the line */
+ protected final GeoPoint centerPoint;
+
+ /** Left/right combination bound */
+ protected final EitherBound eitherBound;
+
+ /** A point on the line */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
+ * Horizontal angle must be greater than or equal to PI.
+ *@param planetModel is the planet model.
+ *@param latitude is the line latitude.
+ *@param leftLon is the left cutoff longitude.
+ *@param rightLon is the right cutoff longitude.
+ */
+ public GeoWideDegenerateHorizontalLine(final PlanetModel planetModel, final double latitude, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (latitude > Math.PI * 0.5 || latitude < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent < Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too small");
+
+ this.latitude = latitude;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinLatitude = Math.sin(latitude);
+ final double cosLatitude = Math.cos(latitude);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the two points
+ this.LHC = new GeoPoint(planetModel, sinLatitude, sinLeftLon, cosLatitude, cosLeftLon, latitude, leftLon);
+ this.RHC = new GeoPoint(planetModel, sinLatitude, sinRightLon, cosLatitude, cosRightLon, latitude, rightLon);
+
+ this.plane = new Plane(planetModel, sinLatitude);
+
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ double middleLon = (leftLon + rightLon) * 0.5;
+ double sinMiddleLon = Math.sin(middleLon);
+ double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinLatitude, sinMiddleLon, cosLatitude, cosMiddleLon);
+
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.planePoints = new GeoPoint[]{LHC, RHC};
+
+ this.eitherBound = new EitherBound();
+
+ this.edgePoints = new GeoPoint[]{centerPoint};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = latitude + angle;
+ final double newBottomLat = latitude - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return plane.evaluateIsZero(x, y, z) &&
+ (leftPlane.isWithin(x, y, z) ||
+ rightPlane.isWithin(x, y, z));
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double topAngle = centerPoint.arcDistance(RHC);
+ final double bottomAngle = centerPoint.arcDistance(LHC);
+ return Math.max(topAngle, bottomAngle);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return p.intersects(planetModel, plane, notablePoints, planePoints, bounds, eitherBound);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.isWide()
+ .addHorizontalPlane(planetModel, latitude, plane, eitherBound)
+ .addPoint(LHC)
+ .addPoint(RHC);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ if (path.intersects(plane, planePoints, eitherBound)) {
+ return OVERLAPS;
+ }
+
+ if (path.isWithin(centerPoint)) {
+ return CONTAINS;
+ }
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double distance = distanceStyle.computeDistance(planetModel, plane, x,y,z, eitherBound);
+
+ final double LHCDistance = distanceStyle.computeDistance(LHC, x,y,z);
+ final double RHCDistance = distanceStyle.computeDistance(RHC, x,y,z);
+
+ return Math.min(
+ distance,
+ Math.min(LHCDistance, RHCDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideDegenerateHorizontalLine))
+ return false;
+ GeoWideDegenerateHorizontalLine other = (GeoWideDegenerateHorizontalLine) o;
+ return super.equals(other) && other.LHC.equals(LHC) && other.RHC.equals(RHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + LHC.hashCode();
+ result = 31 * result + RHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideDegenerateHorizontalLine: {planetmodel="+planetModel+", latitude=" + latitude + "(" + latitude * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightLon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+
+ /** Membership implementation representing a wide cutoff (more than 180 degrees).
+ */
+ protected class EitherBound implements Membership {
+ /** Constructor.
+ */
+ public EitherBound() {
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
+ }
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
new file mode 100755
index 0000000..1d61876
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideLongitudeSlice.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box wider than PI but limited on left and right sides (
+ * left lon, right lon).
+ *
+ * @lucene.internal
+ */
+public class GeoWideLongitudeSlice extends GeoBaseBBox {
+ /** The left longitude */
+ protected final double leftLon;
+ /** The right longitude */
+ protected final double rightLon;
+
+ /** The left plane */
+ protected final SidedPlane leftPlane;
+ /** The right plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for the shape */
+ protected final GeoPoint[] planePoints;
+
+ /** Center point for the shape */
+ protected final GeoPoint centerPoint;
+
+ /** A point on the edge of the shape */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lon: {@code -PI -> PI}.
+ * Horizantal angle must be greater than or equal to PI.
+ *@param planetModel is the planet model.
+ *@param leftLon is the left longitude.
+ *@param rightLon is the right longitude.
+ */
+ public GeoWideLongitudeSlice(final PlanetModel planetModel, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent < Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too small");
+
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ this.centerPoint = new GeoPoint(planetModel, 0.0, middleLon);
+
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.planePoints = new GeoPoint[]{planetModel.NORTH_POLE, planetModel.SOUTH_POLE};
+ this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, Math.PI * 0.5, -Math.PI * 0.5, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) ||
+ rightPlane.isWithin(x, y, z);
+ }
+
+ @Override
+ public double getRadius() {
+ // Compute the extent and divide by two
+ double extent = rightLon - leftLon;
+ if (extent < 0.0)
+ extent += Math.PI * 2.0;
+ return Math.max(Math.PI * 0.5, extent * 0.5);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return p.intersects(planetModel, leftPlane, notablePoints, planePoints, bounds) ||
+ p.intersects(planetModel, rightPlane, notablePoints, planePoints, bounds);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.isWide()
+ .addVerticalPlane(planetModel, leftLon, leftPlane)
+ .addVerticalPlane(planetModel, rightLon, rightPlane)
+ .addPoint(planetModel.NORTH_POLE)
+ .addPoint(planetModel.SOUTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE)
+ return OVERLAPS;
+
+ final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape)
+ return OVERLAPS;
+
+ if (path.intersects(leftPlane, planePoints) ||
+ path.intersects(rightPlane, planePoints))
+ return OVERLAPS;
+
+ if (insideRectangle == ALL_INSIDE)
+ return WITHIN;
+
+ if (insideShape)
+ return CONTAINS;
+
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z);
+
+ final double northDistance = distanceStyle.computeDistance(planetModel.NORTH_POLE, x,y,z);
+ final double southDistance = distanceStyle.computeDistance(planetModel.SOUTH_POLE, x,y,z);
+
+ return Math.min(
+ Math.min(leftDistance, rightDistance),
+ Math.min(northDistance, southDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideLongitudeSlice))
+ return false;
+ GeoWideLongitudeSlice other = (GeoWideLongitudeSlice) o;
+ return super.equals(other) && other.leftLon == leftLon && other.rightLon == rightLon;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp = Double.doubleToLongBits(leftLon);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(rightLon);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideLongitudeSlice: {planetmodel="+planetModel+", leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
new file mode 100644
index 0000000..9f9dd49
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideNorthRectangle.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box wider than PI but limited on three sides (
+ * bottom lat, left lon, right lon).
+ *
+ * @lucene.internal
+ */
+public class GeoWideNorthRectangle extends GeoBaseBBox {
+ /** Bottom latitude */
+ protected final double bottomLat;
+ /** Left longitude */
+ protected final double leftLon;
+ /** Right longitude */
+ protected final double rightLon;
+
+ /** The cosine of the middle latitude */
+ protected final double cosMiddleLat;
+
+ /** The lower right hand corner point */
+ protected final GeoPoint LRHC;
+ /** The lower left hand corner point */
+ protected final GeoPoint LLHC;
+
+ /** The bottom plane */
+ protected final SidedPlane bottomPlane;
+ /** The left plane */
+ protected final SidedPlane leftPlane;
+ /** The right plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for the bottom plane */
+ protected final GeoPoint[] bottomPlanePoints;
+ /** Notable points for the left plane */
+ protected final GeoPoint[] leftPlanePoints;
+ /** Notable points for the right plane */
+ protected final GeoPoint[] rightPlanePoints;
+
+ /** Center point */
+ protected final GeoPoint centerPoint;
+
+ /** Composite left/right bounds */
+ protected final EitherBound eitherBound;
+
+ /** A point on the edge */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
+ * Horizontal angle must be greater than or equal to PI.
+ */
+ public GeoWideNorthRectangle(final PlanetModel planetModel, final double bottomLat, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent < Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too small");
+
+ this.bottomLat = bottomLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinBottomLat = Math.sin(bottomLat);
+ final double cosBottomLat = Math.cos(bottomLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the four points
+ this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
+ this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
+
+ final double middleLat = (Math.PI * 0.5 + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+
+ this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
+ this.leftPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LLHC};
+ this.rightPlanePoints = new GeoPoint[]{planetModel.NORTH_POLE, LRHC};
+
+ this.eitherBound = new EitherBound();
+ this.edgePoints = new GeoPoint[]{planetModel.NORTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = Math.PI * 0.5;
+ final double newBottomLat = bottomLat - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return
+ bottomPlane.isWithin(x, y, z) &&
+ (leftPlane.isWithin(x, y, z) ||
+ rightPlane.isWithin(x, y, z));
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double bottomAngle = centerPoint.arcDistance(LLHC);
+ return Math.max(centerAngle, bottomAngle);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return
+ p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, eitherBound) ||
+ p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, bottomPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, bottomPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.isWide()
+ .addHorizontalPlane(planetModel, bottomLat, bottomPlane, eitherBound)
+ .addVerticalPlane(planetModel, leftLon, leftPlane, bottomPlane)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, bottomPlane)
+ .addPoint(LLHC).addPoint(LRHC).addPoint(planetModel.NORTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" comparing to "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(planetModel.NORTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" both inside each other");
+ return OVERLAPS;
+ }
+
+ if (
+ path.intersects(bottomPlane, bottomPlanePoints, eitherBound) ||
+ path.intersects(leftPlane, leftPlanePoints, bottomPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" rectangle inside shape");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, eitherBound);
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, bottomPlane);
+
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ bottomDistance,
+ Math.min(leftDistance, rightDistance)),
+ Math.min(LRHCDistance, LLHCDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideNorthRectangle))
+ return false;
+ GeoWideNorthRectangle other = (GeoWideNorthRectangle) o;
+ return super.equals(other) && other.LLHC.equals(LLHC) && other.LRHC.equals(LRHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + LLHC.hashCode();
+ result = 31 * result + LRHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideNorthRectangle: {planetmodel="+planetModel+", bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+
+ /** Membership implementation representing a wide (more than 180 degree) bound.
+ */
+ protected class EitherBound implements Membership {
+ /** Constructor.
+ */
+ public EitherBound() {
+ }
+
+ @Override
+ public boolean isWithin(final Vector v) {
+ return leftPlane.isWithin(v) || rightPlane.isWithin(v);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
+ }
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
new file mode 100755
index 0000000..c561747
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideRectangle.java
@@ -0,0 +1,319 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box wider than PI but limited on four sides (top lat,
+ * bottom lat, left lon, right lon).
+ *
+ * @lucene.internal
+ */
+public class GeoWideRectangle extends GeoBaseBBox {
+ /** The top latitude */
+ protected final double topLat;
+ /** The bottom latitude */
+ protected final double bottomLat;
+ /** The left longitude */
+ protected final double leftLon;
+ /** The right longitude */
+ protected final double rightLon;
+
+ /** Cosine of the middle latitude */
+ protected final double cosMiddleLat;
+
+ /** Upper left hand corner point */
+ protected final GeoPoint ULHC;
+ /** Lower right hand corner point */
+ protected final GeoPoint URHC;
+ /** Lower right hand corner point */
+ protected final GeoPoint LRHC;
+ /** Lower left hand corner point */
+ protected final GeoPoint LLHC;
+
+ /** Top plane */
+ protected final SidedPlane topPlane;
+ /** Bottom plane */
+ protected final SidedPlane bottomPlane;
+ /** Left plane */
+ protected final SidedPlane leftPlane;
+ /** Right plane */
+ protected final SidedPlane rightPlane;
+
+ /** Top plane's notable points */
+ protected final GeoPoint[] topPlanePoints;
+ /** Bottom plane's notable points */
+ protected final GeoPoint[] bottomPlanePoints;
+ /** Left plane's notable points */
+ protected final GeoPoint[] leftPlanePoints;
+ /** Right plane's notable points */
+ protected final GeoPoint[] rightPlanePoints;
+
+ /** Center point */
+ protected final GeoPoint centerPoint;
+
+ /** Combined left/right bounds */
+ protected final EitherBound eitherBound;
+
+ /** A point on the edge */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
+ * Horizontal angle must be greater than or equal to PI.
+ */
+ public GeoWideRectangle(final PlanetModel planetModel, final double topLat, final double bottomLat, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top latitude out of range");
+ if (bottomLat > Math.PI * 0.5 || bottomLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Bottom latitude out of range");
+ if (topLat < bottomLat)
+ throw new IllegalArgumentException("Top latitude less than bottom latitude");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent < Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too small");
+
+ this.topLat = topLat;
+ this.bottomLat = bottomLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ final double sinBottomLat = Math.sin(bottomLat);
+ final double cosBottomLat = Math.cos(bottomLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the four points
+ this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
+ this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
+ this.LRHC = new GeoPoint(planetModel, sinBottomLat, sinRightLon, cosBottomLat, cosRightLon, bottomLat, rightLon);
+ this.LLHC = new GeoPoint(planetModel, sinBottomLat, sinLeftLon, cosBottomLat, cosLeftLon, bottomLat, leftLon);
+
+ final double middleLat = (topLat + bottomLat) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+
+ this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+ this.bottomPlane = new SidedPlane(centerPoint, planetModel, sinBottomLat);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
+ this.bottomPlanePoints = new GeoPoint[]{LLHC, LRHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC, LLHC};
+ this.rightPlanePoints = new GeoPoint[]{URHC, LRHC};
+
+ this.eitherBound = new EitherBound();
+
+ this.edgePoints = new GeoPoint[]{ULHC};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = bottomLat - angle;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z) &&
+ bottomPlane.isWithin(x, y, z) &&
+ (leftPlane.isWithin(x, y, z) ||
+ rightPlane.isWithin(x, y, z));
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double topAngle = centerPoint.arcDistance(URHC);
+ final double bottomAngle = centerPoint.arcDistance(LLHC);
+ return Math.max(centerAngle, Math.max(topAngle, bottomAngle));
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ /**
+ * Returns the center of a circle into which the area will be inscribed.
+ *
+ * @return the center.
+ */
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, bottomPlane, eitherBound) ||
+ p.intersects(planetModel, bottomPlane, notablePoints, bottomPlanePoints, bounds, topPlane, eitherBound) ||
+ p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, topPlane, bottomPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane, bottomPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.isWide()
+ .addHorizontalPlane(planetModel, topLat, topPlane, bottomPlane, eitherBound)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane, bottomPlane)
+ .addHorizontalPlane(planetModel, bottomLat, bottomPlane, topPlane, eitherBound)
+ .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane, bottomPlane)
+ .addPoint(ULHC).addPoint(URHC).addPoint(LRHC).addPoint(LLHC);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" comparing to "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(ULHC);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" both inside each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane, topPlanePoints, bottomPlane, eitherBound) ||
+ path.intersects(bottomPlane, bottomPlanePoints, topPlane, eitherBound) ||
+ path.intersects(leftPlane, leftPlanePoints, topPlane, bottomPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, topPlane, bottomPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" rectangle inside shape");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, bottomPlane, eitherBound);
+ final double bottomDistance = distanceStyle.computeDistance(planetModel, bottomPlane, x,y,z, topPlane, eitherBound);
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, topPlane, bottomPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, topPlane, bottomPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+ final double LRHCDistance = distanceStyle.computeDistance(LRHC, x,y,z);
+ final double LLHCDistance = distanceStyle.computeDistance(LLHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ Math.min(topDistance, bottomDistance),
+ Math.min(leftDistance, rightDistance)),
+ Math.min(
+ Math.min(ULHCDistance, URHCDistance),
+ Math.min(LRHCDistance, LLHCDistance)));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideRectangle))
+ return false;
+ GeoWideRectangle other = (GeoWideRectangle) o;
+ return super.equals(other) && other.ULHC.equals(ULHC) && other.LRHC.equals(LRHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + ULHC.hashCode();
+ result = 31 * result + LRHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideRectangle: {planetmodel=" + planetModel + ", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), bottomlat=" + bottomLat + "(" + bottomLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+
+ /** A membership implementation representing a wide (more than 180) left/right bound.
+ */
+ protected class EitherBound implements Membership {
+ /** Constructor.
+ */
+ public EitherBound() {
+ }
+
+ @Override
+ public boolean isWithin(final Vector v) {
+ return leftPlane.isWithin(v) || rightPlane.isWithin(v);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
+ }
+ }
+}
+
[40/50] [abbrv] lucene-solr git commit: SOLR-6926: fix
smokeTestRelease.py to stop calling ant example.
Posted by no...@apache.org.
SOLR-6926: fix smokeTestRelease.py to stop calling ant example.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/e490b329
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/e490b329
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/e490b329
Branch: refs/heads/apiv2
Commit: e490b329b3a6553720f3b422ce4422153baabad9
Parents: e3fcbfe
Author: David Smiley <ds...@apache.org>
Authored: Tue Mar 8 14:36:04 2016 -0500
Committer: David Smiley <ds...@apache.org>
Committed: Tue Mar 8 14:36:04 2016 -0500
----------------------------------------------------------------------
dev-tools/scripts/smokeTestRelease.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e490b329/dev-tools/scripts/smokeTestRelease.py
----------------------------------------------------------------------
diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py
index 87a772f..180599b 100644
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -700,7 +700,7 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
checkJavadocpathFull('%s/solr/build/docs' % unpackPath, False)
print(' test solr example w/ Java 8...')
- java.run_java8('ant clean example', '%s/antexample.log' % unpackPath)
+ java.run_java8('ant clean server', '%s/antexample.log' % unpackPath)
testSolrExample(unpackPath, java.java8_home, True)
os.chdir('..')
@@ -782,6 +782,7 @@ def readSolrOutput(p, startupEvent, failureEvent, logFile):
f.close()
def testSolrExample(unpackPath, javaPath, isSrc):
+ # test solr using some examples it comes with
logFile = '%s/solr-example.log' % unpackPath
if isSrc:
os.chdir(unpackPath+'/solr')
[41/50] [abbrv] lucene-solr git commit: SOLR-8793: Fix stale commit
files' size computation in LukeRequestHandler
Posted by no...@apache.org.
SOLR-8793: Fix stale commit files' size computation in LukeRequestHandler
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/4384627f
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/4384627f
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/4384627f
Branch: refs/heads/apiv2
Commit: 4384627f0891e4dc3232d3c7f20a54bc9224365c
Parents: e490b32
Author: Shai Erera <sh...@apache.org>
Authored: Tue Mar 8 22:11:18 2016 +0200
Committer: Shai Erera <sh...@apache.org>
Committed: Tue Mar 8 22:13:21 2016 +0200
----------------------------------------------------------------------
solr/CHANGES.txt | 5 +++++
.../apache/solr/handler/admin/LukeRequestHandler.java | 12 +++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4384627f/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index ecf8b32..d094b58 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -423,6 +423,11 @@ Bug Fixes
* SOLR-8712: Variable solr.core.instanceDir was not being resolved (Kristine
Jetzke, Shawn Heisey, Alan Woodward)
+* SOLR-8793: Fix Core admin status API to not fail when computing the size of the segments_N
+ file if the file no longer exists (for example, if a commit happened and the IndexReader
+ hasn't refreshed yet). In this case the reported size of the file is -1.
+ (Shai Erera, Alexey Serba, Richard Coggins)
+
======================= 5.5.0 =======================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4384627f/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
index 0ec6d79..450a505 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
@@ -582,7 +582,7 @@ public class LukeRequestHandler extends RequestHandlerBase
IndexCommit indexCommit = reader.getIndexCommit();
String segmentsFileName = indexCommit.getSegmentsFileName();
indexInfo.add("segmentsFile", segmentsFileName);
- indexInfo.add("segmentsFileSizeInBytes", indexCommit.getDirectory().fileLength(segmentsFileName));
+ indexInfo.add("segmentsFileSizeInBytes", getFileLength(indexCommit.getDirectory(), segmentsFileName));
Map<String,String> userData = indexCommit.getUserData();
indexInfo.add("userData", userData);
String s = userData.get(SolrIndexWriter.COMMIT_TIME_MSEC_KEY);
@@ -592,6 +592,16 @@ public class LukeRequestHandler extends RequestHandlerBase
return indexInfo;
}
+ private static long getFileLength(Directory dir, String filename) {
+ try {
+ return dir.fileLength(filename);
+ } catch (IOException e) {
+ // Whatever the error is, only log it and return -1.
+ log.warn("Error getting file length for [{}]", filename, e);
+ return -1;
+ }
+ }
+
/** Returns the sum of RAM bytes used by each segment */
private static long getIndexHeapUsed(DirectoryReader reader) {
long indexHeapRamBytesUsed = 0;
[39/50] [abbrv] lucene-solr git commit: don't use slow composite
reader in this test
Posted by no...@apache.org.
don't use slow composite reader in this test
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/e3fcbfe7
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/e3fcbfe7
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/e3fcbfe7
Branch: refs/heads/apiv2
Commit: e3fcbfe7ce32b1286576bf6f08c93c3192987e41
Parents: 2cac33a
Author: Mike McCandless <mi...@apache.org>
Authored: Tue Mar 8 13:34:08 2016 -0500
Committer: Mike McCandless <mi...@apache.org>
Committed: Tue Mar 8 13:34:08 2016 -0500
----------------------------------------------------------------------
.../apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3fcbfe7/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
index a3e049d..80c3903 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/ThreadedIndexingAndSearchingTestCase.java
@@ -480,7 +480,7 @@ public abstract class ThreadedIndexingAndSearchingTestCase extends LuceneTestCas
}
}
- IndexSearcher searcher = newSearcher(reader);
+ IndexSearcher searcher = newSearcher(reader, false);
sum += searcher.search(new TermQuery(new Term("body", "united")), 10).totalHits;
if (VERBOSE) {
[04/50] [abbrv] lucene-solr git commit: SOLR-8736: schema GET
operations on fields, dynamicFields, fieldTypes,
copyField are reimplemented as a part of the bulk API with less details. The
tests and write implementations are removed
Posted by no...@apache.org.
SOLR-8736: schema GET operations on fields, dynamicFields, fieldTypes, copyField are
reimplemented as a part of the bulk API with less details. The tests and write implementations are removed
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/f2c281ab
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/f2c281ab
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/f2c281ab
Branch: refs/heads/apiv2
Commit: f2c281abcbfc254d44c196ceb7c7f61311e7967c
Parents: 9082d5f
Author: Noble Paul <no...@apache.org>
Authored: Mon Mar 7 22:44:36 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Mon Mar 7 22:44:36 2016 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 5 +
.../org/apache/solr/handler/SchemaHandler.java | 78 +++-
.../org/apache/solr/rest/SolrSchemaRestApi.java | 56 +--
.../solr/rest/schema/BaseFieldResource.java | 146 --------
.../solr/rest/schema/BaseFieldTypeResource.java | 98 -----
.../schema/CopyFieldCollectionResource.java | 198 ----------
.../schema/DynamicFieldCollectionResource.java | 207 -----------
.../solr/rest/schema/DynamicFieldResource.java | 197 ----------
.../rest/schema/FieldCollectionResource.java | 225 -----------
.../apache/solr/rest/schema/FieldResource.java | 201 ----------
.../schema/FieldTypeCollectionResource.java | 197 ----------
.../solr/rest/schema/FieldTypeResource.java | 203 ----------
.../org/apache/solr/schema/IndexSchema.java | 11 +-
.../org/apache/solr/servlet/HttpSolrCall.java | 3 +
.../rest/schema/TestClassNameShortening.java | 3 +-
.../schema/TestCopyFieldCollectionResource.java | 96 +----
.../TestDynamicFieldCollectionResource.java | 29 --
.../rest/schema/TestDynamicFieldResource.java | 7 -
.../schema/TestFieldCollectionResource.java | 45 ---
.../solr/rest/schema/TestFieldResource.java | 23 +-
.../schema/TestFieldTypeCollectionResource.java | 1 +
.../solr/rest/schema/TestFieldTypeResource.java | 17 +-
.../TestManagedSchemaDynamicFieldResource.java | 366 ------------------
.../schema/TestManagedSchemaFieldResource.java | 369 -------------------
.../TestManagedSchemaFieldTypeResource.java | 350 ------------------
.../schema/TestRemoveLastDynamicCopyField.java | 80 ----
.../schema/TestSchemaSimilarityResource.java | 1 -
.../analysis/TestManagedStopFilterFactory.java | 2 +-
.../TestManagedSynonymFilterFactory.java | 6 +-
.../TestCloudManagedSchemaConcurrent.java | 3 +-
.../solr/client/solrj/request/SchemaTest.java | 4 -
31 files changed, 125 insertions(+), 3102 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 61fcd47..7893b88 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -105,6 +105,8 @@ Upgrading from Solr 5.x
* When requesting stats in date fields, "sum" is now a double value instead of a date. See SOLR-8671
+* SOLR-8736: The deprecated GET methods for schema are now accessible and implemented differently
+
Detailed Change List
----------------------
@@ -395,6 +397,9 @@ Other Changes
* SOLR-8758: Add a new SolrCloudTestCase class, using MiniSolrCloudCluster (Alan
Woodward)
+* SOLR-8736: schema GET operations on fields, dynamicFields, fieldTypes, copyField are
+ reimplemented as a part of the bulk API with less details (noble)
+
================== 5.5.1 ==================
Bug Fixes
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java b/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
index 046de46..4279864 100644
--- a/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
@@ -20,15 +20,20 @@ import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
+import java.util.Map;
import java.util.Set;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.ContentStream;
-import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestHandler;
@@ -42,17 +47,29 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.solr.common.params.CommonParams.JSON;
-import static org.apache.solr.core.ConfigSetProperties.IMMUTABLE_CONFIGSET_ARG;
public class SchemaHandler extends RequestHandlerBase implements SolrCoreAware {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private boolean isImmutableConfigSet = false;
- @Override
- public void init(NamedList args) {
- super.init(args);
+ private static final Map<String, String> level2;
+
+ static {
+ Set<String> s = ImmutableSet.of(
+ IndexSchema.FIELD_TYPES,
+ IndexSchema.FIELDS,
+ IndexSchema.DYNAMIC_FIELDS,
+ IndexSchema.COPY_FIELDS
+ );
+ Map<String, String> m = new HashMap<>();
+ for (String s1 : s) {
+ m.put(s1, s1);
+ m.put(s1.toLowerCase(Locale.ROOT), s1);
+ }
+ level2 = ImmutableMap.copyOf(m);
}
+
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
SolrConfigHandler.setWt(req, JSON);
@@ -150,6 +167,33 @@ public class SchemaHandler extends RequestHandlerBase implements SolrCoreAware {
break;
}
default: {
+ List<String> parts = StrUtils.splitSmart(path, '/');
+ if (parts.get(0).isEmpty()) parts.remove(0);
+ if (parts.size() > 1 && level2.containsKey(parts.get(1))) {
+ String realName = level2.get(parts.get(1));
+ SimpleOrderedMap<Object> propertyValues = req.getSchema().getNamedPropertyValues(req.getParams());
+ Object o = propertyValues.get(realName);
+ if(parts.size()> 2) {
+ String name = parts.get(2);
+ if (o instanceof List) {
+ List list = (List) o;
+ for (Object obj : list) {
+ if (obj instanceof SimpleOrderedMap) {
+ SimpleOrderedMap simpleOrderedMap = (SimpleOrderedMap) obj;
+ if(name.equals(simpleOrderedMap.get("name"))) {
+ rsp.add(realName.substring(0, realName.length() - 1), simpleOrderedMap);
+ return;
+ }
+ }
+ }
+ }
+ throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "No such path " + path);
+ } else {
+ rsp.add(realName, o);
+ }
+ return;
+ }
+
throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "No such path " + path);
}
}
@@ -160,19 +204,25 @@ public class SchemaHandler extends RequestHandlerBase implements SolrCoreAware {
}
private static Set<String> subPaths = new HashSet<>(Arrays.asList(
- "/version",
- "/uniquekey",
- "/name",
- "/similarity",
- "/defaultsearchfield",
- "/solrqueryparser",
- "/zkversion",
- "/solrqueryparser/defaultoperator"
+ "version",
+ "uniquekey",
+ "name",
+ "similarity",
+ "defaultsearchfield",
+ "solrqueryparser",
+ "zkversion"
));
+ static {
+ subPaths.addAll(level2.keySet());
+ }
@Override
public SolrRequestHandler getSubHandler(String subPath) {
- if (subPaths.contains(subPath)) return this;
+ List<String> parts = StrUtils.splitSmart(subPath, '/');
+ if (parts.get(0).isEmpty()) parts.remove(0);
+ String prefix = parts.get(0);
+ if(subPaths.contains(prefix)) return this;
+
return null;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java b/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java
index 0e40f73..1310198 100644
--- a/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java
+++ b/solr/core/src/java/org/apache/solr/rest/SolrSchemaRestApi.java
@@ -15,14 +15,14 @@
* limitations under the License.
*/
package org.apache.solr.rest;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
import org.apache.solr.request.SolrRequestInfo;
-import org.apache.solr.rest.schema.CopyFieldCollectionResource;
-import org.apache.solr.rest.schema.DynamicFieldCollectionResource;
-import org.apache.solr.rest.schema.DynamicFieldResource;
-import org.apache.solr.rest.schema.FieldCollectionResource;
-import org.apache.solr.rest.schema.FieldResource;
-import org.apache.solr.rest.schema.FieldTypeCollectionResource;
-import org.apache.solr.rest.schema.FieldTypeResource;
import org.apache.solr.schema.IndexSchema;
import org.restlet.Application;
import org.restlet.Restlet;
@@ -30,39 +30,18 @@ import org.restlet.routing.Router;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.lang.invoke.MethodHandles;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-
/**
* Restlet servlet handling /<context>/<collection>/schema/* URL paths
*/
public class SolrSchemaRestApi extends Application {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- public static final String FIELDS_PATH = "/" + IndexSchema.FIELDS;
-
- public static final String DYNAMIC_FIELDS = IndexSchema.DYNAMIC_FIELDS.toLowerCase(Locale.ROOT);
- public static final String DYNAMIC_FIELDS_PATH = "/" + DYNAMIC_FIELDS;
-
- public static final String FIELDTYPES = IndexSchema.FIELD_TYPES.toLowerCase(Locale.ROOT);
- public static final String FIELDTYPES_PATH = "/" + FIELDTYPES;
- public static final String NAME_SEGMENT = "/{" + IndexSchema.NAME.toLowerCase(Locale.ROOT) + "}";
-
- public static final String COPY_FIELDS = IndexSchema.COPY_FIELDS.toLowerCase(Locale.ROOT);
- public static final String COPY_FIELDS_PATH = "/" + COPY_FIELDS;
-
+
/**
* Returns reserved endpoints under /schema
*/
public static Set<String> getReservedEndpoints() {
Set<String> reservedEndpoints = new HashSet<>();
- reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + FIELDS_PATH);
- reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + DYNAMIC_FIELDS_PATH);
- reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + FIELDTYPES_PATH);
- reservedEndpoints.add(RestManager.SCHEMA_BASE_PATH + COPY_FIELDS_PATH);
return Collections.unmodifiableSet(reservedEndpoints);
}
@@ -88,25 +67,6 @@ public class SolrSchemaRestApi extends Application {
log.info("createInboundRoot started for /schema");
- router.attach(FIELDS_PATH, FieldCollectionResource.class);
- // Allow a trailing slash on collection requests
- router.attach(FIELDS_PATH + "/", FieldCollectionResource.class);
- router.attach(FIELDS_PATH + NAME_SEGMENT, FieldResource.class);
-
- router.attach(DYNAMIC_FIELDS_PATH, DynamicFieldCollectionResource.class);
- // Allow a trailing slash on collection requests
- router.attach(DYNAMIC_FIELDS_PATH + "/", DynamicFieldCollectionResource.class);
- router.attach(DYNAMIC_FIELDS_PATH + NAME_SEGMENT, DynamicFieldResource.class);
-
- router.attach(FIELDTYPES_PATH, FieldTypeCollectionResource.class);
- // Allow a trailing slash on collection requests
- router.attach(FIELDTYPES_PATH + "/", FieldTypeCollectionResource.class);
- router.attach(FIELDTYPES_PATH + NAME_SEGMENT, FieldTypeResource.class);
-
- router.attach(COPY_FIELDS_PATH, CopyFieldCollectionResource.class);
- // Allow a trailing slash on collection requests
- router.attach(COPY_FIELDS_PATH + "/", CopyFieldCollectionResource.class);
-
router.attachDefault(RestManager.ManagedEndpoint.class);
// attach all the dynamically registered schema resources
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldResource.java b/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldResource.java
deleted file mode 100644
index 25f631d..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldResource.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.cloud.ZkSolrResourceLoader;
-import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.core.CoreDescriptor;
-import org.apache.solr.rest.BaseSolrResource;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.restlet.resource.ResourceException;
-
-import java.util.LinkedHashSet;
-import java.util.Map;
-
-
-/**
- * Base class for Schema Field and DynamicField requests.
- */
-abstract class BaseFieldResource extends BaseSolrResource {
- protected static final String INCLUDE_DYNAMIC_PARAM = "includeDynamic";
- private static final String DYNAMIC_BASE = "dynamicBase";
-
- private LinkedHashSet<String> requestedFields;
- private boolean showDefaults;
-
- protected LinkedHashSet<String> getRequestedFields() {
- return requestedFields;
- }
-
-
- protected BaseFieldResource() {
- super();
- }
-
- /**
- * Pulls the "fl" param from the request and splits it to get the
- * requested list of fields. The (Dynamic)FieldCollectionResource classes
- * will then restrict the fields sent back in the response to those
- * on this list. The (Dynamic)FieldResource classes ignore this list,
- * since the (dynamic) field is specified in the URL path, rather than
- * in a query parameter.
- * <p>
- * Also pulls the "showDefaults" param from the request, for use by all
- * subclasses to include default values from the associated field type
- * in the response. By default this param is off.
- */
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- String flParam = getSolrRequest().getParams().get(CommonParams.FL);
- if (null != flParam) {
- String[] fields = flParam.trim().split("[,\\s]+");
- if (fields.length > 0) {
- requestedFields = new LinkedHashSet<>();
- for (String field : fields) {
- if ( ! field.trim().isEmpty()) {
- requestedFields.add(field.trim());
- }
- }
- }
- }
- showDefaults = getSolrRequest().getParams().getBool(SHOW_DEFAULTS, false);
- }
- }
-
- /** Get the properties for a given field.
- *
- * @param field not required to exist in the schema
- */
- protected SimpleOrderedMap<Object> getFieldProperties(SchemaField field) {
- if (null == field) {
- return null;
- }
- SimpleOrderedMap<Object> properties = field.getNamedPropertyValues(showDefaults);
- if ( ! getSchema().getFields().containsKey(field.getName())) {
- String dynamicBase = getSchema().getDynamicPattern(field.getName());
- // Add dynamicBase property if it's different from the field name.
- if ( ! field.getName().equals(dynamicBase)) {
- properties.add(DYNAMIC_BASE, dynamicBase);
- }
- }
- if (field == getSchema().getUniqueKeyField()) {
- properties.add(IndexSchema.UNIQUE_KEY, true);
- }
- return properties;
- }
-
- /**
- * When running in cloud mode, waits for a schema update to be
- * applied by all active replicas of the current collection.
- */
- protected void waitForSchemaUpdateToPropagate(IndexSchema newSchema) {
- // If using ZooKeeper and the client application has requested an update timeout, then block until all
- // active replicas for this collection process the updated schema
- if (getUpdateTimeoutSecs() > 0 && newSchema != null &&
- newSchema.getResourceLoader() instanceof ZkSolrResourceLoader)
- {
- CoreDescriptor cd = getSolrCore().getCoreDescriptor();
- String collection = cd.getCollectionName();
- if (collection != null) {
- ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) newSchema.getResourceLoader();
- ManagedIndexSchema.waitForSchemaZkVersionAgreement(collection,
- cd.getCloudDescriptor().getCoreNodeName(),
- ((ManagedIndexSchema) newSchema).getSchemaZkVersion(),
- zkLoader.getZkController(),
- getUpdateTimeoutSecs());
- }
- }
- }
-
- // protected access on this class triggers a bug in javadoc generation caught by
- // documentation-link: "BROKEN LINK" reported in javadoc for classes using
- // NewFieldArguments because the link target file is BaseFieldResource.NewFieldArguments,
- // but the actual file is BaseFieldResource$NewFieldArguments.
- static class NewFieldArguments {
- private String name;
- private String type;
- Map<String,Object> map;
- NewFieldArguments(String name, String type, Map<String,Object> map) {
- this.name = name;
- this.type = type;
- this.map = map;
- }
-
- public String getName() { return name; }
- public String getType() { return type; }
- public Map<String, Object> getMap() { return map; }
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java b/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java
deleted file mode 100644
index c475dd0..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-
-import org.apache.solr.cloud.ZkSolrResourceLoader;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.core.CoreDescriptor;
-import org.apache.solr.rest.BaseSolrResource;
-import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.restlet.resource.ResourceException;
-
-import java.util.List;
-
-/**
- * Base class for the FieldType resource classes.
- */
-abstract class BaseFieldTypeResource extends BaseSolrResource {
- private boolean showDefaults;
-
- protected BaseFieldTypeResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- showDefaults = getSolrRequest().getParams().getBool(SHOW_DEFAULTS, false);
- }
- }
-
- /** Used by subclasses to collect field type properties */
- protected SimpleOrderedMap<Object> getFieldTypeProperties(FieldType fieldType) {
- SimpleOrderedMap<Object> properties = fieldType.getNamedPropertyValues(showDefaults);
- properties.add(IndexSchema.FIELDS, getFieldsWithFieldType(fieldType));
- properties.add(IndexSchema.DYNAMIC_FIELDS, getDynamicFieldsWithFieldType(fieldType));
- return properties;
- }
-
-
- /** Return a list of names of Fields that have the given FieldType */
- protected abstract List<String> getFieldsWithFieldType(FieldType fieldType);
-
- /** Return a list of names of DynamicFields that have the given FieldType */
- protected abstract List<String> getDynamicFieldsWithFieldType(FieldType fieldType);
-
- /**
- * Adds one or more new FieldType definitions to the managed schema for the given core.
- */
- protected void addNewFieldTypes(List<FieldType> newFieldTypes, ManagedIndexSchema oldSchema) {
- IndexSchema newSchema = null;
- boolean success = false;
- while (!success) {
- try {
- synchronized (oldSchema.getSchemaUpdateLock()) {
- newSchema = oldSchema.addFieldTypes(newFieldTypes, true);
- getSolrCore().setLatestSchema(newSchema);
- success = true;
- }
- } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
- oldSchema = (ManagedIndexSchema)getSolrCore().getLatestSchema();
- }
- }
-
- // If using ZooKeeper and the client application has requested an update timeout, then block until all
- // active replicas for this collection process the updated schema
- if (getUpdateTimeoutSecs() > 0 && newSchema != null &&
- newSchema.getResourceLoader() instanceof ZkSolrResourceLoader)
- {
- CoreDescriptor cd = getSolrCore().getCoreDescriptor();
- String collection = cd.getCollectionName();
- if (collection != null) {
- ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) newSchema.getResourceLoader();
- ManagedIndexSchema.waitForSchemaZkVersionAgreement(collection,
- cd.getCloudDescriptor().getCoreNodeName(),
- ((ManagedIndexSchema) newSchema).getSchemaZkVersion(),
- zkLoader.getZkController(),
- getUpdateTimeoutSecs());
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java b/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
deleted file mode 100644
index 610c054..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.POSTable;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.invoke.MethodHandles;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.solr.common.SolrException.ErrorCode;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/copyfields
- * <p>
- *
- * To restrict the set of copyFields in the response, specify one or both
- * of the following as query parameters, with values as space and/or comma
- * separated dynamic or explicit field names:
- *
- * <ul>
- * <li>dest.fl: include copyFields that have one of these as a destination</li>
- * <li>source.fl: include copyFields that have one of these as a source</li>
- * </ul>
- *
- * If both dest.fl and source.fl are given as query parameters, the copyfields
- * in the response will be restricted to those that match any of the destinations
- * in dest.fl and also match any of the sources in source.fl.
- */
-public class CopyFieldCollectionResource extends BaseFieldResource implements GETable, POSTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private static final String SOURCE_FIELD_LIST = IndexSchema.SOURCE + "." + CommonParams.FL;
- private static final String DESTINATION_FIELD_LIST = IndexSchema.DESTINATION + "." + CommonParams.FL;
-
- private Set<String> requestedSourceFields;
- private Set<String> requestedDestinationFields;
-
- public CopyFieldCollectionResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- String sourceFieldListParam = getSolrRequest().getParams().get(SOURCE_FIELD_LIST);
- if (null != sourceFieldListParam) {
- String[] fields = sourceFieldListParam.trim().split("[,\\s]+");
- if (fields.length > 0) {
- requestedSourceFields = new HashSet<>(Arrays.asList(fields));
- requestedSourceFields.remove(""); // Remove empty values, if any
- }
- }
- String destinationFieldListParam = getSolrRequest().getParams().get(DESTINATION_FIELD_LIST);
- if (null != destinationFieldListParam) {
- String[] fields = destinationFieldListParam.trim().split("[,\\s]+");
- if (fields.length > 0) {
- requestedDestinationFields = new HashSet<>(Arrays.asList(fields));
- requestedDestinationFields.remove(""); // Remove empty values, if any
- }
- }
- }
- }
-
- @Override
- public Representation get() {
- try {
- getSolrResponse().add(IndexSchema.COPY_FIELDS,
- getSchema().getCopyFieldProperties(true, requestedSourceFields, requestedDestinationFields));
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- @Override
- public Representation post(Representation entity) throws ResourceException {
- try {
- if (!getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- if (!entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Object object = ObjectBuilder.fromJSON(entity.getText());
-
- if (!(object instanceof List)) {
- String message = "Invalid JSON type " + object.getClass().getName() + ", expected List of the form"
- + " (ignore the backslashes): [{\"source\":\"foo\",\"dest\":\"comma-separated list of targets\"}, {...}, ...]";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- List<Map<String, Object>> list = (List<Map<String, Object>>) object;
- Map<String, Collection<String>> fieldsToCopy = new HashMap<>();
- ManagedIndexSchema oldSchema = (ManagedIndexSchema) getSchema();
- Set<String> malformed = new HashSet<>();
- for (Map<String,Object> map : list) {
- String fieldName = (String)map.get(IndexSchema.SOURCE);
- if (null == fieldName) {
- String message = "Missing '" + IndexSchema.SOURCE + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- Object dest = map.get(IndexSchema.DESTINATION);
- List<String> destinations = null;
- if (dest != null) {
- if (dest instanceof List){
- destinations = (List<String>)dest;
- } else if (dest instanceof String){
- destinations = Collections.singletonList(dest.toString());
- } else {
- String message = "Invalid '" + IndexSchema.DESTINATION + "' type.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- }
- if (destinations == null) {
- malformed.add(fieldName);
- } else {
- fieldsToCopy.put(fieldName, destinations);
- }
- }
- if (malformed.size() > 0){
- StringBuilder message = new StringBuilder("Malformed destination(s) for: ");
- for (String s : malformed) {
- message.append(s).append(", ");
- }
- if (message.length() > 2) {
- message.setLength(message.length() - 2);//drop the last ,
- }
- log.error(message.toString().trim());
- throw new SolrException(ErrorCode.BAD_REQUEST, message.toString().trim());
- }
- IndexSchema newSchema = null;
- boolean success = false;
- while (!success) {
- try {
- synchronized (oldSchema.getSchemaUpdateLock()) {
- newSchema = oldSchema.addCopyFields(fieldsToCopy,true);
- if (null != newSchema) {
- getSolrCore().setLatestSchema(newSchema);
- success = true;
- } else {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Failed to add fields.");
- }
- }
- } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
- log.debug("Schema changed while processing request, retrying");
- oldSchema = (ManagedIndexSchema)getSolrCore().getLatestSchema();
- }
- }
- waitForSchemaUpdateToPropagate(newSchema);
- }
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
- return new SolrOutputRepresentation();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java b/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java
deleted file mode 100644
index bf94234..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.POSTable;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/dynamicfields
- * <p>
- * To restrict the set of dynamic fields in the response, specify a comma
- * and/or space separated list of dynamic field patterns in the "fl" query
- * parameter.
- */
-public class DynamicFieldCollectionResource extends BaseFieldResource implements GETable, POSTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- public DynamicFieldCollectionResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- }
-
- @Override
- public Representation get() {
-
- try {
- List<SimpleOrderedMap<Object>> props = new ArrayList<>();
- if (null == getRequestedFields()) {
- for (IndexSchema.DynamicField dynamicField : getSchema().getDynamicFields()) {
- if ( ! dynamicField.getRegex().startsWith(IndexSchema.INTERNAL_POLY_FIELD_PREFIX)) { // omit internal polyfields
- props.add(getFieldProperties(dynamicField.getPrototype()));
- }
- }
- } else {
- if (0 == getRequestedFields().size()) {
- String message = "Empty " + CommonParams.FL + " parameter value";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- Map<String,SchemaField> dynamicFieldsByName = new HashMap<>();
- for (IndexSchema.DynamicField dynamicField : getSchema().getDynamicFields()) {
- dynamicFieldsByName.put(dynamicField.getRegex(), dynamicField.getPrototype());
- }
- // Use the same order as the fl parameter
- for (String dynamicFieldName : getRequestedFields()) {
- final SchemaField dynamicSchemaField = dynamicFieldsByName.get(dynamicFieldName);
- if (null == dynamicSchemaField) {
- log.info("Requested dynamic field '" + dynamicFieldName + "' not found.");
- } else {
- props.add(getFieldProperties(dynamicSchemaField));
- }
- }
- }
- getSolrResponse().add(IndexSchema.DYNAMIC_FIELDS, props);
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- @Override
- public Representation post(Representation entity) {
- try {
- if ( ! getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- if (null == entity.getMediaType()) {
- entity.setMediaType(MediaType.APPLICATION_JSON);
- }
- if ( ! entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Object object = ObjectBuilder.fromJSON(entity.getText());
- if ( ! (object instanceof List)) {
- String message = "Invalid JSON type " + object.getClass().getName() + ", expected List of the form"
- + " (ignore the backslashes): [{\"name\":\"*_foo\",\"type\":\"text_general\", ...}, {...}, ...]";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- List<Map<String,Object>> list = (List<Map<String,Object>>)object;
- List<SchemaField> newDynamicFields = new ArrayList<>();
- List<NewFieldArguments> newDynamicFieldArguments = new ArrayList<>();
- ManagedIndexSchema oldSchema = (ManagedIndexSchema)getSchema();
- Map<String,Collection<String>> copyFields = new HashMap<>();
- for (Map<String,Object> map : list) {
- String fieldNamePattern = (String)map.remove(IndexSchema.NAME);
- if (null == fieldNamePattern) {
- String message = "Missing '" + IndexSchema.NAME + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- String fieldType = (String)map.remove(IndexSchema.TYPE);
- if (null == fieldType) {
- String message = "Missing '" + IndexSchema.TYPE + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- // copyFields:"comma separated list of destination fields"
- Object copies = map.get(IndexSchema.COPY_FIELDS);
- List<String> copyTo = null;
- if (copies != null) {
- if (copies instanceof List){
- copyTo = (List<String>)copies;
- } else if (copies instanceof String){
- copyTo = Collections.singletonList(copies.toString());
- } else {
- String message = "Invalid '" + IndexSchema.COPY_FIELDS + "' type.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- }
- if (copyTo != null) {
- map.remove(IndexSchema.COPY_FIELDS);
- copyFields.put(fieldNamePattern, copyTo);
- }
- newDynamicFields.add(oldSchema.newDynamicField(fieldNamePattern, fieldType, map));
- newDynamicFieldArguments.add(new NewFieldArguments(fieldNamePattern, fieldType, map));
- }
- IndexSchema newSchema = null;
- boolean firstAttempt = true;
- boolean success = false;
- while ( ! success) {
- try {
- if ( ! firstAttempt) {
- // If this isn't the first attempt, we must have failed due to
- // the schema changing in Zk during optimistic concurrency control.
- // In that case, rerun creating the new fields, because they may
- // fail now due to changes in the schema. This behavior is consistent
- // with what would happen if we locked the schema and the other schema
- // change went first.
- newDynamicFields.clear();
- for (NewFieldArguments args : newDynamicFieldArguments) {
- newDynamicFields.add(oldSchema.newDynamicField(args.getName(), args.getType(), args.getMap()));
- }
- }
- firstAttempt = false;
- synchronized (oldSchema.getSchemaUpdateLock()) {
- newSchema = oldSchema.addDynamicFields(newDynamicFields, copyFields, true);
- if (null != newSchema) {
- getSolrCore().setLatestSchema(newSchema);
- success = true;
- } else {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Failed to add dynamic fields.");
- }
- }
- } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
- log.debug("Schema changed while processing request, retrying");
- oldSchema = (ManagedIndexSchema)getSolrCore().getLatestSchema();
- }
- }
-
- waitForSchemaUpdateToPropagate(newSchema);
-
- }
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java b/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java
deleted file mode 100644
index bf67608..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.PUTable;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.invoke.MethodHandles;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/dynamicfields/(pattern)
- * where pattern is a field name pattern (with an asterisk at the beginning or the end).
- */
-public class DynamicFieldResource extends BaseFieldResource implements GETable, PUTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private String fieldNamePattern;
-
- public DynamicFieldResource() {
- super();
- }
-
- /**
- * Gets the field name pattern from the request attribute where it's stored by Restlet.
- */
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- fieldNamePattern = (String)getRequestAttributes().get(IndexSchema.NAME);
- try {
- fieldNamePattern = null == fieldNamePattern ? "" : urlDecode(fieldNamePattern.trim()).trim();
- } catch (UnsupportedEncodingException e) {
- throw new ResourceException(e);
- }
- }
- }
-
- @Override
- public Representation get() {
- try {
- if (fieldNamePattern.isEmpty()) {
- final String message = "Dynamic field name is missing";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- SchemaField field = null;
- for (SchemaField prototype : getSchema().getDynamicFieldPrototypes()) {
- if (prototype.getName().equals(fieldNamePattern)) {
- field = prototype;
- break;
- }
- }
- if (null == field) {
- final String message = "Dynamic field '" + fieldNamePattern + "' not found.";
- throw new SolrException(ErrorCode.NOT_FOUND, message);
- } else {
- getSolrResponse().add(IndexSchema.DYNAMIC_FIELD, getFieldProperties(field));
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- /**
- * Accepts JSON add dynamic field request
- */
- @Override
- public Representation put(Representation entity) {
- try {
- if ( ! getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- if (null == entity.getMediaType()) {
- entity.setMediaType(MediaType.APPLICATION_JSON);
- }
- if ( ! entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Object object = ObjectBuilder.fromJSON(entity.getText());
- if ( ! (object instanceof Map)) {
- String message = "Invalid JSON type " + object.getClass().getName() + ", expected Map of the form"
- + " (ignore the backslashes): {\"type\":\"text_general\", ...}, either with or"
- + " without a \"name\" mapping. If the \"name\" is specified, it must match the"
- + " name given in the request URL: /schema/dynamicfields/(name)";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Map<String,Object> map = (Map<String,Object>)object;
- if (1 == map.size() && map.containsKey(IndexSchema.DYNAMIC_FIELD)) {
- map = (Map<String,Object>)map.get(IndexSchema.DYNAMIC_FIELD);
- }
- String bodyFieldName;
- if (null != (bodyFieldName = (String)map.remove(IndexSchema.NAME))
- && ! fieldNamePattern.equals(bodyFieldName)) {
- String message = "Dynamic field name in the request body '" + bodyFieldName
- + "' doesn't match dynamic field name in the request URL '" + fieldNamePattern + "'";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- String fieldType;
- if (null == (fieldType = (String) map.remove(IndexSchema.TYPE))) {
- String message = "Missing '" + IndexSchema.TYPE + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- ManagedIndexSchema oldSchema = (ManagedIndexSchema)getSchema();
- Object copies = map.get(IndexSchema.COPY_FIELDS);
- Collection<String> copyFieldNames = null;
- if (copies != null) {
- if (copies instanceof List) {
- copyFieldNames = (List<String>)copies;
- } else if (copies instanceof String) {
- copyFieldNames = singletonList(copies.toString());
- } else {
- String message = "Invalid '" + IndexSchema.COPY_FIELDS + "' type.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- }
- if (copyFieldNames != null) {
- map.remove(IndexSchema.COPY_FIELDS);
- }
- IndexSchema newSchema = null;
- boolean success = false;
- while ( ! success) {
- try {
- SchemaField newDynamicField = oldSchema.newDynamicField(fieldNamePattern, fieldType, map);
- synchronized (oldSchema.getSchemaUpdateLock()) {
- newSchema = oldSchema.addDynamicFields(singletonList(newDynamicField), singletonMap(newDynamicField.getName(), copyFieldNames), true);
- if (null != newSchema) {
- getSolrCore().setLatestSchema(newSchema);
- success = true;
- } else {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Failed to add dynamic field.");
- }
- }
- } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
- log.debug("Schema changed while processing request, retrying");
- oldSchema = (ManagedIndexSchema)getSolrCore().getLatestSchema();
- }
- }
- // if in cloud mode, wait for schema updates to propagate to all replicas
- waitForSchemaUpdateToPropagate(newSchema);
- }
- }
- }
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java b/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java
deleted file mode 100644
index f1bf6a4..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.cloud.ZkSolrResourceLoader;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.core.CoreDescriptor;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.POSTable;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/fields
- * <p>
- * Two query parameters are supported:
- * <ul>
- * <li>
- * "fl": a comma- and/or space-separated list of fields to send properties
- * for in the response, rather than the default: all of them.
- * </li>
- * <li>
- * "includeDynamic": if the "fl" parameter is specified, matching dynamic
- * fields are included in the response and identified with the "dynamicBase"
- * property. If the "fl" parameter is not specified, the "includeDynamic"
- * query parameter is ignored.
- * </li>
- * </ul>
- */
-public class FieldCollectionResource extends BaseFieldResource implements GETable, POSTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private boolean includeDynamic;
-
- public FieldCollectionResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- includeDynamic = getSolrRequest().getParams().getBool(INCLUDE_DYNAMIC_PARAM, false);
- }
- }
-
- @Override
- public Representation get() {
- try {
- final List<SimpleOrderedMap<Object>> props = new ArrayList<>();
- if (null == getRequestedFields()) {
- SortedSet<String> fieldNames = new TreeSet<>(getSchema().getFields().keySet());
- for (String fieldName : fieldNames) {
- props.add(getFieldProperties(getSchema().getFields().get(fieldName)));
- }
- } else {
- if (0 == getRequestedFields().size()) {
- String message = "Empty " + CommonParams.FL + " parameter value";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- // Use the same order as the fl parameter
- for (String fieldName : getRequestedFields()) {
- final SchemaField field;
- if (includeDynamic) {
- field = getSchema().getFieldOrNull(fieldName);
- } else {
- field = getSchema().getFields().get(fieldName);
- }
- if (null == field) {
- log.info("Requested field '" + fieldName + "' not found.");
- } else {
- props.add(getFieldProperties(field));
- }
- }
- }
- getSolrResponse().add(IndexSchema.FIELDS, props);
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- @Override
- public Representation post(Representation entity) {
- try {
- if (!getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- if (null == entity.getMediaType()) {
- entity.setMediaType(MediaType.APPLICATION_JSON);
- }
- if (!entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Object object = ObjectBuilder.fromJSON(entity.getText());
- if (!(object instanceof List)) {
- String message = "Invalid JSON type " + object.getClass().getName() + ", expected List of the form"
- + " (ignore the backslashes): [{\"name\":\"foo\",\"type\":\"text_general\", ...}, {...}, ...]";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- List<Map<String, Object>> list = (List<Map<String, Object>>) object;
- List<SchemaField> newFields = new ArrayList<>();
- List<NewFieldArguments> newFieldArguments = new ArrayList<>();
- IndexSchema oldSchema = getSchema();
- Map<String, Collection<String>> copyFields = new HashMap<>();
- for (Map<String, Object> map : list) {
- String fieldName = (String) map.remove(IndexSchema.NAME);
- if (null == fieldName) {
- String message = "Missing '" + IndexSchema.NAME + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- String fieldType = (String) map.remove(IndexSchema.TYPE);
- if (null == fieldType) {
- String message = "Missing '" + IndexSchema.TYPE + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- // copyFields:"comma separated list of destination fields"
- Object copies = map.get(IndexSchema.COPY_FIELDS);
- List<String> copyTo = null;
- if (copies != null) {
- if (copies instanceof List){
- copyTo = (List<String>) copies;
- } else if (copies instanceof String){
- copyTo = Collections.singletonList(copies.toString());
- } else {
- String message = "Invalid '" + IndexSchema.COPY_FIELDS + "' type.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- }
- if (copyTo != null) {
- map.remove(IndexSchema.COPY_FIELDS);
- copyFields.put(fieldName, copyTo);
- }
- newFields.add(oldSchema.newField(fieldName, fieldType, map));
- newFieldArguments.add(new NewFieldArguments(fieldName, fieldType, map));
- }
- IndexSchema newSchema = null;
- boolean firstAttempt = true;
- boolean success = false;
- while (!success) {
- try {
- if (!firstAttempt) {
- // If this isn't the first attempt, we must have failed due to
- // the schema changing in Zk during optimistic concurrency control.
- // In that case, rerun creating the new fields, because they may
- // fail now due to changes in the schema. This behavior is consistent
- // with what would happen if we locked the schema and the other schema
- // change went first.
- newFields.clear();
- for (NewFieldArguments args : newFieldArguments) {
- newFields.add(oldSchema.newField(
- args.getName(), args.getType(), args.getMap()));
- }
- }
- firstAttempt = false;
- synchronized (oldSchema.getSchemaUpdateLock()) {
- newSchema = oldSchema.addFields(newFields, copyFields, true);
- if (null != newSchema) {
- getSolrCore().setLatestSchema(newSchema);
- success = true;
- } else {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Failed to add fields.");
- }
- }
- } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
- log.debug("Schema changed while processing request, retrying");
- oldSchema = getSolrCore().getLatestSchema();
- }
- }
- waitForSchemaUpdateToPropagate(newSchema);
- }
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/FieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/FieldResource.java b/solr/core/src/java/org/apache/solr/rest/schema/FieldResource.java
deleted file mode 100644
index 2634bbd..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/FieldResource.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.cloud.ZkSolrResourceLoader;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.core.CoreDescriptor;
-import org.apache.solr.core.SolrResourceLoader;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.PUTable;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.invoke.MethodHandles;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/fields/(fieldname)
- * where "fieldname" is the name of a field.
- * <p>
- * The GET method returns properties for the given fieldname.
- * The "includeDynamic" query parameter, if specified, will cause the
- * dynamic field matching the given fieldname to be returned if fieldname
- * is not explicitly declared in the schema.
- * <p>
- * The PUT method accepts field addition requests in JSON format.
- */
-public class FieldResource extends BaseFieldResource implements GETable, PUTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private boolean includeDynamic;
- private String fieldName;
-
- public FieldResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- includeDynamic = getSolrRequest().getParams().getBool(INCLUDE_DYNAMIC_PARAM, false);
- fieldName = (String) getRequestAttributes().get(IndexSchema.NAME);
- try {
- fieldName = null == fieldName ? "" : urlDecode(fieldName.trim()).trim();
- } catch (UnsupportedEncodingException e) {
- throw new ResourceException(e);
- }
- }
- }
-
- @Override
- public Representation get() {
- try {
- if (fieldName.isEmpty()) {
- final String message = "Field name is missing";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- final SchemaField field;
- if (includeDynamic) {
- field = getSchema().getFieldOrNull(fieldName);
- } else {
- field = getSchema().getFields().get(fieldName);
- }
- if (null == field) {
- final String message = "Field '" + fieldName + "' not found.";
- throw new SolrException(ErrorCode.NOT_FOUND, message);
- } else {
- getSolrResponse().add(IndexSchema.FIELD, getFieldProperties(field));
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- /**
- * Accepts JSON add field request, to URL
- */
- @Override
- public Representation put(Representation entity) {
- try {
- if (!getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- if (null == entity.getMediaType()) {
- entity.setMediaType(MediaType.APPLICATION_JSON);
- }
- if (!entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Object object = ObjectBuilder.fromJSON(entity.getText());
- if (!(object instanceof Map)) {
- String message = "Invalid JSON type " + object.getClass().getName() + ", expected Map of the form"
- + " (ignore the backslashes): {\"type\":\"text_general\", ...}, either with or"
- + " without a \"name\" mapping. If the \"name\" is specified, it must match the"
- + " name given in the request URL: /schema/fields/(name)";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- Map<String, Object> map = (Map<String, Object>) object;
- if (1 == map.size() && map.containsKey(IndexSchema.FIELD)) {
- map = (Map<String, Object>) map.get(IndexSchema.FIELD);
- }
- String bodyFieldName;
- if (null != (bodyFieldName = (String) map.remove(IndexSchema.NAME)) && !fieldName.equals(bodyFieldName)) {
- String message = "Field name in the request body '" + bodyFieldName
- + "' doesn't match field name in the request URL '" + fieldName + "'";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- String fieldType;
- if (null == (fieldType = (String) map.remove(IndexSchema.TYPE))) {
- String message = "Missing '" + IndexSchema.TYPE + "' mapping.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- ManagedIndexSchema oldSchema = (ManagedIndexSchema) getSchema();
- Object copies = map.get(IndexSchema.COPY_FIELDS);
- List<String> copyFieldNames = null;
- if (copies != null) {
- if (copies instanceof List) {
- copyFieldNames = (List<String>) copies;
- } else if (copies instanceof String) {
- copyFieldNames = Collections.singletonList(copies.toString());
- } else {
- String message = "Invalid '" + IndexSchema.COPY_FIELDS + "' type.";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- }
- if (copyFieldNames != null) {
- map.remove(IndexSchema.COPY_FIELDS);
- }
-
- IndexSchema newSchema = null;
- boolean success = false;
- while (!success) {
- try {
- SchemaField newField = oldSchema.newField(fieldName, fieldType, map);
- synchronized (oldSchema.getSchemaUpdateLock()) {
- newSchema = oldSchema.addField(newField, copyFieldNames);
- if (null != newSchema) {
- getSolrCore().setLatestSchema(newSchema);
- success = true;
- } else {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Failed to add field.");
- }
- }
- } catch (ManagedIndexSchema.SchemaChangedInZkException e) {
- log.debug("Schema changed while processing request, retrying");
- oldSchema = (ManagedIndexSchema)getSolrCore().getLatestSchema();
- }
- }
- waitForSchemaUpdateToPropagate(newSchema);
- }
- }
- }
- }
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeCollectionResource.java b/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeCollectionResource.java
deleted file mode 100644
index d2eb1bd..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeCollectionResource.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.POSTable;
-import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/fieldtypes
- *
- * The GET method returns properties for all field types defined in the schema.
- */
-public class FieldTypeCollectionResource extends BaseFieldTypeResource implements GETable, POSTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private Map<String,List<String>> fieldsByFieldType;
- private Map<String,List<String>> dynamicFieldsByFieldType;
-
- public FieldTypeCollectionResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- fieldsByFieldType = getFieldsByFieldType();
- dynamicFieldsByFieldType = getDynamicFieldsByFieldType();
- }
- }
-
- @Override
- public Representation get() {
- try {
- List<SimpleOrderedMap<Object>> props = new ArrayList<>();
- Map<String,FieldType> sortedFieldTypes = new TreeMap<>(getSchema().getFieldTypes());
- for (FieldType fieldType : sortedFieldTypes.values()) {
- props.add(getFieldTypeProperties(fieldType));
- }
- getSolrResponse().add(IndexSchema.FIELD_TYPES, props);
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- /** Returns field lists from the map constructed in doInit() */
- @Override
- protected List<String> getFieldsWithFieldType(FieldType fieldType) {
- List<String> fields = fieldsByFieldType.get(fieldType.getTypeName());
- if (null == fields) {
- fields = Collections.emptyList();
- }
- return fields;
- }
-
- /** Returns dynamic field lists from the map constructed in doInit() */
- @Override
- protected List<String> getDynamicFieldsWithFieldType(FieldType fieldType) {
- List<String> dynamicFields = dynamicFieldsByFieldType.get(fieldType.getTypeName());
- if (null == dynamicFields) {
- dynamicFields = Collections.emptyList();
- }
- return dynamicFields;
- }
-
- /**
- * Returns a map from field type names to a sorted list of fields that use the field type.
- * The map only includes field types that are used by at least one field.
- */
- private Map<String,List<String>> getFieldsByFieldType() {
- Map<String,List<String>> fieldsByFieldType = new HashMap<>();
- for (SchemaField schemaField : getSchema().getFields().values()) {
- final String fieldType = schemaField.getType().getTypeName();
- List<String> fields = fieldsByFieldType.get(fieldType);
- if (null == fields) {
- fields = new ArrayList<>();
- fieldsByFieldType.put(fieldType, fields);
- }
- fields.add(schemaField.getName());
- }
- for (List<String> fields : fieldsByFieldType.values()) {
- Collections.sort(fields);
- }
- return fieldsByFieldType;
- }
-
- /**
- * Returns a map from field type names to a list of dynamic fields that use the field type.
- * The map only includes field types that are used by at least one dynamic field.
- */
- private Map<String,List<String>> getDynamicFieldsByFieldType() {
- Map<String,List<String>> dynamicFieldsByFieldType = new HashMap<>();
- for (SchemaField schemaField : getSchema().getDynamicFieldPrototypes()) {
- final String fieldType = schemaField.getType().getTypeName();
- List<String> dynamicFields = dynamicFieldsByFieldType.get(fieldType);
- if (null == dynamicFields) {
- dynamicFields = new ArrayList<>();
- dynamicFieldsByFieldType.put(fieldType, dynamicFields);
- }
- dynamicFields.add(schemaField.getName());
- }
- return dynamicFieldsByFieldType;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Representation post(Representation entity) {
- try {
- if (!getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- if (null == entity.getMediaType())
- entity.setMediaType(MediaType.APPLICATION_JSON);
-
- if (!entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- Object object = ObjectBuilder.fromJSON(entity.getText());
- if (!(object instanceof List)) {
- String message = "Invalid JSON type " + object.getClass().getName()
- + ", expected List of field type definitions in the form of"
- + " (ignore the backslashes): [{\"name\":\"text_general\",\"class\":\"solr.TextField\", ...}, {...}, ...]";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- List<Map<String, Object>> fieldTypeList = (List<Map<String, Object>>) object;
- if (fieldTypeList.size() > 0)
- addOrUpdateFieldTypes(fieldTypeList);
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- @SuppressWarnings("unchecked")
- protected void addOrUpdateFieldTypes(List<Map<String, Object>> fieldTypeList) throws Exception {
- List<FieldType> newFieldTypes = new ArrayList<>(fieldTypeList.size());
- ManagedIndexSchema oldSchema = (ManagedIndexSchema) getSchema();
- for (Map<String,Object> fieldTypeJson : fieldTypeList) {
- if (1 == fieldTypeJson.size() && fieldTypeJson.containsKey(IndexSchema.FIELD_TYPE)) {
- fieldTypeJson = (Map<String, Object>) fieldTypeJson.get(IndexSchema.FIELD_TYPE);
- }
- FieldType newFieldType =
- FieldTypeResource.buildFieldTypeFromJson(oldSchema,
- (String)fieldTypeJson.get(IndexSchema.NAME), fieldTypeJson);
- newFieldTypes.add(newFieldType);
- }
- // now deploy the added types (all or nothing)
- addNewFieldTypes(newFieldTypes, oldSchema);
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeResource.java b/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeResource.java
deleted file mode 100644
index 361c8c2..0000000
--- a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeResource.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.rest.GETable;
-import org.apache.solr.rest.PUTable;
-import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.ManagedIndexSchema;
-import org.apache.solr.schema.SchemaField;
-import org.noggit.ObjectBuilder;
-import org.restlet.data.MediaType;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ResourceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class responds to requests at /solr/(corename)/schema/fieldtype/(typename)
- * where "typename" is the name of a field type in the schema.
- *
- * The GET method returns properties for the named field type.
- */
-public class FieldTypeResource extends BaseFieldTypeResource implements GETable, PUTable {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
- private String typeName;
-
- public FieldTypeResource() {
- super();
- }
-
- @Override
- public void doInit() throws ResourceException {
- super.doInit();
- if (isExisting()) {
- typeName = (String)getRequestAttributes().get(IndexSchema.NAME);
- try {
- typeName = null == typeName ? "" : urlDecode(typeName.trim()).trim();
- } catch (UnsupportedEncodingException e) {
- throw new ResourceException(e);
- }
- }
- }
-
- @Override
- public Representation get() {
- try {
- if (typeName.isEmpty()) {
- final String message = "Field type name is missing";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- } else {
- FieldType fieldType = getSchema().getFieldTypes().get(typeName);
- if (null == fieldType) {
- final String message = "Field type '" + typeName + "' not found.";
- throw new SolrException(ErrorCode.NOT_FOUND, message);
- }
- getSolrResponse().add(IndexSchema.FIELD_TYPE, getFieldTypeProperties(fieldType));
- }
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- /**
- * Returns a field list using the given field type by iterating over all fields
- * defined in the schema.
- */
- @Override
- protected List<String> getFieldsWithFieldType(FieldType fieldType) {
- List<String> fields = new ArrayList<>();
- for (SchemaField schemaField : getSchema().getFields().values()) {
- if (schemaField.getType().getTypeName().equals(fieldType.getTypeName())) {
- fields.add(schemaField.getName());
- }
- }
- Collections.sort(fields);
- return fields;
- }
-
- /**
- * Returns a dynamic field list using the given field type by iterating over all
- * dynamic fields defined in the schema.
- */
- @Override
- protected List<String> getDynamicFieldsWithFieldType(FieldType fieldType) {
- List<String> dynamicFields = new ArrayList<>();
- for (SchemaField prototype : getSchema().getDynamicFieldPrototypes()) {
- if (prototype.getType().getTypeName().equals(fieldType.getTypeName())) {
- dynamicFields.add(prototype.getName());
- }
- }
- return dynamicFields; // Don't sort these - they're matched in order
- }
-
- /**
- * Accepts JSON add fieldtype request, to URL
- */
- @SuppressWarnings("unchecked")
- @Override
- public Representation put(Representation entity) {
- try {
- if (!getSchema().isMutable()) {
- final String message = "This IndexSchema is not mutable.";
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- if (null == entity.getMediaType())
- entity.setMediaType(MediaType.APPLICATION_JSON);
-
- if (!entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
- String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
- + " Request has media type " + entity.getMediaType().toString() + ".";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- Object object = ObjectBuilder.fromJSON(entity.getText());
- if (!(object instanceof Map)) {
- String message = "Invalid JSON type " + object.getClass().getName() + ", expected Map of the form"
- + " (ignore the backslashes): {\"name\":\"text_general\", \"class\":\"solr.TextField\" ...},"
- + " either with or without a \"name\" mapping. If the \"name\" is specified, it must match the"
- + " name given in the request URL: /schema/fieldtypes/(name)";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- // basic validation passed, let's try to create it!
- addOrUpdateFieldType((Map<String, Object>)object);
-
- } catch (Exception e) {
- getSolrResponse().setException(e);
- }
- handlePostExecution(log);
-
- return new SolrOutputRepresentation();
- }
-
- protected void addOrUpdateFieldType(Map<String,Object> fieldTypeJson) {
- ManagedIndexSchema oldSchema = (ManagedIndexSchema) getSchema();
- FieldType newFieldType = buildFieldTypeFromJson(oldSchema, typeName, fieldTypeJson);
- addNewFieldTypes(Collections.singletonList(newFieldType), oldSchema);
- }
-
- /**
- * Builds a FieldType definition from a JSON object.
- */
- @SuppressWarnings("unchecked")
- static FieldType buildFieldTypeFromJson(ManagedIndexSchema oldSchema, String fieldTypeName, Map<String,Object> fieldTypeJson) {
- if (1 == fieldTypeJson.size() && fieldTypeJson.containsKey(IndexSchema.FIELD_TYPE)) {
- fieldTypeJson = (Map<String, Object>)fieldTypeJson.get(IndexSchema.FIELD_TYPE);
- }
-
- String bodyTypeName = (String) fieldTypeJson.get(IndexSchema.NAME);
- if (bodyTypeName == null) {
- // must provide the name in the JSON for converting to the XML format needed
- // to create FieldType objects using the FieldTypePluginLoader
- fieldTypeJson.put(IndexSchema.NAME, fieldTypeName);
- } else {
- // if they provide it in the JSON, then it must match the value from the path
- if (!fieldTypeName.equals(bodyTypeName)) {
- String message = "Field type name in the request body '" + bodyTypeName
- + "' doesn't match field type name in the request URL '" + fieldTypeName + "'";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
- }
-
- String className = (String)fieldTypeJson.get(FieldType.CLASS_NAME);
- if (className == null) {
- String message = "Missing required '" + FieldType.CLASS_NAME + "' property!";
- log.error(message);
- throw new SolrException(ErrorCode.BAD_REQUEST, message);
- }
-
- return oldSchema.newFieldType(fieldTypeName, className, fieldTypeJson);
- }
-}
[25/50] [abbrv] lucene-solr git commit: SOLR-8782: Improve async
collections API
Posted by no...@apache.org.
SOLR-8782: Improve async collections API
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/5b7be9d1
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/5b7be9d1
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/5b7be9d1
Branch: refs/heads/apiv2
Commit: 5b7be9d16abf72052910a63e6d79debd8af5a7c1
Parents: a0a571c
Author: Alan Woodward <ro...@apache.org>
Authored: Mon Mar 7 16:00:40 2016 +0000
Committer: Alan Woodward <ro...@apache.org>
Committed: Tue Mar 8 10:53:29 2016 +0000
----------------------------------------------------------------------
solr/CHANGES.txt | 4 +
.../configsets/cloud-minimal/conf/schema.xml | 32 +
.../cloud-minimal/conf/solrconfig.xml | 48 ++
.../CollectionsAPIAsyncDistributedZkTest.java | 174 ++---
.../solr/security/BasicAuthIntegrationTest.java | 2 +-
.../solrj/request/CollectionAdminRequest.java | 691 +++++++++++++------
6 files changed, 622 insertions(+), 329 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5b7be9d1/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 7893b88..b71c63b 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -22,6 +22,10 @@ See the Quick Start guide at http://lucene.apache.org/solr/quickstart.html
================== 6.1.0 ==================
Detailed Change List
----------------------
+* SOLR-8782: Add asynchronous sugar methods to the SolrJ Collections API. You
+ can now call .processAsync() to run a method asynchronously, or
+ .processAndWait() to wait for a call to finish without holding HTTP
+ collections open. (Alan Woodward)
New Features
----------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5b7be9d1/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml
new file mode 100644
index 0000000..2a276af
--- /dev/null
+++ b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/schema.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<schema name="minimal" version="1.1">
+ <types>
+ <fieldType name="string" class="solr.StrField"/>
+ <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
+ <fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
+ </types>
+ <fields>
+ <dynamicField name="*" type="string" indexed="true" stored="true" />
+ <!-- for versioning -->
+ <field name="_version_" type="long" indexed="true" stored="true"/>
+ <field name="_root_" type="int" indexed="true" stored="true" multiValued="false" required="false"/>
+ <field name="id" type="string" indexed="true" stored="true"/>
+ </fields>
+ <uniqueKey>id</uniqueKey>
+</schema>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5b7be9d1/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml
new file mode 100644
index 0000000..059e58f
--- /dev/null
+++ b/solr/core/src/test-files/solr/configsets/cloud-minimal/conf/solrconfig.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" ?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Minimal solrconfig.xml with /select, /admin and /update only -->
+
+<config>
+
+ <dataDir>${solr.data.dir:}</dataDir>
+
+ <directoryFactory name="DirectoryFactory"
+ class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
+ <schemaFactory class="ClassicIndexSchemaFactory"/>
+
+ <luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
+
+ <updateHandler class="solr.DirectUpdateHandler2">
+ <commitWithin>
+ <softCommit>${solr.commitwithin.softcommit:true}</softCommit>
+ </commitWithin>
+ <updateLog></updateLog>
+ </updateHandler>
+
+ <requestHandler name="/select" class="solr.SearchHandler">
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <str name="indent">true</str>
+ <str name="df">text</str>
+ </lst>
+
+ </requestHandler>
+</config>
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5b7be9d1/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java
index 493b298..dcb115a 100644
--- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIAsyncDistributedZkTest.java
@@ -21,90 +21,80 @@ import java.util.List;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.lucene.util.TestUtil;
-import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.CollectionAdminRequest.Create;
import org.apache.solr.client.solrj.request.CollectionAdminRequest.SplitShard;
import org.apache.solr.client.solrj.response.RequestStatusState;
-import org.apache.solr.client.solrj.response.CollectionAdminResponse;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.Slice;
+import org.junit.BeforeClass;
import org.junit.Test;
/**
* Tests the Cloud Collections API.
*/
@Slow
-public class CollectionsAPIAsyncDistributedZkTest extends AbstractFullDistribZkTestBase {
+public class CollectionsAPIAsyncDistributedZkTest extends SolrCloudTestCase {
+
private static final int MAX_TIMEOUT_SECONDS = 60;
- public CollectionsAPIAsyncDistributedZkTest() {
- sliceCount = 1;
+ @BeforeClass
+ public static void setupCluster() throws Exception {
+ configureCluster(2)
+ .addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
+ .configure();
}
@Test
- @ShardsFixed(num = 1)
public void testSolrJAPICalls() throws Exception {
- try (SolrClient client = createNewSolrClient("", getBaseUrl((HttpSolrClient) clients.get(0)))) {
- Create createCollectionRequest = new Create()
- .setCollectionName("testasynccollectioncreation")
- .setNumShards(1)
- .setConfigName("conf1")
- .setAsyncId("1001");
- createCollectionRequest.process(client);
-
- RequestStatusState state = getRequestStateAfterCompletion("1001", MAX_TIMEOUT_SECONDS, client);
-
- assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state);
-
- createCollectionRequest = new Create()
- .setCollectionName("testasynccollectioncreation")
- .setNumShards(1)
- .setConfigName("conf1")
- .setAsyncId("1002");
- createCollectionRequest.process(client);
-
- state = getRequestStateAfterCompletion("1002", MAX_TIMEOUT_SECONDS, client);
-
- assertSame("Recreating a collection with the same should have failed.", RequestStatusState.FAILED, state);
-
- CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica()
- .setCollectionName("testasynccollectioncreation")
- .setShardName("shard1")
- .setAsyncId("1003");
- client.request(addReplica);
- state = getRequestStateAfterCompletion("1003", MAX_TIMEOUT_SECONDS, client);
- assertSame("Add replica did not complete", RequestStatusState.COMPLETED, state);
-
- SplitShard splitShardRequest = new SplitShard()
- .setCollectionName("testasynccollectioncreation")
- .setShardName("shard1")
- .setAsyncId("1004");
- splitShardRequest.process(client);
-
- state = getRequestStateAfterCompletion("1004", MAX_TIMEOUT_SECONDS * 2, client);
-
- assertEquals("Shard split did not complete. Last recorded state: " + state, RequestStatusState.COMPLETED, state);
- }
+
+ final CloudSolrClient client = cluster.getSolrClient();
+
+ RequestStatusState state = new Create()
+ .setCollectionName("testasynccollectioncreation")
+ .setNumShards(1)
+ .setReplicationFactor(1)
+ .setConfigName("conf1")
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
+ assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state);
+
+ state = new Create()
+ .setCollectionName("testasynccollectioncreation")
+ .setNumShards(1)
+ .setConfigName("conf1")
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
+ assertSame("Recreating a collection with the same should have failed.", RequestStatusState.FAILED, state);
+
+ state = new CollectionAdminRequest.AddReplica()
+ .setCollectionName("testasynccollectioncreation")
+ .setShardName("shard1")
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
+ assertSame("Add replica did not complete", RequestStatusState.COMPLETED, state);
+
+ state = new SplitShard()
+ .setCollectionName("testasynccollectioncreation")
+ .setShardName("shard1")
+ .processAndWait(client, MAX_TIMEOUT_SECONDS * 2);
+ assertEquals("Shard split did not complete. Last recorded state: " + state, RequestStatusState.COMPLETED, state);
+
}
@Test
public void testAsyncRequests() throws Exception {
- String collection = "testAsyncOperations";
- Create createCollectionRequest = new Create()
+ final String collection = "testAsyncOperations";
+ final CloudSolrClient client = cluster.getSolrClient();
+
+ RequestStatusState state = new Create()
.setCollectionName(collection)
.setNumShards(1)
.setRouterName("implicit")
.setShards("shard1")
.setConfigName("conf1")
- .setAsyncId("42");
- CollectionAdminResponse response = createCollectionRequest.process(cloudClient);
- assertEquals("42", response.getResponse().get("requestid"));
- RequestStatusState state = getRequestStateAfterCompletion("42", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("CreateCollection task did not complete!", RequestStatusState.COMPLETED, state);
//Add a few documents to shard1
@@ -116,59 +106,48 @@ public class CollectionsAPIAsyncDistributedZkTest extends AbstractFullDistribZkT
doc.addField("_route_", "shard1");
docs.add(doc);
}
- cloudClient.add(collection, docs);
- cloudClient.commit(collection);
+ client.add(collection, docs);
+ client.commit(collection);
SolrQuery query = new SolrQuery("*:*");
query.set("shards", "shard1");
- assertEquals(numDocs, cloudClient.query(collection, query).getResults().getNumFound());
+ assertEquals(numDocs, client.query(collection, query).getResults().getNumFound());
- CollectionAdminRequest.Reload reloadCollection = new CollectionAdminRequest.Reload();
- reloadCollection.setCollectionName(collection).setAsyncId("43");
- response = reloadCollection.process(cloudClient);
- assertEquals("43", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("43", MAX_TIMEOUT_SECONDS, cloudClient);
+ state = new CollectionAdminRequest.Reload()
+ .setCollectionName(collection)
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("ReloadCollection did not complete", RequestStatusState.COMPLETED, state);
- CollectionAdminRequest.CreateShard createShard = new CollectionAdminRequest.CreateShard()
+ state = new CollectionAdminRequest.CreateShard()
.setCollectionName(collection)
.setShardName("shard2")
- .setAsyncId("44");
- response = createShard.process(cloudClient);
- assertEquals("44", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("44", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("CreateShard did not complete", RequestStatusState.COMPLETED, state);
//Add a doc to shard2 to make sure shard2 was created properly
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", numDocs + 1);
doc.addField("_route_", "shard2");
- cloudClient.add(collection, doc);
- cloudClient.commit(collection);
+ client.add(collection, doc);
+ client.commit(collection);
query = new SolrQuery("*:*");
query.set("shards", "shard2");
- assertEquals(1, cloudClient.query(collection, query).getResults().getNumFound());
+ assertEquals(1, client.query(collection, query).getResults().getNumFound());
- CollectionAdminRequest.DeleteShard deleteShard = new CollectionAdminRequest.DeleteShard()
+ state = new CollectionAdminRequest.DeleteShard()
.setCollectionName(collection)
.setShardName("shard2")
- .setAsyncId("45");
- response = deleteShard.process(cloudClient);
- assertEquals("45", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("45", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("DeleteShard did not complete", RequestStatusState.COMPLETED, state);
- CollectionAdminRequest.AddReplica addReplica = new CollectionAdminRequest.AddReplica()
+ state = new CollectionAdminRequest.AddReplica()
.setCollectionName(collection)
.setShardName("shard1")
- .setAsyncId("46");
- response = addReplica.process(cloudClient);
- assertEquals("46", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("46", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("AddReplica did not complete", RequestStatusState.COMPLETED, state);
//cloudClient watch might take a couple of seconds to reflect it
- Slice shard1 = cloudClient.getZkStateReader().getClusterState().getSlice(collection, "shard1");
+ Slice shard1 = client.getZkStateReader().getClusterState().getSlice(collection, "shard1");
int count = 0;
while (shard1.getReplicas().size() != 2) {
if (count++ > 1000) {
@@ -177,51 +156,40 @@ public class CollectionsAPIAsyncDistributedZkTest extends AbstractFullDistribZkT
Thread.sleep(100);
}
- CollectionAdminRequest.CreateAlias createAlias = new CollectionAdminRequest.CreateAlias()
+ state = new CollectionAdminRequest.CreateAlias()
.setAliasName("myalias")
.setAliasedCollections(collection)
- .setAsyncId("47");
- response = createAlias.process(cloudClient);
- assertEquals("47", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("47", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("CreateAlias did not complete", RequestStatusState.COMPLETED, state);
query = new SolrQuery("*:*");
query.set("shards", "shard1");
- assertEquals(numDocs, cloudClient.query("myalias", query).getResults().getNumFound());
+ assertEquals(numDocs, client.query("myalias", query).getResults().getNumFound());
- CollectionAdminRequest.DeleteAlias deleteAlias = new CollectionAdminRequest.DeleteAlias()
+ state = new CollectionAdminRequest.DeleteAlias()
.setAliasName("myalias")
- .setAsyncId("48");
- response = deleteAlias.process(cloudClient);
- assertEquals("48", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("48", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("DeleteAlias did not complete", RequestStatusState.COMPLETED, state);
try {
- cloudClient.query("myalias", query);
+ client.query("myalias", query);
fail("Alias should not exist");
} catch (SolrException e) {
//expected
}
String replica = shard1.getReplicas().iterator().next().getName();
- CollectionAdminRequest.DeleteReplica deleteReplica = new CollectionAdminRequest.DeleteReplica()
+ state = new CollectionAdminRequest.DeleteReplica()
.setCollectionName(collection)
.setShardName("shard1")
.setReplica(replica)
- .setAsyncId("47");
- response = deleteReplica.process(cloudClient);
- assertEquals("47", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("47", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("DeleteReplica did not complete", RequestStatusState.COMPLETED, state);
- CollectionAdminRequest.Delete deleteCollection = new CollectionAdminRequest.Delete()
+ state = new CollectionAdminRequest.Delete()
.setCollectionName(collection)
- .setAsyncId("48");
- response = deleteCollection.process(cloudClient);
- assertEquals("48", response.getResponse().get("requestid"));
- state = getRequestStateAfterCompletion("48", MAX_TIMEOUT_SECONDS, cloudClient);
+ .processAndWait(client, MAX_TIMEOUT_SECONDS);
assertSame("DeleteCollection did not complete", RequestStatusState.COMPLETED, state);
}
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5b7be9d1/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
index c5d27a9..ab02a3e 100644
--- a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
@@ -161,7 +161,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/permissions[2]/name", "collection-admin-edit", 20);
CollectionAdminRequest.Reload reload = new CollectionAdminRequest.Reload();
- reload.setCollectionName(cloudSolrClient.getDefaultCollection());
+ reload.setCollectionName(defaultCollName);
HttpSolrClient solrClient = new HttpSolrClient(baseUrl);
try {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5b7be9d1/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
index a7d71ca..c9c8c39 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
@@ -21,10 +21,15 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.CollectionAdminResponse;
+import org.apache.solr.client.solrj.response.RequestStatusState;
import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.DocCollection;
@@ -37,33 +42,28 @@ import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ContentStream;
+import org.apache.solr.common.util.NamedList;
/**
* This class is experimental and subject to change.
*
* @since solr 4.5
*/
-public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q>> extends SolrRequest<CollectionAdminResponse> {
+public abstract class CollectionAdminRequest<T extends CollectionAdminResponse> extends SolrRequest<T> {
- protected CollectionAction action = null;
+ protected final CollectionAction action;
private static String PROPERTY_PREFIX = "property.";
- protected CollectionAdminRequest setAction(CollectionAction action) {
- this.action = action;
- return this;
- }
-
- public CollectionAdminRequest() {
- super(METHOD.GET, "/admin/collections");
+ public CollectionAdminRequest(CollectionAction action) {
+ this("/admin/collections", action);
}
- public CollectionAdminRequest(String path) {
+ public CollectionAdminRequest(String path, CollectionAction action) {
super(METHOD.GET, path);
+ this.action = action;
}
- protected abstract Q getThis();
-
@Override
public SolrParams getParams() {
if (action == null) {
@@ -79,11 +79,6 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return null;
}
- @Override
- protected CollectionAdminResponse createResponse(SolrClient client) {
- return new CollectionAdminResponse();
- }
-
protected void addProperties(ModifiableSolrParams params, Properties props) {
Iterator<Map.Entry<Object, Object>> iter = props.entrySet().iterator();
while(iter.hasNext()) {
@@ -94,18 +89,84 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
}
- protected abstract static class AsyncCollectionAdminRequest <T extends CollectionAdminRequest<T>> extends CollectionAdminRequest<T> {
- protected String asyncId = null;
+ protected abstract static class AsyncCollectionAdminRequest extends CollectionAdminRequest<CollectionAdminResponse> {
- public final T setAsyncId(String asyncId) {
- this.asyncId = asyncId;
- return getThis();
+ public AsyncCollectionAdminRequest(CollectionAction action) {
+ super(action);
}
+ @Override
+ protected CollectionAdminResponse createResponse(SolrClient client) {
+ return new CollectionAdminResponse();
+ }
+
+ private static String generateAsyncId() {
+ return UUID.randomUUID().toString();
+ }
+
+ protected String asyncId = null;
+
public String getAsyncId() {
return asyncId;
}
+ /**
+ * @deprecated Use {@link #processAsync(String, SolrClient)} or {@link #processAsync(SolrClient)}
+ */
+ @Deprecated
+ public abstract AsyncCollectionAdminRequest setAsyncId(String id);
+
+ /**
+ * Process this request asynchronously, generating and returning a request id
+ * @param client a Solr client
+ * @return the request id
+ * @see CollectionAdminRequest.RequestStatus
+ */
+ public String processAsync(SolrClient client) throws IOException, SolrServerException {
+ return processAsync(generateAsyncId(), client);
+ }
+
+ /**
+ * Process this request asynchronously, using a specified request id
+ * @param asyncId the request id
+ * @param client a Solr client
+ * @return the request id
+ */
+ public String processAsync(String asyncId, SolrClient client) throws IOException, SolrServerException {
+ this.asyncId = asyncId;
+ NamedList<Object> resp = client.request(this);
+ if (resp.get("error") != null) {
+ throw new SolrServerException((String)resp.get("error"));
+ }
+ return (String) resp.get("requestid");
+ }
+
+ /**
+ * Send this request to a Solr server, and wait (up to a timeout) for the request to
+ * complete or fail
+ * @param client a Solr client
+ * @param timeoutSeconds the maximum time to wait
+ * @return the status of the request on completion or timeout
+ */
+ public RequestStatusState processAndWait(SolrClient client, long timeoutSeconds)
+ throws SolrServerException, InterruptedException, IOException {
+ return processAndWait(generateAsyncId(), client, timeoutSeconds);
+ }
+
+ /**
+ * Send this request to a Solr server, and wait (up to a timeout) for the request to
+ * complete or fail
+ * @param asyncId an id for the request
+ * @param client a Solr client
+ * @param timeoutSeconds the maximum time to wait
+ * @return the status of the request on completion or timeout
+ */
+ public RequestStatusState processAndWait(String asyncId, SolrClient client, long timeoutSeconds)
+ throws IOException, SolrServerException, InterruptedException {
+ processAsync(asyncId, client);
+ return new RequestStatus().setRequestId(asyncId).waitFor(client, timeoutSeconds);
+ }
+
@Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
@@ -116,121 +177,110 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
}
- //---------------------------------------------------------------------------------------
- //
- //---------------------------------------------------------------------------------------
+ protected abstract static class AsyncCollectionSpecificAdminRequest extends AsyncCollectionAdminRequest {
- protected abstract static class CollectionSpecificAdminRequest <T extends CollectionAdminRequest<T>> extends CollectionAdminRequest<T> {
- protected String collection = null;
+ protected String collection;
- public T setCollectionName(String collectionName) {
- this.collection = collectionName;
- return getThis();
+ public AsyncCollectionSpecificAdminRequest(CollectionAction action) {
+ super(action);
}
- public final String getCollectionName() {
- return collection;
- }
+ public abstract AsyncCollectionSpecificAdminRequest setCollectionName(String collection);
@Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+ if (collection == null)
+ throw new IllegalArgumentException("You must call setCollectionName() on this request");
params.set(CoreAdminParams.NAME, collection);
return params;
}
}
- protected abstract static class CollectionSpecificAsyncAdminRequest<T extends CollectionAdminRequest<T>> extends CollectionSpecificAdminRequest<T> {
- protected String asyncId = null;
+ protected abstract static class AsyncShardSpecificAdminRequest extends AsyncCollectionAdminRequest {
- public final T setAsyncId(String asyncId) {
- this.asyncId = asyncId;
- return getThis();
- }
+ protected String collection;
+ protected String shard;
- public String getAsyncId() {
- return asyncId;
+ public AsyncShardSpecificAdminRequest(CollectionAction action) {
+ super(action);
}
+ public abstract AsyncShardSpecificAdminRequest setCollectionName(String collection);
+
+ public abstract AsyncShardSpecificAdminRequest setShardName(String shard);
+
@Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
- if (asyncId != null) {
- params.set(CommonAdminParams.ASYNC, asyncId);
- }
+ if (collection == null)
+ throw new IllegalArgumentException("You must call setCollectionName() on this request");
+ if (shard == null)
+ throw new IllegalArgumentException("You must call setShardName() on this request");
+ params.set(CoreAdminParams.COLLECTION, collection);
+ params.set(CoreAdminParams.SHARD, shard);
return params;
}
}
- protected abstract static class CollectionShardAdminRequest <T extends CollectionAdminRequest<T>> extends CollectionAdminRequest<T> {
- protected String shardName = null;
- protected String collection = null;
+ protected abstract static class ShardSpecificAdminRequest extends CollectionAdminRequest {
- public T setCollectionName(String collectionName) {
- this.collection = collectionName;
- return getThis();
- }
+ protected String collection;
+ protected String shard;
- public String getCollectionName() {
- return collection;
+ public ShardSpecificAdminRequest(CollectionAction action) {
+ super(action);
}
- public T setShardName(String shard) {
- this.shardName = shard;
- return getThis();
- }
+ public abstract ShardSpecificAdminRequest setCollectionName(String collection);
- public String getShardName() {
- return this.shardName;
- }
+ public abstract ShardSpecificAdminRequest setShardName(String shard);
@Override
public SolrParams getParams() {
- ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
+ ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+ if (collection == null)
+ throw new IllegalArgumentException("You must call setCollectionName() on this request");
+ if (shard == null)
+ throw new IllegalArgumentException("You must call setShardName() on this request");
params.set(CoreAdminParams.COLLECTION, collection);
- params.set(CoreAdminParams.SHARD, shardName);
+ params.set(CoreAdminParams.SHARD, shard);
return params;
}
+
+ @Override
+ protected SolrResponse createResponse(SolrClient client) {
+ return new CollectionAdminResponse();
+ }
}
- protected abstract static class CollectionShardAsyncAdminRequest<T extends CollectionAdminRequest<T>> extends CollectionShardAdminRequest<T> {
- protected String asyncId = null;
+ //---------------------------------------------------------------------------------------
+ //
+ //---------------------------------------------------------------------------------------
- public final T setAsyncId(String asyncId) {
- this.asyncId = asyncId;
- return getThis();
- }
- public String getAsyncId() {
- return asyncId;
+ protected abstract static class CollectionAdminRoleRequest extends AsyncCollectionAdminRequest {
+
+ protected String node;
+ protected String role;
+
+ public CollectionAdminRoleRequest(CollectionAction action) {
+ super(action);
}
@Override
- public SolrParams getParams() {
- ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
- if (asyncId != null) {
- params.set(CommonAdminParams.ASYNC, asyncId);
- }
- return params;
+ public CollectionAdminRoleRequest setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
}
- }
- protected abstract static class CollectionAdminRoleRequest <T extends CollectionAdminRequest<T>> extends AsyncCollectionAdminRequest<T> {
- protected String node;
- protected String role;
- public T setNode(String node) {
- this.node = node;
- return getThis();
- }
+ public abstract CollectionAdminRoleRequest setNode(String node);
public String getNode() {
return this.node;
}
- public T setRole(String role) {
- this.role = role;
- return getThis();
- }
+ public abstract CollectionAdminRoleRequest setRole(String role);
public String getRole() {
return this.role;
@@ -249,7 +299,8 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
/** Specific Collection API call implementations **/
// CREATE request
- public static class Create extends CollectionSpecificAsyncAdminRequest<Create> {
+ public static class Create extends AsyncCollectionSpecificAdminRequest {
+
protected String configName = null;
protected String createNodeSet = null;
protected String routerName;
@@ -263,8 +314,9 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
protected Boolean autoAddReplicas;
protected Integer stateFormat;
private String[] rule , snitch;
+
public Create() {
- action = CollectionAction.CREATE;
+ super(CollectionAction.CREATE);
}
public Create setConfigName(String config) { this.configName = config; return this; }
@@ -314,7 +366,6 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
*
* @throws IllegalArgumentException if the collection name contains invalid characters.
*/
- @Override
public Create setCollectionName(String collectionName) throws SolrException {
if (!SolrIdentifierValidator.validateCollectionName(collectionName)) {
throw new IllegalArgumentException(SolrIdentifierValidator.getIdentifierMessage(SolrIdentifierValidator.IdentifierType.COLLECTION,
@@ -324,6 +375,12 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return this;
}
+ @Override
+ public Create setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
public Properties getProperties() {
return properties;
}
@@ -337,8 +394,8 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
public SolrParams getParams() {
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
- params.set( "collection.configName", configName);
- params.set( "createNodeSet", createNodeSet);
+ params.set("collection.configName", configName);
+ params.set("createNodeSet", createNodeSet);
if (numShards != null) {
params.set( ZkStateReader.NUM_SHARDS_PROP, numShards);
}
@@ -367,51 +424,51 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected Create getThis() {
- return this;
- }
}
// RELOAD request
- public static class Reload extends CollectionSpecificAsyncAdminRequest<Reload> {
+ public static class Reload extends AsyncCollectionSpecificAdminRequest {
+
public Reload() {
- action = CollectionAction.RELOAD;
+ super(CollectionAction.RELOAD);
}
@Override
- public SolrParams getParams() {
- ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
- return params;
+ public Reload setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
}
@Override
- protected Reload getThis() {
+ public Reload setAsyncId(String id) {
+ this.asyncId = id;
return this;
}
}
// DELETE request
- public static class Delete extends CollectionSpecificAsyncAdminRequest<Delete> {
+ public static class Delete extends AsyncCollectionSpecificAdminRequest {
public Delete() {
- action = CollectionAction.DELETE;
+ super(CollectionAction.DELETE);
}
@Override
- public SolrParams getParams() {
- ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
- return params;
+ public Delete setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
}
@Override
- protected Delete getThis() {
+ public Delete setAsyncId(String id) {
+ this.asyncId = id;
return this;
}
}
// CREATESHARD request
- public static class CreateShard extends CollectionShardAsyncAdminRequest<CreateShard> {
+ public static class CreateShard extends AsyncShardSpecificAdminRequest {
+
protected String nodeSet;
protected Properties properties;
@@ -434,9 +491,15 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
public CreateShard() {
- action = CollectionAction.CREATESHARD;
+ super(CollectionAction.CREATESHARD);
}
-
+
+ @Override
+ public CreateShard setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
/**
* Provide the name of the shard to be created.
*
@@ -450,7 +513,13 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
throw new IllegalArgumentException(SolrIdentifierValidator.getIdentifierMessage(SolrIdentifierValidator.IdentifierType.SHARD,
shardName));
}
- this.shardName = shardName;
+ this.shard = shardName;
+ return this;
+ }
+
+ @Override
+ public CreateShard setAsyncId(String id) {
+ this.asyncId = id;
return this;
}
@@ -466,21 +535,18 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected CreateShard getThis() {
- return this;
- }
+
}
// SPLITSHARD request
- public static class SplitShard extends CollectionShardAsyncAdminRequest<SplitShard> {
+ public static class SplitShard extends AsyncShardSpecificAdminRequest {
protected String ranges;
protected String splitKey;
private Properties properties;
public SplitShard() {
- action = CollectionAction.SPLITSHARD;
+ super(CollectionAction.SPLITSHARD);
}
public SplitShard setRanges(String ranges) { this.ranges = ranges; return this; }
@@ -505,6 +571,24 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public SplitShard setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ @Override
+ public SplitShard setShardName(String shard) {
+ this.shard = shard;
+ return this;
+ }
+
+ @Override
+ public SplitShard setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
params.set( "ranges", ranges);
@@ -518,25 +602,16 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected SplitShard getThis() {
- return this;
- }
}
// DELETESHARD request
- public static class DeleteShard extends CollectionShardAsyncAdminRequest<DeleteShard> {
+ public static class DeleteShard extends AsyncShardSpecificAdminRequest {
private Boolean deleteInstanceDir;
private Boolean deleteDataDir;
public DeleteShard() {
- action = CollectionAction.DELETESHARD;
- }
-
- @Override
- protected DeleteShard getThis() {
- return this;
+ super(CollectionAction.DELETESHARD);
}
public Boolean getDeleteInstanceDir() {
@@ -558,6 +633,24 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public DeleteShard setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ @Override
+ public DeleteShard setShardName(String shard) {
+ this.shard = shard;
+ return this;
+ }
+
+ @Override
+ public DeleteShard setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
if (deleteInstanceDir != null) {
@@ -571,24 +664,43 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
// FORCELEADER request
- public static class ForceLeader extends CollectionShardAdminRequest<ForceLeader> {
+ public static class ForceLeader extends ShardSpecificAdminRequest {
public ForceLeader() {
- action = CollectionAction.FORCELEADER;
+ super(CollectionAction.FORCELEADER);
+ }
+
+
+ @Override
+ public ForceLeader setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
}
@Override
- protected ForceLeader getThis() {
+ public ForceLeader setShardName(String shard) {
+ this.shard = shard;
return this;
}
+
+ }
+
+ public static class RequestStatusResponse extends CollectionAdminResponse {
+
+ public RequestStatusState getRequestStatus() {
+ NamedList innerResponse = (NamedList) getResponse().get("status");
+ return RequestStatusState.fromKey((String) innerResponse.get("state"));
+ }
+
}
// REQUESTSTATUS request
- public static class RequestStatus extends CollectionAdminRequest<RequestStatus> {
- protected String requestId = null;
+ public static class RequestStatus extends CollectionAdminRequest<RequestStatusResponse> {
+
+ protected String requestId = null;
public RequestStatus() {
- action = CollectionAction.REQUESTSTATUS;
+ super(CollectionAction.REQUESTSTATUS);
}
public RequestStatus setRequestId(String requestId) {
@@ -603,23 +715,41 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
@Override
public SolrParams getParams() {
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
+ if (requestId == null)
+ throw new IllegalArgumentException("You must call setRequestId() on this request");
params.set(CoreAdminParams.REQUESTID, requestId);
return params;
}
@Override
- protected RequestStatus getThis() {
- return this;
+ protected RequestStatusResponse createResponse(SolrClient client) {
+ return new RequestStatusResponse();
+ }
+
+ public RequestStatusState waitFor(SolrClient client, long timeoutSeconds)
+ throws IOException, SolrServerException, InterruptedException {
+ long finishTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(timeoutSeconds);
+ RequestStatusState state = RequestStatusState.NOT_FOUND;
+ while (System.nanoTime() < finishTime) {
+ state = this.process(client).getRequestStatus();
+ if (state == RequestStatusState.COMPLETED || state == RequestStatusState.FAILED) {
+ new DeleteStatus().setRequestId(requestId).process(client);
+ return state;
+ }
+ TimeUnit.SECONDS.sleep(1);
+ }
+ return state;
}
}
// DELETESTATUS request
- public static class DeleteStatus extends CollectionAdminRequest<DeleteStatus> {
+ public static class DeleteStatus extends CollectionAdminRequest<CollectionAdminResponse> {
+
protected String requestId = null;
protected Boolean flush = null;
public DeleteStatus() {
- action = CollectionAction.DELETESTATUS;
+ super(CollectionAction.DELETESTATUS);
}
public DeleteStatus setRequestId(String requestId) {
@@ -652,18 +782,20 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
- protected DeleteStatus getThis() {
- return this;
+ protected CollectionAdminResponse createResponse(SolrClient client) {
+ return new CollectionAdminResponse();
}
+
}
// CREATEALIAS request
- public static class CreateAlias extends AsyncCollectionAdminRequest<CreateAlias> {
+ public static class CreateAlias extends AsyncCollectionAdminRequest {
+
protected String aliasName;
protected String aliasedCollections;
public CreateAlias() {
- action = CollectionAction.CREATEALIAS;
+ super(CollectionAction.CREATEALIAS);
}
/**
@@ -696,6 +828,12 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public CreateAlias setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
params.set(CoreAdminParams.NAME, aliasName);
@@ -703,18 +841,15 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected CreateAlias getThis() {
- return this;
- }
}
// DELETEALIAS request
- public static class DeleteAlias extends AsyncCollectionAdminRequest<DeleteAlias> {
+ public static class DeleteAlias extends AsyncCollectionAdminRequest {
+
protected String aliasName;
public DeleteAlias() {
- action = CollectionAction.DELETEALIAS;
+ super(CollectionAction.DELETEALIAS);
}
public DeleteAlias setAliasName(String aliasName) {
@@ -723,20 +858,26 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public DeleteAlias setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
params.set(CoreAdminParams.NAME, aliasName);
return params;
}
- @Override
- protected DeleteAlias getThis() {
- return this;
- }
+
}
// ADDREPLICA request
- public static class AddReplica extends CollectionShardAsyncAdminRequest<AddReplica> {
+ public static class AddReplica extends AsyncCollectionAdminRequest {
+
+ protected String collection;
+ protected String shard;
protected String node;
protected String routeKey;
protected String instanceDir;
@@ -744,7 +885,7 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
protected Properties properties;
public AddReplica() {
- action = CollectionAction.ADDREPLICA;
+ super(CollectionAction.ADDREPLICA);
}
public Properties getProperties() {
@@ -792,16 +933,37 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return this;
}
+ public AddReplica setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ public AddReplica setShardName(String shard) {
+ this.shard = shard;
+ return this;
+ }
+
+ @Override
+ public AddReplica setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
@Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
- if (shardName == null || shardName.isEmpty()) {
- params.remove(CoreAdminParams.SHARD);
+ if (collection == null)
+ throw new IllegalArgumentException("You must call setCollection() on this request");
+ params.add(CoreAdminParams.COLLECTION, collection);
+ if (shard == null || shard.isEmpty()) {
if (routeKey == null) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Either shard or routeKey must be provided");
}
params.add(ShardParams._ROUTE_, routeKey);
}
+ else {
+ params.add(CoreAdminParams.SHARD, shard);
+ }
if (node != null) {
params.add("node", node);
}
@@ -817,14 +979,12 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected AddReplica getThis() {
- return this;
- }
+
}
// DELETEREPLICA request
- public static class DeleteReplica extends CollectionShardAsyncAdminRequest<DeleteReplica> {
+ public static class DeleteReplica extends AsyncShardSpecificAdminRequest {
+
protected String replica;
protected Boolean onlyIfDown;
private Boolean deleteDataDir;
@@ -832,7 +992,7 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
private Boolean deleteIndexDir;
public DeleteReplica() {
- action = CollectionAction.DELETEREPLICA;
+ super(CollectionAction.DELETEREPLICA);
}
public DeleteReplica setReplica(String replica) {
@@ -854,6 +1014,24 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public DeleteReplica setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ @Override
+ public DeleteReplica setShardName(String shard) {
+ this.shard = shard;
+ return this;
+ }
+
+ @Override
+ public DeleteReplica setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
params.set(ZkStateReader.REPLICA_PROP, this.replica);
@@ -873,11 +1051,6 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected DeleteReplica getThis() {
- return this;
- }
-
public Boolean getDeleteDataDir() {
return deleteDataDir;
}
@@ -898,12 +1071,13 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
// CLUSTERPROP request
- public static class ClusterProp extends CollectionAdminRequest<ClusterProp> {
+ public static class ClusterProp extends CollectionAdminRequest<CollectionAdminResponse> {
+
private String propertyName;
private String propertyValue;
public ClusterProp() {
- this.action = CollectionAction.CLUSTERPROP;
+ super(CollectionAction.CLUSTERPROP);
}
public ClusterProp setPropertyName(String propertyName) {
@@ -934,13 +1108,16 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
- protected ClusterProp getThis() {
- return this;
+ protected CollectionAdminResponse createResponse(SolrClient client) {
+ return new CollectionAdminResponse();
}
+
+
}
// MIGRATE request
- public static class Migrate extends AsyncCollectionAdminRequest<Migrate> {
+ public static class Migrate extends AsyncCollectionAdminRequest {
+
private String collection;
private String targetCollection;
private String splitKey;
@@ -948,7 +1125,7 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
private Properties properties;
public Migrate() {
- action = CollectionAction.MIGRATE;
+ super(CollectionAction.MIGRATE);
}
public Migrate setCollectionName(String collection) {
@@ -997,6 +1174,12 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public Migrate setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
params.set(CoreAdminParams.COLLECTION, collection);
@@ -1012,58 +1195,72 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected Migrate getThis() {
- return this;
- }
+
}
// ADDROLE request
- public static class AddRole extends CollectionAdminRoleRequest<AddRole> {
+ public static class AddRole extends CollectionAdminRoleRequest {
+
public AddRole() {
- action = CollectionAction.ADDROLE;
+ super(CollectionAction.ADDROLE);
}
@Override
- protected AddRole getThis() {
+ public AddRole setNode(String node) {
+ this.node = node;
+ return this;
+ }
+
+ @Override
+ public AddRole setRole(String role) {
+ this.role = role;
return this;
}
}
// REMOVEROLE request
- public static class RemoveRole extends CollectionAdminRoleRequest<RemoveRole> {
+ public static class RemoveRole extends CollectionAdminRoleRequest {
+
public RemoveRole() {
- action = CollectionAction.REMOVEROLE;
+ super(CollectionAction.REMOVEROLE);
}
@Override
- protected RemoveRole getThis() {
+ public RemoveRole setNode(String node) {
+ this.node = node;
+ return this;
+ }
+
+ @Override
+ public RemoveRole setRole(String role) {
+ this.role = role;
return this;
}
}
// OVERSEERSTATUS request
- public static class OverseerStatus extends AsyncCollectionAdminRequest<OverseerStatus> {
+ public static class OverseerStatus extends AsyncCollectionAdminRequest {
public OverseerStatus () {
- action = CollectionAction.OVERSEERSTATUS;
+ super(CollectionAction.OVERSEERSTATUS);
}
@Override
- protected OverseerStatus getThis() {
+ public OverseerStatus setAsyncId(String id) {
+ this.asyncId = id;
return this;
}
}
// CLUSTERSTATUS request
- public static class ClusterStatus extends CollectionAdminRequest<ClusterStatus> {
+ public static class ClusterStatus extends CollectionAdminRequest<CollectionAdminResponse> {
protected String shardName = null;
protected String collection = null;
protected String routeKey = null;
public ClusterStatus () {
- action = CollectionAction.CLUSTERSTATUS;
+ super(CollectionAction.CLUSTERSTATUS);
}
public ClusterStatus setCollectionName(String collectionName) {
@@ -1109,32 +1306,35 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
- protected ClusterStatus getThis() {
- return this;
+ protected CollectionAdminResponse createResponse(SolrClient client) {
+ return new CollectionAdminResponse();
}
+
+
}
// LIST request
- public static class List extends CollectionAdminRequest<List> {
+ public static class List extends CollectionAdminRequest<CollectionAdminResponse> {
public List () {
- action = CollectionAction.LIST;
+ super(CollectionAction.LIST);
}
@Override
- protected List getThis() {
- return this;
+ protected CollectionAdminResponse createResponse(SolrClient client) {
+ return new CollectionAdminResponse();
}
}
// ADDREPLICAPROP request
- public static class AddReplicaProp extends CollectionShardAsyncAdminRequest<AddReplicaProp> {
+ public static class AddReplicaProp extends AsyncShardSpecificAdminRequest {
+
private String replica;
private String propertyName;
private String propertyValue;
private Boolean shardUnique;
public AddReplicaProp() {
- action = CollectionAction.ADDREPLICAPROP;
+ super(CollectionAction.ADDREPLICAPROP);
}
public String getReplica() {
@@ -1174,6 +1374,24 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public AddReplicaProp setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ @Override
+ public AddReplicaProp setShardName(String shard) {
+ this.shard = shard;
+ return this;
+ }
+
+ @Override
+ public AddReplicaProp setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
params.set(CoreAdminParams.REPLICA, replica);
@@ -1187,19 +1405,16 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected AddReplicaProp getThis() {
- return this;
- }
}
// DELETEREPLICAPROP request
- public static class DeleteReplicaProp extends CollectionShardAsyncAdminRequest<DeleteReplicaProp> {
+ public static class DeleteReplicaProp extends AsyncShardSpecificAdminRequest {
+
private String replica;
private String propertyName;
public DeleteReplicaProp() {
- this.action = CollectionAction.DELETEREPLICAPROP;
+ super(CollectionAction.DELETEREPLICAPROP);
}
public String getReplica() {
@@ -1221,6 +1436,24 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public DeleteReplicaProp setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
+ }
+
+ @Override
+ public DeleteReplicaProp setShardName(String shard) {
+ this.shard = shard;
+ return this;
+ }
+
+ @Override
+ public DeleteReplicaProp setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
params.set("replica", replica);
@@ -1228,44 +1461,49 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
return params;
}
- @Override
- protected DeleteReplicaProp getThis() {
- return this;
- }
+
}
// MIGRATECLUSTERSTATE request
- public static class MigrateClusterState extends CollectionShardAsyncAdminRequest<MigrateClusterState> {
+ public static class MigrateClusterState extends AsyncCollectionAdminRequest {
+
+ protected String collection;
public MigrateClusterState() {
- this.action = CollectionAction.MIGRATESTATEFORMAT;
+ super(CollectionAction.MIGRATESTATEFORMAT);
}
- @Override
- public MigrateClusterState setShardName(String shard) {
- throw new UnsupportedOperationException();
+ public MigrateClusterState setCollectionName(String collection) {
+ this.collection = collection;
+ return this;
}
@Override
- public String getShardName() {
- throw new UnsupportedOperationException();
+ public MigrateClusterState setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
}
@Override
- protected MigrateClusterState getThis() {
- return this;
+ public SolrParams getParams() {
+ ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
+ if (collection == null)
+ throw new IllegalArgumentException("You must call setCollection() on this request");
+ params.set(CoreAdminParams.COLLECTION, collection);
+ return params;
}
}
// BALANCESHARDUNIQUE request
- public static class BalanceShardUnique extends AsyncCollectionAdminRequest<BalanceShardUnique> {
+ public static class BalanceShardUnique extends AsyncCollectionAdminRequest {
+
protected String collection;
protected String propertyName;
protected Boolean onlyActiveNodes;
protected Boolean shardUnique;
public BalanceShardUnique() {
- this.action = CollectionAction.BALANCESHARDUNIQUE;
+ super(CollectionAction.BALANCESHARDUNIQUE);
}
public String getPropertyName() {
@@ -1305,20 +1543,23 @@ public abstract class CollectionAdminRequest <Q extends CollectionAdminRequest<Q
}
@Override
+ public BalanceShardUnique setAsyncId(String id) {
+ this.asyncId = id;
+ return this;
+ }
+
+ @Override
public SolrParams getParams() {
ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
params.set(CoreAdminParams.COLLECTION, collection);
params.set("property", propertyName);
- if(onlyActiveNodes != null)
+ if (onlyActiveNodes != null)
params.set("onlyactivenodes", onlyActiveNodes);
- if(shardUnique != null)
+ if (shardUnique != null)
params.set("shardUnique", shardUnique);
return params;
}
- @Override
- protected BalanceShardUnique getThis() {
- return this;
- }
}
+
}
[29/50] [abbrv] lucene-solr git commit: SOLR-8736: schema GET
operations on fields, dynamicFields, fieldTypes, copyField have less details
Posted by no...@apache.org.
SOLR-8736: schema GET operations on fields, dynamicFields, fieldTypes, copyField have less details
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/5ea6ee73
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/5ea6ee73
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/5ea6ee73
Branch: refs/heads/apiv2
Commit: 5ea6ee7362d5020d6a0b80f9c0efcb83b7bee196
Parents: bfd58bc
Author: Noble Paul <no...@apache.org>
Authored: Tue Mar 8 18:00:12 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Mar 8 18:00:12 2016 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/5ea6ee73/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index b71c63b..4a14786 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -109,7 +109,8 @@ Upgrading from Solr 5.x
* When requesting stats in date fields, "sum" is now a double value instead of a date. See SOLR-8671
-* SOLR-8736: The deprecated GET methods for schema are now accessible and implemented differently
+* SOLR-8736: The deprecated GET methods for schema are now accessible through the bulk API. The output
+ has less details and is not backward compatible.
Detailed Change List
----------------------
[44/50] [abbrv] lucene-solr git commit: SOLR-8799: Improve error
message when tuple can't be read by SolrJ JDBC
Posted by no...@apache.org.
SOLR-8799: Improve error message when tuple can't be read by SolrJ JDBC
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/56ad6e5d
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/56ad6e5d
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/56ad6e5d
Branch: refs/heads/apiv2
Commit: 56ad6e5d8a3d92f7ea496c598c2097aa572263cc
Parents: 4384627
Author: jbernste <jb...@apache.org>
Authored: Tue Mar 8 15:21:19 2016 -0500
Committer: jbernste <jb...@apache.org>
Committed: Tue Mar 8 15:22:42 2016 -0500
----------------------------------------------------------------------
.../solr/client/solrj/io/sql/ResultSetImpl.java | 2 +-
.../apache/solr/client/solrj/io/sql/JdbcTest.java | 15 +++++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/56ad6e5d/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ResultSetImpl.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ResultSetImpl.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ResultSetImpl.java
index e2f8cf0..0aa3a4b 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ResultSetImpl.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/ResultSetImpl.java
@@ -78,7 +78,7 @@ class ResultSetImpl implements ResultSet {
this.firstTuple = this.solrStream.read();
this.solrStream.pushBack(firstTuple);
} catch (IOException e) {
- throw new SQLException("Couldn't read first tuple", e);
+ throw new SQLException(e);
}
this.resultSetMetaData = new ResultSetMetaDataImpl(this);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/56ad6e5d/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java
index e1e9739..572491e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/sql/JdbcTest.java
@@ -396,6 +396,21 @@ public class JdbcTest extends AbstractFullDistribZkTestBase {
}
}
+
+ //Test error propagation
+ props = new Properties();
+ props.put("aggregationMode", "facet");
+ try (Connection con = DriverManager.getConnection("jdbc:solr://" + zkHost + "?collection=collection1", props)) {
+ try (Statement stmt = con.createStatement()) {
+ try (ResultSet rs = stmt.executeQuery("select crap from collection1 group by a_s " +
+ "order by sum(a_f) desc")) {
+ } catch (Exception e) {
+ String errorMessage = e.getMessage();
+ assertTrue(errorMessage.contains("Group by queries must include atleast one aggregate function"));
+ }
+ }
+ }
+
testDriverMetadata();
}
[32/50] [abbrv] lucene-solr git commit: Merge remote-tracking branch
'origin/master'
Posted by no...@apache.org.
Merge remote-tracking branch 'origin/master'
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/dd1dd46b
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/dd1dd46b
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/dd1dd46b
Branch: refs/heads/apiv2
Commit: dd1dd46b8eca97e72207c402144d0d4ae0b08259
Parents: e70c638 862bf7b
Author: Noble Paul <no...@apache.org>
Authored: Tue Mar 8 18:54:20 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Mar 8 18:54:20 2016 +0530
----------------------------------------------------------------------
.../index/BaseStoredFieldsFormatTestCase.java | 53 ++++++++------------
1 file changed, 22 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
[31/50] [abbrv] lucene-solr git commit: SOLR-8766: deprecated
tag in solrconfig.xml is removed
Posted by no...@apache.org.
SOLR-8766: deprecated <admin> tag in solrconfig.xml is removed
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/e70c638b
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/e70c638b
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/e70c638b
Branch: refs/heads/apiv2
Commit: e70c638bcf5b2b76f3b2dd70fed55ccd6b25411d
Parents: 5ea6ee7
Author: Noble Paul <no...@apache.org>
Authored: Tue Mar 8 18:49:44 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Mar 8 18:53:59 2016 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 2 ++
.../src/test-files/solr/collection1/conf/solrconfig.xml | 6 ------
.../src/test-files/solr/minimr/conf/solrconfig.xml | 6 ------
.../src/test-files/solr/mrunit/conf/solrconfig.xml | 7 -------
.../solr/solrcelltest/collection1/conf/solrconfig.xml | 6 ------
.../src/test-files/solr/solrcloud/conf/solrconfig.xml | 6 ------
solr/example/example-DIH/solr/db/conf/solrconfig.xml | 6 ------
solr/example/example-DIH/solr/mail/conf/solrconfig.xml | 6 ------
solr/example/example-DIH/solr/rss/conf/solrconfig.xml | 6 ------
solr/example/example-DIH/solr/solr/conf/solrconfig.xml | 6 ------
solr/example/example-DIH/solr/tika/conf/solrconfig.xml | 7 -------
solr/example/files/conf/solrconfig.xml | 6 ------
solr/server/solr/configsets/basic_configs/conf/solrconfig.xml | 5 -----
.../configsets/data_driven_schema_configs/conf/solrconfig.xml | 7 -------
.../sample_techproducts_configs/conf/solrconfig.xml | 6 ------
15 files changed, 2 insertions(+), 86 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 4a14786..02021c5 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -405,6 +405,8 @@ Other Changes
* SOLR-8736: schema GET operations on fields, dynamicFields, fieldTypes, copyField are
reimplemented as a part of the bulk API with less details (noble)
+* SOLR-8766 : deprecated <admin> tag in solrconfig.xml is removed (noble)
+
================== 5.5.1 ==================
Bug Fixes
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml
index b8d1ca6..ab1acd9 100644
--- a/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml
+++ b/solr/contrib/morphlines-core/src/test-files/solr/collection1/conf/solrconfig.xml
@@ -1487,11 +1487,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/contrib/morphlines-core/src/test-files/solr/minimr/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/contrib/morphlines-core/src/test-files/solr/minimr/conf/solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/minimr/conf/solrconfig.xml
index 65637c1..f5ce41b 100644
--- a/solr/contrib/morphlines-core/src/test-files/solr/minimr/conf/solrconfig.xml
+++ b/solr/contrib/morphlines-core/src/test-files/solr/minimr/conf/solrconfig.xml
@@ -1508,10 +1508,4 @@
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/contrib/morphlines-core/src/test-files/solr/mrunit/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/contrib/morphlines-core/src/test-files/solr/mrunit/conf/solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/mrunit/conf/solrconfig.xml
index 691643f..d40b16d 100644
--- a/solr/contrib/morphlines-core/src/test-files/solr/mrunit/conf/solrconfig.xml
+++ b/solr/contrib/morphlines-core/src/test-files/solr/mrunit/conf/solrconfig.xml
@@ -1511,11 +1511,4 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/contrib/morphlines-core/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/contrib/morphlines-core/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml
index b8d1ca6..ab1acd9 100644
--- a/solr/contrib/morphlines-core/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml
+++ b/solr/contrib/morphlines-core/src/test-files/solr/solrcelltest/collection1/conf/solrconfig.xml
@@ -1487,11 +1487,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/contrib/morphlines-core/src/test-files/solr/solrcloud/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/contrib/morphlines-core/src/test-files/solr/solrcloud/conf/solrconfig.xml b/solr/contrib/morphlines-core/src/test-files/solr/solrcloud/conf/solrconfig.xml
index 336c789..9d33201 100644
--- a/solr/contrib/morphlines-core/src/test-files/solr/solrcloud/conf/solrconfig.xml
+++ b/solr/contrib/morphlines-core/src/test-files/solr/solrcloud/conf/solrconfig.xml
@@ -1510,11 +1510,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/example/example-DIH/solr/db/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/example-DIH/solr/db/conf/solrconfig.xml b/solr/example/example-DIH/solr/db/conf/solrconfig.xml
index e541565..339e77f 100644
--- a/solr/example/example-DIH/solr/db/conf/solrconfig.xml
+++ b/solr/example/example-DIH/solr/db/conf/solrconfig.xml
@@ -1486,11 +1486,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/example-DIH/solr/mail/conf/solrconfig.xml b/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
index 30c61a8..0698704 100644
--- a/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
+++ b/solr/example/example-DIH/solr/mail/conf/solrconfig.xml
@@ -1489,11 +1489,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/example-DIH/solr/rss/conf/solrconfig.xml b/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
index a6597a1..152321e 100644
--- a/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
+++ b/solr/example/example-DIH/solr/rss/conf/solrconfig.xml
@@ -1485,11 +1485,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/example-DIH/solr/solr/conf/solrconfig.xml b/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
index 84469d9..7091b9d 100644
--- a/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
+++ b/solr/example/example-DIH/solr/solr/conf/solrconfig.xml
@@ -1485,11 +1485,5 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/example-DIH/solr/tika/conf/solrconfig.xml b/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
index 9c770a0..c3d0168 100644
--- a/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
+++ b/solr/example/example-DIH/solr/tika/conf/solrconfig.xml
@@ -1463,11 +1463,4 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/example/files/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/example/files/conf/solrconfig.xml b/solr/example/files/conf/solrconfig.xml
index 4dea6c9..cab776a 100644
--- a/solr/example/files/conf/solrconfig.xml
+++ b/solr/example/files/conf/solrconfig.xml
@@ -1505,10 +1505,4 @@
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/server/solr/configsets/basic_configs/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/server/solr/configsets/basic_configs/conf/solrconfig.xml b/solr/server/solr/configsets/basic_configs/conf/solrconfig.xml
index 6b2f745..9ee1ff5 100644
--- a/solr/server/solr/configsets/basic_configs/conf/solrconfig.xml
+++ b/solr/server/solr/configsets/basic_configs/conf/solrconfig.xml
@@ -559,9 +559,4 @@
</arr>
</requestHandler>
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml b/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
index 72d7bdf..6d9c8b5 100644
--- a/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
+++ b/solr/server/solr/configsets/data_driven_schema_configs/conf/solrconfig.xml
@@ -1479,11 +1479,4 @@
EditorialMarkerFactory will do exactly that:
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e70c638b/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
----------------------------------------------------------------------
diff --git a/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml b/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
index 900a123..c8f52a6 100644
--- a/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
+++ b/solr/server/solr/configsets/sample_techproducts_configs/conf/solrconfig.xml
@@ -1698,10 +1698,4 @@
<transformer name="qecBooster" class="org.apache.solr.response.transform.EditorialMarkerFactory" />
-->
-
- <!-- Legacy config for the admin interface -->
- <admin>
- <defaultQuery>*:*</defaultQuery>
- </admin>
-
</config>
[24/50] [abbrv] lucene-solr git commit: SOLR-6926: Remove deprecated
"ant example"; replaced by "ant server" a year ago
Posted by no...@apache.org.
SOLR-6926: Remove deprecated "ant example"; replaced by "ant server" a year ago
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/a0a571ca
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/a0a571ca
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/a0a571ca
Branch: refs/heads/apiv2
Commit: a0a571caa9777a8a6401b88ff9c4d2bb982055b8
Parents: f7f81c3
Author: David Smiley <ds...@apache.org>
Authored: Mon Mar 7 23:48:31 2016 -0500
Committer: David Smiley <ds...@apache.org>
Committed: Mon Mar 7 23:48:31 2016 -0500
----------------------------------------------------------------------
solr/build.xml | 14 --------------
1 file changed, 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a0a571ca/solr/build.xml
----------------------------------------------------------------------
diff --git a/solr/build.xml b/solr/build.xml
index 218bf8c..61503df 100644
--- a/solr/build.xml
+++ b/solr/build.xml
@@ -809,18 +809,4 @@
<contrib-crawl target="-append-module-dependencies-properties"/>
</target>
- <target name="example" depends="server">
- <!-- no description so -p doesn't list it -->
- <echo>
-
- ! ! ! NOTICE NOTICE NOTICE ! ! !
-
- 'ant example' is no longer recomended
-
- Use 'ant server' instead
-
- 'ant example' is going to be removed at some point
-
- </echo>
- </target>
</project>
[03/50] [abbrv] lucene-solr git commit: SOLR-8736: schema GET
operations on fields, dynamicFields, fieldTypes,
copyField are reimplemented as a part of the bulk API with less details. The
tests and write implementations are removed
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
index acc8c13..4319c3e 100644
--- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
@@ -39,6 +39,7 @@ import org.apache.lucene.uninverting.UninvertingReader;
import org.apache.lucene.util.Version;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
@@ -1352,6 +1353,10 @@ public class IndexSchema {
* Get a map of property name -> value for the whole schema.
*/
public SimpleOrderedMap<Object> getNamedPropertyValues() {
+ return getNamedPropertyValues(new MapSolrParams(Collections.EMPTY_MAP));
+
+ }
+ public SimpleOrderedMap<Object> getNamedPropertyValues(SolrParams params) {
SimpleOrderedMap<Object> topLevel = new SimpleOrderedMap<>();
topLevel.add(NAME, getSchemaName());
topLevel.add(VERSION, getVersion());
@@ -1372,19 +1377,19 @@ public class IndexSchema {
List<SimpleOrderedMap<Object>> fieldTypeProperties = new ArrayList<>();
SortedMap<String,FieldType> sortedFieldTypes = new TreeMap<>(fieldTypes);
for (FieldType fieldType : sortedFieldTypes.values()) {
- fieldTypeProperties.add(fieldType.getNamedPropertyValues(false));
+ fieldTypeProperties.add(fieldType.getNamedPropertyValues(params.getBool("showDefaults", false)));
}
topLevel.add(FIELD_TYPES, fieldTypeProperties);
List<SimpleOrderedMap<Object>> fieldProperties = new ArrayList<>();
SortedSet<String> fieldNames = new TreeSet<>(fields.keySet());
for (String fieldName : fieldNames) {
- fieldProperties.add(fields.get(fieldName).getNamedPropertyValues(false));
+ fieldProperties.add(fields.get(fieldName).getNamedPropertyValues(params.getBool("showDefaults", false)));
}
topLevel.add(FIELDS, fieldProperties);
List<SimpleOrderedMap<Object>> dynamicFieldProperties = new ArrayList<>();
for (IndexSchema.DynamicField dynamicField : dynamicFields) {
if ( ! dynamicField.getRegex().startsWith(INTERNAL_POLY_FIELD_PREFIX)) { // omit internal polyfields
- dynamicFieldProperties.add(dynamicField.getPrototype().getNamedPropertyValues(false));
+ dynamicFieldProperties.add(dynamicField.getPrototype().getNamedPropertyValues(params.getBool("showDefaults", false)));
}
}
topLevel.add(DYNAMIC_FIELDS, dynamicFieldProperties);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
index d87eb69..f291b2f 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -35,10 +35,12 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import com.google.common.collect.ImmutableSet;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
@@ -84,6 +86,7 @@ import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.response.QueryResponseWriter;
import org.apache.solr.response.QueryResponseWriterUtil;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.schema.IndexSchema;
import org.apache.solr.security.AuthenticationPlugin;
import org.apache.solr.security.AuthorizationContext;
import org.apache.solr.security.AuthorizationContext.CollectionRequest;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestClassNameShortening.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestClassNameShortening.java b/solr/core/src/test/org/apache/solr/rest/schema/TestClassNameShortening.java
index ddbd331..52ba10b 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestClassNameShortening.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestClassNameShortening.java
@@ -18,13 +18,14 @@ package org.apache.solr.rest.schema;
import org.apache.solr.util.RestTestBase;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.restlet.ext.servlet.ServerServlet;
import java.util.SortedMap;
import java.util.TreeMap;
-
+@Ignore
public class TestClassNameShortening extends RestTestBase {
@BeforeClass
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestCopyFieldCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestCopyFieldCollectionResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestCopyFieldCollectionResource.java
index 5eeee8c..c0f936d 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestCopyFieldCollectionResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestCopyFieldCollectionResource.java
@@ -30,73 +30,51 @@ public class TestCopyFieldCollectionResource extends SolrRestletTestBase {
+" and int[@name='maxChars'][.='200']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='title']"
- +" and str[@name='dest'][.='dest_sub_no_ast_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ +" and str[@name='dest'][.='dest_sub_no_ast_s']]",
- "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
+ "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
+" and str[@name='dest'][.='title']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
+" and str[@name='dest'][.='*_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
- +" and str[@name='dest'][.='*_dest_sub_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ +" and str[@name='dest'][.='*_dest_sub_s']]",
- "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
- +" and str[@name='dest'][.='dest_sub_no_ast_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
+ +" and str[@name='dest'][.='dest_sub_no_ast_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_src_sub_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
+" and str[@name='dest'][.='title']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_src_sub_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
+" and str[@name='dest'][.='*_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_src_sub_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
- +" and str[@name='dest'][.='*_dest_sub_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ +" and str[@name='dest'][.='*_dest_sub_s']]",
- "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_src_sub_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
- +" and str[@name='dest'][.='dest_sub_no_ast_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_src_sub_i']"
+ +" and str[@name='dest'][.='dest_sub_no_ast_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='src_sub_no_ast_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
+" and str[@name='dest'][.='*_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='src_sub_no_ast_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
- +" and str[@name='dest'][.='*_dest_sub_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ +" and str[@name='dest'][.='*_dest_sub_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='src_sub_no_ast_i']"
- +" and str[@name='sourceDynamicBase'][.='*_i']"
- +" and str[@name='dest'][.='dest_sub_no_ast_s']"
- +" and str[@name='destDynamicBase'][.='*_s']]",
+ +" and str[@name='dest'][.='dest_sub_no_ast_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='title_*']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_stemmed']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_lettertok']"
+" and str[@name='dest'][.='text']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='title_*']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_stemmed']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_lettertok']"
+" and str[@name='dest'][.='*_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='title_*']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_stemmed']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_lettertok']"
+" and str[@name='dest'][.='*_dest_sub_s']]",
"/response/arr[@name='copyFields']/lst[ str[@name='source'][.='title_*']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_stemmed']"
- +" and arr[@name='sourceExplicitFields']/str[.='title_lettertok']"
+" and str[@name='dest'][.='dest_sub_no_ast_s']]");
}
@@ -104,56 +82,22 @@ public class TestCopyFieldCollectionResource extends SolrRestletTestBase {
public void testJsonGetAllCopyFields() throws Exception {
assertJQ("/schema/copyfields?indent=on&wt=json",
"/copyFields/[1]=={'source':'src_sub_no_ast_i','dest':'title'}",
- "/copyFields/[7]=={'source':'title','dest':'dest_sub_no_ast_s','destDynamicBase':'*_s'}",
+ "/copyFields/[7]=={'source':'title','dest':'dest_sub_no_ast_s'}",
"/copyFields/[8]=={'source':'*_i','dest':'title'}",
"/copyFields/[9]=={'source':'*_i','dest':'*_s'}",
- "/copyFields/[10]=={'source':'*_i','dest':'*_dest_sub_s','destDynamicBase':'*_s'}",
- "/copyFields/[11]=={'source':'*_i','dest':'dest_sub_no_ast_s','destDynamicBase':'*_s'}",
+ "/copyFields/[10]=={'source':'*_i','dest':'*_dest_sub_s'}",
+ "/copyFields/[11]=={'source':'*_i','dest':'dest_sub_no_ast_s'}",
- "/copyFields/[12]=={'source':'*_src_sub_i','sourceDynamicBase':'*_i','dest':'title'}",
- "/copyFields/[13]=={'source':'*_src_sub_i','sourceDynamicBase':'*_i','dest':'*_s'}",
- "/copyFields/[14]=={'source':'*_src_sub_i','sourceDynamicBase':'*_i','dest':'*_dest_sub_s','destDynamicBase':'*_s'}",
- "/copyFields/[15]=={'source':'*_src_sub_i','sourceDynamicBase':'*_i','dest':'dest_sub_no_ast_s','destDynamicBase':'*_s'}",
+ "/copyFields/[12]=={'source':'*_src_sub_i','dest':'title'}",
+ "/copyFields/[13]=={'source':'*_src_sub_i','dest':'*_s'}",
+ "/copyFields/[14]=={'source':'*_src_sub_i','dest':'*_dest_sub_s'}",
+ "/copyFields/[15]=={'source':'*_src_sub_i','dest':'dest_sub_no_ast_s'}",
- "/copyFields/[16]=={'source':'src_sub_no_ast_i','sourceDynamicBase':'*_i','dest':'*_s'}",
- "/copyFields/[17]=={'source':'src_sub_no_ast_i','sourceDynamicBase':'*_i','dest':'*_dest_sub_s','destDynamicBase':'*_s'}",
- "/copyFields/[18]=={'source':'src_sub_no_ast_i','sourceDynamicBase':'*_i','dest':'dest_sub_no_ast_s','destDynamicBase':'*_s'}");
+ "/copyFields/[16]=={'source':'src_sub_no_ast_i','dest':'*_s'}",
+ "/copyFields/[17]=={'source':'src_sub_no_ast_i','dest':'*_dest_sub_s'}",
+ "/copyFields/[18]=={'source':'src_sub_no_ast_i','dest':'dest_sub_no_ast_s'}");
}
- @Test
- public void testRestrictSource() throws Exception {
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=title,*_i,*_src_sub_i,src_sub_no_ast_i",
- "count(/response/arr[@name='copyFields']/lst) = 16", // 4 + 4 + 4 + 4
- "count(/response/arr[@name='copyFields']/lst/str[@name='source'][.='title']) = 4",
- "count(/response/arr[@name='copyFields']/lst/str[@name='source'][.='*_i']) = 4",
- "count(/response/arr[@name='copyFields']/lst/str[@name='source'][.='*_src_sub_i']) = 4",
- "count(/response/arr[@name='copyFields']/lst/str[@name='source'][.='src_sub_no_ast_i']) = 4");
- }
-
- @Test
- public void testRestrictDest() throws Exception {
- assertQ("/schema/copyfields/?indent=on&wt=xml&dest.fl=title,*_s,*_dest_sub_s,dest_sub_no_ast_s",
- "count(/response/arr[@name='copyFields']/lst) = 16", // 3 + 4 + 4 + 5
- "count(/response/arr[@name='copyFields']/lst/str[@name='dest'][.='title']) = 3",
- "count(/response/arr[@name='copyFields']/lst/str[@name='dest'][.='*_s']) = 4",
- "count(/response/arr[@name='copyFields']/lst/str[@name='dest'][.='*_dest_sub_s']) = 4",
- "count(/response/arr[@name='copyFields']/lst/str[@name='dest'][.='dest_sub_no_ast_s']) = 5");
- }
-
- @Test
- public void testRestrictSourceAndDest() throws Exception {
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=title,*_i&dest.fl=title,dest_sub_no_ast_s",
- "count(/response/arr[@name='copyFields']/lst) = 3",
-
- "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='title']"
- +" and str[@name='dest'][.='dest_sub_no_ast_s']]",
-
- "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
- +" and str[@name='dest'][.='title']]",
-
- "/response/arr[@name='copyFields']/lst[ str[@name='source'][.='*_i']"
- +" and str[@name='dest'][.='dest_sub_no_ast_s']]");
- }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldCollectionResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldCollectionResource.java
index 318b28a..032bbad 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldCollectionResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldCollectionResource.java
@@ -30,39 +30,10 @@ public class TestDynamicFieldCollectionResource extends SolrRestletTestBase {
}
@Test
- public void testGetTwoDynamicFields() throws IOException {
- assertQ("/schema/dynamicfields?indent=on&wt=xml&fl=*_i,*_s",
- "count(/response/arr[@name='dynamicFields']/lst/str[@name='name']) = 2",
- "(/response/arr[@name='dynamicFields']/lst/str[@name='name'])[1] = '*_i'",
- "(/response/arr[@name='dynamicFields']/lst/str[@name='name'])[2] = '*_s'");
- }
-
- @Test
- public void testNotFoundDynamicFields() throws IOException {
- assertQ("/schema/dynamicfields?indent=on&wt=xml&fl=*_not_in_there,this_one_isnt_either_*",
- "count(/response/arr[@name='dynamicFields']) = 1",
- "count(/response/arr[@name='dynamicfields']/lst/str[@name='name']) = 0");
- }
-
- @Test
public void testJsonGetAllDynamicFields() throws Exception {
assertJQ("/schema/dynamicfields?indent=on",
"/dynamicFields/[0]/name=='*_coordinate'",
"/dynamicFields/[1]/name=='ignored_*'",
"/dynamicFields/[2]/name=='*_mfacet'");
}
-
- @Test
- public void testJsonGetTwoDynamicFields() throws Exception {
- assertJQ("/schema/dynamicfields?indent=on&fl=*_i,*_s&wt=xml", // assertJQ will fix the wt param to be json
- "/dynamicFields/[0]/name=='*_i'",
- "/dynamicFields/[1]/name=='*_s'");
- }
-
- @Test
- public void testJsonPostFieldsToNonMutableIndexSchema() throws Exception {
- assertJPost("/schema/dynamicfields",
- "[{\"name\":\"foobarbaz\", \"type\":\"text_general\", \"stored\":\"false\"}]",
- "/error/msg=='This IndexSchema is not mutable.'");
- }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldResource.java
index 54b17fc..7ca7953 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestDynamicFieldResource.java
@@ -67,11 +67,4 @@ public class TestDynamicFieldResource extends SolrRestletTestBase {
"/dynamicField/required==false",
"/dynamicField/tokenized==false");
}
-
- @Test
- public void testJsonPutFieldToNonMutableIndexSchema() throws Exception {
- assertJPut("/schema/dynamicfields/newfield_*",
- "{\"type\":\"text_general\", \"stored\":\"false\"}",
- "/error/msg=='This IndexSchema is not mutable.'");
- }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestFieldCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldCollectionResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldCollectionResource.java
index 571acc5..dd55415 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldCollectionResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldCollectionResource.java
@@ -30,45 +30,6 @@ public class TestFieldCollectionResource extends SolrRestletTestBase {
"(/response/arr[@name='fields']/lst/str[@name='name'])[3] = '_version_'");
}
- @Test
- public void testGetTwoFields() throws IOException {
- assertQ("/schema/fields?indent=on&wt=xml&fl=id,_version_",
- "count(/response/arr[@name='fields']/lst/str[@name='name']) = 2",
- "(/response/arr[@name='fields']/lst/str[@name='name'])[1] = 'id'",
- "(/response/arr[@name='fields']/lst/str[@name='name'])[2] = '_version_'");
- }
-
- @Test
- public void testGetThreeFieldsDontIncludeDynamic() throws IOException {
- //
- assertQ("/schema/fields?indent=on&wt=xml&fl=id,_version_,price_i",
- "count(/response/arr[@name='fields']/lst/str[@name='name']) = 2",
- "(/response/arr[@name='fields']/lst/str[@name='name'])[1] = 'id'",
- "(/response/arr[@name='fields']/lst/str[@name='name'])[2] = '_version_'");
- }
-
- @Test
- public void testGetThreeFieldsIncludeDynamic() throws IOException {
- assertQ("/schema/fields?indent=on&wt=xml&fl=id,_version_,price_i&includeDynamic=on",
-
- "count(/response/arr[@name='fields']/lst/str[@name='name']) = 3",
-
- "(/response/arr[@name='fields']/lst/str[@name='name'])[1] = 'id'",
-
- "(/response/arr[@name='fields']/lst/str[@name='name'])[2] = '_version_'",
-
- "(/response/arr[@name='fields']/lst/str[@name='name'])[3] = 'price_i'",
-
- "/response/arr[@name='fields']/lst[ str[@name='name']='price_i' "
- +" and str[@name='dynamicBase']='*_i']");
- }
-
- @Test
- public void testNotFoundFields() throws IOException {
- assertQ("/schema/fields?indent=on&wt=xml&fl=not_in_there,this_one_either",
- "count(/response/arr[@name='fields']) = 1",
- "count(/response/arr[@name='fields']/lst/str[@name='name']) = 0");
- }
@Test
public void testJsonGetAllFields() throws Exception {
@@ -78,10 +39,4 @@ public class TestFieldCollectionResource extends SolrRestletTestBase {
"/fields/[2]/name=='_version_'");
}
- @Test
- public void testJsonGetTwoFields() throws Exception {
- assertJQ("/schema/fields?indent=on&fl=id,_version_&wt=xml", // assertJQ should fix the wt param to be json
- "/fields/[0]/name=='id'",
- "/fields/[1]/name=='_version_'");
- }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestFieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldResource.java
index 711e3c0..627aee0 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldResource.java
@@ -72,18 +72,12 @@ public class TestFieldResource extends SolrRestletTestBase {
"/field/tokenized==true");
}
- @Test
- public void testGetFieldIncludeDynamic() throws Exception {
- assertQ("/schema/fields/some_crazy_name_i?indent=on&wt=xml&includeDynamic=true",
- "/response/lst[@name='field']/str[@name='name'] = 'some_crazy_name_i'",
- "/response/lst[@name='field']/str[@name='dynamicBase'] = '*_i'");
- }
-
+
@Test
public void testGetFieldDontShowDefaults() throws Exception {
String[] tests = {
"count(/response/lst[@name='field']) = 1",
- "count(/response/lst[@name='field']/*) = 7",
+ "count(/response/lst[@name='field']/*) = 6",
"/response/lst[@name='field']/str[@name='name'] = 'id'",
"/response/lst[@name='field']/str[@name='type'] = 'string'",
"/response/lst[@name='field']/bool[@name='indexed'] = 'true'",
@@ -95,17 +89,4 @@ public class TestFieldResource extends SolrRestletTestBase {
assertQ("/schema/fields/id?indent=on&wt=xml&showDefaults=false", tests);
}
- @Test
- public void testJsonPutFieldToNonMutableIndexSchema() throws Exception {
- assertJPut("/schema/fields/newfield",
- "{\"type\":\"text_general\", \"stored\":\"false\"}",
- "/error/msg=='This IndexSchema is not mutable.'");
- }
-
- @Test
- public void testJsonPostFieldsToNonMutableIndexSchema() throws Exception {
- assertJPost("/schema/fields",
- "[{\"name\":\"foobarbaz\", \"type\":\"text_general\", \"stored\":\"false\"}]",
- "/error/msg=='This IndexSchema is not mutable.'");
- }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeCollectionResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeCollectionResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeCollectionResource.java
index a61f644..53cd1c0 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeCollectionResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeCollectionResource.java
@@ -19,6 +19,7 @@ import org.apache.solr.rest.SolrRestletTestBase;
import org.junit.Test;
public class TestFieldTypeCollectionResource extends SolrRestletTestBase {
+
@Test
public void testGetAllFieldTypes() throws Exception {
assertQ("/schema/fieldtypes?indent=on&wt=xml",
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeResource.java
index 2f0c241..eb72aed 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeResource.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestFieldTypeResource.java
@@ -24,7 +24,7 @@ public class TestFieldTypeResource extends SolrRestletTestBase {
public void testGetFieldType() throws Exception {
assertQ("/schema/fieldtypes/float?indent=on&wt=xml&showDefaults=true",
"count(/response/lst[@name='fieldType']) = 1",
- "count(/response/lst[@name='fieldType']/*) = 18",
+ "count(/response/lst[@name='fieldType']/*) = 16",
"/response/lst[@name='fieldType']/str[@name='name'] = 'float'",
"/response/lst[@name='fieldType']/str[@name='class'] = 'solr.TrieFloatField'",
"/response/lst[@name='fieldType']/str[@name='precisionStep'] ='0'",
@@ -39,9 +39,7 @@ public class TestFieldTypeResource extends SolrRestletTestBase {
"/response/lst[@name='fieldType']/bool[@name='omitPositions'] = 'false'",
"/response/lst[@name='fieldType']/bool[@name='storeOffsetsWithPositions'] = 'false'",
"/response/lst[@name='fieldType']/bool[@name='multiValued'] = 'false'",
- "/response/lst[@name='fieldType']/bool[@name='tokenized'] = 'false'",
- "/response/lst[@name='fieldType']/arr[@name='fields']/str = 'weight'",
- "/response/lst[@name='fieldType']/arr[@name='dynamicFields']/str = '*_f'");
+ "/response/lst[@name='fieldType']/bool[@name='tokenized'] = 'false'");
}
@Test
@@ -69,22 +67,19 @@ public class TestFieldTypeResource extends SolrRestletTestBase {
"/fieldType/omitPositions==false",
"/fieldType/storeOffsetsWithPositions==false",
"/fieldType/multiValued==false",
- "/fieldType/tokenized==false",
- "/fieldType/fields==['weight']",
- "/fieldType/dynamicFields==['*_f']");
+ "/fieldType/tokenized==false");
}
@Test
public void testGetFieldTypeDontShowDefaults() throws Exception {
assertQ("/schema/fieldtypes/teststop?wt=xml&indent=on",
- "count(/response/lst[@name='fieldType']/*) = 5",
+ "count(/response/lst[@name='fieldType']/*) = 3",
"/response/lst[@name='fieldType']/str[@name='name'] = 'teststop'",
"/response/lst[@name='fieldType']/str[@name='class'] = 'solr.TextField'",
"/response/lst[@name='fieldType']/lst[@name='analyzer']/lst[@name='tokenizer']/str[@name='class'] = 'solr.LowerCaseTokenizerFactory'",
"/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst/str[@name='class'][.='solr.StandardFilterFactory']",
"/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst/str[@name='class'][.='solr.StopFilterFactory']",
- "/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst/str[@name='words'][.='stopwords.txt']",
- "/response/lst[@name='fieldType']/arr[@name='fields']/str[.='teststop']",
- "/response/lst[@name='fieldType']/arr[@name='dynamicFields']");
+ "/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst/str[@name='words'][.='stopwords.txt']"
+ );
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaDynamicFieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaDynamicFieldResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaDynamicFieldResource.java
deleted file mode 100644
index 6572709..0000000
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaDynamicFieldResource.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.commons.io.FileUtils;
-import org.apache.solr.util.RestTestBase;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.restlet.ext.servlet.ServerServlet;
-
-import java.io.File;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-
-public class TestManagedSchemaDynamicFieldResource extends RestTestBase {
-
- private static File tmpSolrHome;
- private static File tmpConfDir;
-
- private static final String collection = "collection1";
- private static final String confDir = collection + "/conf";
-
-
- @Before
- public void before() throws Exception {
- tmpSolrHome = createTempDir().toFile();
- tmpConfDir = new File(tmpSolrHome, confDir);
- FileUtils.copyDirectory(new File(TEST_HOME()), tmpSolrHome.getAbsoluteFile());
-
- final SortedMap<ServletHolder,String> extraServlets = new TreeMap<>();
- final ServletHolder solrRestApi = new ServletHolder("SolrSchemaRestApi", ServerServlet.class);
- solrRestApi.setInitParameter("org.restlet.application", "org.apache.solr.rest.SolrSchemaRestApi");
- extraServlets.put(solrRestApi, "/schema/*"); // '/schema/*' matches '/schema', '/schema/', and '/schema/whatever...'
-
- System.setProperty("managed.schema.mutable", "true");
- System.setProperty("enable.update.log", "false");
-
- createJettyAndHarness(tmpSolrHome.getAbsolutePath(), "solrconfig-managed-schema.xml", "schema-rest.xml",
- "/solr", true, extraServlets);
- }
-
- @After
- public void after() throws Exception {
- if (jetty != null) {
- jetty.stop();
- jetty = null;
- }
- client = null;
- if (restTestHarness != null) {
- restTestHarness.close();
- }
- restTestHarness = null;
- }
-
- @Test
- public void testAddDynamicFieldBadFieldType() throws Exception {
- assertJPut("/schema/dynamicfields/*_newdynamicfield",
- json( "{'type':'not_in_there_at_all','stored':false}" ),
- "/error/msg==\"Dynamic field \\'*_newdynamicfield\\': Field type \\'not_in_there_at_all\\' not found.\"");
- }
-
- @Test
- public void testAddDynamicFieldMismatchedName() throws Exception {
- assertJPut("/schema/dynamicfields/*_newdynamicfield",
- json( "{'name':'*_something_else','type':'text','stored':false}" ),
- "/error/msg=='///regex:\\\\*_newdynamicfield///'");
- }
-
- @Test
- public void testAddDynamicFieldBadProperty() throws Exception {
- assertJPut("/schema/dynamicfields/*_newdynamicfield",
- json( "{'type':'text','no_property_with_this_name':false}" ),
- "/error/msg==\"java.lang.IllegalArgumentException: Invalid field property: no_property_with_this_name\"");
- }
-
- @Test
- public void testAddDynamicField() throws Exception {
- assertQ("/schema/dynamicfields/newdynamicfield_*?indent=on&wt=xml",
- "count(/response/lst[@name='newdynamicfield_*']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/dynamicfields/newdynamicfield_*",
- json("{'type':'text','stored':false}"),
- "/responseHeader/status==0");
-
- assertQ("/schema/dynamicfields/newdynamicfield_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- assertU(adoc("newdynamicfield_A", "value1 value2", "id", "123"));
- assertU(commit());
-
- assertQ("/select?q=newdynamicfield_A:value1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc/*) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='123']");
- }
-
- @Test
- public void testAddDynamicFieldWithMulipleOptions() throws Exception {
- assertQ("/schema/dynamicfields/newdynamicfield_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/dynamicfields/newdynamicfield_*",
- json("{'type':'text_en','stored':true,'indexed':false}"),
- "/responseHeader/status==0");
-
- File managedSchemaFile = new File(tmpConfDir, "managed-schema");
- assertTrue(managedSchemaFile.exists());
- String managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newdynamicfieldStoredTrueIndexedFalsePattern
- = Pattern.compile( "<dynamicField name=\"newdynamicfield_\\*\" type=\"text_en\""
- + "(?=.*stored=\"true\")(?=.*indexed=\"false\").*/>");
- assertTrue(newdynamicfieldStoredTrueIndexedFalsePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/dynamicfields/newdynamicfield_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/lst[@name='dynamicField']/str[@name='name'] = 'newdynamicfield_*'",
- "/response/lst[@name='dynamicField']/str[@name='type'] = 'text_en'",
- "/response/lst[@name='dynamicField']/bool[@name='indexed'] = 'false'",
- "/response/lst[@name='dynamicField']/bool[@name='stored'] = 'true'");
-
- assertU(adoc("newdynamicfield_A", "value1 value2", "id", "1234"));
- assertU(commit());
-
- assertQ("/schema/dynamicfields/newdynamicfield2_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/dynamicfields/newdynamicfield2_*",
- json("{'type':'text_en','stored':true,'indexed':true,'multiValued':true}"),
- "/responseHeader/status==0");
-
- managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newdynamicfield2StoredTrueIndexedTrueMultiValuedTruePattern
- = Pattern.compile( "<dynamicField name=\"newdynamicfield2_\\*\" type=\"text_en\" "
- + "(?=.*stored=\"true\")(?=.*indexed=\"true\")(?=.*multiValued=\"true\").*/>");
- assertTrue(newdynamicfield2StoredTrueIndexedTrueMultiValuedTruePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/dynamicfields/newdynamicfield2_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/lst[@name='dynamicField']/str[@name='name'] = 'newdynamicfield2_*'",
- "/response/lst[@name='dynamicField']/str[@name='type'] = 'text_en'",
- "/response/lst[@name='dynamicField']/bool[@name='indexed'] = 'true'",
- "/response/lst[@name='dynamicField']/bool[@name='stored'] = 'true'",
- "/response/lst[@name='dynamicField']/bool[@name='multiValued'] = 'true'");
-
- assertU(adoc("newdynamicfield2_A", "value1 value2", "newdynamicfield2_A", "value3 value4", "id", "5678"));
- assertU(commit());
-
- assertQ("/select?q=newdynamicfield2_A:value3",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='5678']");
- }
-
- @Test
- public void testAddDynamicFieldCollectionWithMultipleOptions() throws Exception {
- assertQ("/schema/dynamicfields?indent=on&wt=xml",
- "count(/response/arr[@name='dynamicFields']/lst/str[@name]) > 0", // there are fields
- "count(/response/arr[@name='dynamicFields']/lst/str[starts-with(@name,'newfield')]) = 0"); // but none named newfield*
-
- assertJPost("/schema/dynamicfields",
- json("[{'name':'newdynamicfield_*','type':'text_en','stored':true,'indexed':false}]"),
- "/responseHeader/status==0");
-
- File managedSchemaFile = new File(tmpConfDir, "managed-schema");
- assertTrue(managedSchemaFile.exists());
- String managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newfieldStoredTrueIndexedFalsePattern
- = Pattern.compile( "<dynamicField name=\"newdynamicfield_\\*\" type=\"text_en\""
- + "(?=.*stored=\"true\")(?=.*indexed=\"false\").*/>");
- assertTrue(newfieldStoredTrueIndexedFalsePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/dynamicfields?indent=on&wt=xml",
- "/response/arr[@name='dynamicFields']/lst"
- + "[str[@name='name']='newdynamicfield_*' and str[@name='type']='text_en'"
- + " and bool[@name='stored']='true' and bool[@name='indexed']='false']");
-
- assertU(adoc("newdynamicfield_A", "value1 value2", "id", "789"));
- assertU(commit());
-
- assertJPost("/schema/dynamicfields",
- json("[{'name':'newdynamicfield2_*','type':'text_en','stored':true,'indexed':true,'multiValued':true}]"),
- "/responseHeader/status==0");
-
- managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newdynamicfield2StoredTrueIndexedTrueMultiValuedTruePattern
- = Pattern.compile( "<dynamicField name=\"newdynamicfield2_\\*\" type=\"text_en\" "
- + "(?=.*stored=\"true\")(?=.*indexed=\"true\")(?=.*multiValued=\"true\").*/>");
- assertTrue(newdynamicfield2StoredTrueIndexedTrueMultiValuedTruePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/dynamicfields?indent=on&wt=xml",
- "/response/arr[@name='dynamicFields']/lst"
- + "[str[@name='name']='newdynamicfield2_*' and str[@name='type']='text_en'"
- + " and bool[@name='stored']='true' and bool[@name='indexed']='true' and bool[@name='multiValued']='true']");
-
- assertU(adoc("newdynamicfield2_A", "value1 value2", "newdynamicfield2_A", "value3 value4", "id", "790"));
- assertU(commit());
-
- assertQ("/select?q=newdynamicfield2_A:value3",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='790']");
- }
-
-
- @Test
- public void testAddCopyField() throws Exception {
- assertQ("/schema/dynamicfields/newdynamicfield2_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/dynamicfields/dynamicfieldA_*",
- json("{'type':'text','stored':false}"),
- "/responseHeader/status==0");
- assertJPut("/schema/dynamicfields/dynamicfieldB_*",
- json("{'type':'text','stored':false, 'copyFields':['dynamicfieldA_*']}"),
- "/responseHeader/status==0");
- assertJPut("/schema/dynamicfields/dynamicfieldC_*",
- json("{'type':'text','stored':false, 'copyFields':'dynamicfieldA_*'}"),
- "/responseHeader/status==0");
-
- assertQ("/schema/dynamicfields/dynamicfieldB_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=dynamicfieldB_*",
- "count(/response/arr[@name='copyFields']/lst) = 1");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=dynamicfieldC_*",
- "count(/response/arr[@name='copyFields']/lst) = 1");
- //fine to pass in empty list, just won't do anything
- assertJPut("/schema/dynamicfields/dynamicfieldD_*",
- json("{'type':'text','stored':false, 'copyFields':[]}"),
- "/responseHeader/status==0");
- //some bad usages
- assertJPut("/schema/dynamicfields/dynamicfieldF_*",
- json("{'type':'text','stored':false, 'copyFields':['some_nonexistent_dynamicfield_ignore_exception_*']}"),
- "/error/msg==\"copyField dest :\\'some_nonexistent_dynamicfield_ignore_exception_*\\' is not an explicit field and doesn\\'t match a dynamicField.\"");
- }
-
- @Test
- public void testPostMultipleDynamicFields() throws Exception {
- assertQ("/schema/dynamicfields/newdynamicfield1_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertQ("/schema/dynamicfields/newdynamicfield2_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPost("/schema/dynamicfields",
- json( "[{'name':'newdynamicfield1_*','type':'text','stored':false},"
- + " {'name':'newdynamicfield2_*','type':'text','stored':false}]"),
- "/responseHeader/status==0");
-
- assertQ("/schema/dynamicfields/newdynamicfield1_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- assertQ("/schema/dynamicfields/newdynamicfield2_*?indent=on&wt=xml",
- "count(/response/lst[@name='dynamicField']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- assertU(adoc("newdynamicfield1_A", "value1 value2", "id", "123"));
- assertU(adoc("newdynamicfield2_A", "value3 value4", "id", "456"));
- assertU(commit());
-
- assertQ("/select?q=newdynamicfield1_A:value1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc/*) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='123']");
- assertQ("/select?q=newdynamicfield2_A:value3",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc/*) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='456']");
- }
-
- @Test
- public void testPostCopy() throws Exception {
- assertJPost("/schema/dynamicfields",
- json( "[{'name':'dynamicfieldA_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldB_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldC_*','type':'text','stored':false, 'copyFields':['dynamicfieldB_*']}]"),
- "/responseHeader/status==0");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=dynamicfieldC_*",
- "count(/response/arr[@name='copyFields']/lst) = 1");
- assertJPost("/schema/dynamicfields",
- json( "[{'name':'dynamicfieldD_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldE_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldF_*','type':'text','stored':false, 'copyFields':['dynamicfieldD_*','dynamicfieldE_*']},"
- + " {'name':'dynamicfieldG_*','type':'text','stored':false, 'copyFields':'dynamicfieldD_*'}]"),//single
- "/responseHeader/status==0");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=dynamicfieldF_*",
- "count(/response/arr[@name='copyFields']/lst) = 2");
- //passing in an empty list is perfectly acceptable, it just won't do anything
- assertJPost("/schema/dynamicfields",
- json( "[{'name':'dynamicfieldX_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldY_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldZ_*','type':'text','stored':false, 'copyFields':[]}]"),
- "/responseHeader/status==0");
- //some bad usages
-
- assertJPost("/schema/dynamicfields",
- json( "[{'name':'dynamicfieldH_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldI_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldJ_*','type':'text','stored':false, 'copyFields':['some_nonexistent_dynamicfield_ignore_exception_*']}]"),
- "/error/msg=='copyField dest :\\'some_nonexistent_dynamicfield_ignore_exception_*\\' is not an explicit field and doesn\\'t match a dynamicField.'");
- }
-
- @Test
- public void testPostCopyFields() throws Exception {
- assertJPost("/schema/dynamicfields",
- json( "[{'name':'dynamicfieldA_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldB_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldC_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldD_*','type':'text','stored':false},"
- + " {'name':'dynamicfieldE_*','type':'text','stored':false}]"),
- "/responseHeader/status==0");
- assertJPost("/schema/copyfields",
- json( "[{'source':'dynamicfieldA_*', 'dest':'dynamicfieldB_*'},"
- + " {'source':'dynamicfieldD_*', 'dest':['dynamicfieldC_*', 'dynamicfieldE_*']}]"),
- "/responseHeader/status==0");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=dynamicfieldA_*",
- "count(/response/arr[@name='copyFields']/lst) = 1");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=dynamicfieldD_*",
- "count(/response/arr[@name='copyFields']/lst) = 2");
- assertJPost("/schema/copyfields", // copyField glob sources are not required to match a dynamic field
- json("[{'source':'some_glob_not_necessarily_matching_any_dynamicfield_*', 'dest':['dynamicfieldA_*']},"
- +" {'source':'*', 'dest':['dynamicfieldD_*']}]"),
- "/responseHeader/status==0");
- assertJPost("/schema/copyfields",
- json("[{'source':'dynamicfieldD_*', 'dest':['some_nonexistent_dynamicfield_ignore_exception_*']}]"),
- "/error/msg=='copyField dest :\\'some_nonexistent_dynamicfield_ignore_exception_*\\' is not an explicit field and doesn\\'t match a dynamicField.'");
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java
deleted file mode 100644
index b39d266..0000000
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldResource.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import org.apache.commons.io.FileUtils;
-import org.apache.solr.util.RestTestBase;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.restlet.ext.servlet.ServerServlet;
-
-import java.io.File;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.regex.Pattern;
-
-public class TestManagedSchemaFieldResource extends RestTestBase {
-
- private static File tmpSolrHome;
- private static File tmpConfDir;
-
- private static final String collection = "collection1";
- private static final String confDir = collection + "/conf";
-
-
- @Before
- public void before() throws Exception {
- tmpSolrHome = createTempDir().toFile();
- tmpConfDir = new File(tmpSolrHome, confDir);
- FileUtils.copyDirectory(new File(TEST_HOME()), tmpSolrHome.getAbsoluteFile());
-
- final SortedMap<ServletHolder,String> extraServlets = new TreeMap<>();
- final ServletHolder solrRestApi = new ServletHolder("SolrSchemaRestApi", ServerServlet.class);
- solrRestApi.setInitParameter("org.restlet.application", "org.apache.solr.rest.SolrSchemaRestApi");
- extraServlets.put(solrRestApi, "/schema/*"); // '/schema/*' matches '/schema', '/schema/', and '/schema/whatever...'
-
- System.setProperty("managed.schema.mutable", "true");
- System.setProperty("enable.update.log", "false");
-
- createJettyAndHarness(tmpSolrHome.getAbsolutePath(), "solrconfig-managed-schema.xml", "schema-rest.xml",
- "/solr", true, extraServlets);
- }
-
- @After
- public void after() throws Exception {
- if (jetty != null) {
- jetty.stop();
- jetty = null;
- }
- client = null;
- if (restTestHarness != null) {
- restTestHarness.close();
- }
- restTestHarness = null;
- }
-
- @Test
- public void testAddFieldBadFieldType() throws Exception {
- assertJPut("/schema/fields/newfield",
- json( "{'type':'not_in_there_at_all','stored':false}" ),
- "/error/msg==\"Field \\'newfield\\': Field type \\'not_in_there_at_all\\' not found.\"");
- }
-
- @Test
- public void testAddFieldMismatchedName() throws Exception {
- assertJPut("/schema/fields/newfield",
- json( "{'name':'something_else','type':'text','stored':false}" ),
- "/error/msg=='///regex:newfield///'");
- }
-
- @Test
- public void testAddFieldBadProperty() throws Exception {
- assertJPut("/schema/fields/newfield",
- json( "{'type':'text','no_property_with_this_name':false}" ),
- "/error/msg==\"java.lang.IllegalArgumentException: Invalid field property: no_property_with_this_name\"");
- }
-
- @Test
- public void testAddField() throws Exception {
- assertQ("/schema/fields/newfield?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/fields/newfield",
- json("{'type':'text','stored':false}"),
- "/responseHeader/status==0");
-
- assertQ("/schema/fields/newfield?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- assertU(adoc("newfield", "value1 value2", "id", "123"));
- assertU(commit());
-
- assertQ("/select?q=newfield:value1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc/*) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='123']");
- }
-
- @Test
- public void testAddFieldWithMulipleOptions() throws Exception {
- assertQ("/schema/fields/newfield?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/fields/newfield",
- json("{'type':'text_en','stored':true,'indexed':false}"),
- "/responseHeader/status==0");
-
- File managedSchemaFile = new File(tmpConfDir, "managed-schema");
- assertTrue(managedSchemaFile.exists());
- String managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newfieldStoredTrueIndexedFalsePattern
- = Pattern.compile( "<field name=\"newfield\" type=\"text_en\" "
- + "(?=.*stored=\"true\")(?=.*indexed=\"false\").*/>");
- assertTrue(newfieldStoredTrueIndexedFalsePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/fields/newfield?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/lst[@name='field']/str[@name='name'] = 'newfield'",
- "/response/lst[@name='field']/str[@name='type'] = 'text_en'",
- "/response/lst[@name='field']/bool[@name='indexed'] = 'false'",
- "/response/lst[@name='field']/bool[@name='stored'] = 'true'");
-
- assertU(adoc("newfield", "value1 value2", "id", "1234"));
- assertU(commit());
-
- assertQ("/schema/fields/newfield2?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/fields/newfield2",
- json("{'type':'text_en','stored':true,'indexed':true,'multiValued':true}"),
- "/responseHeader/status==0");
-
- managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newfield2StoredTrueIndexedTrueMultiValuedTruePattern
- = Pattern.compile( "<field name=\"newfield2\" type=\"text_en\" "
- + "(?=.*stored=\"true\")(?=.*indexed=\"true\")(?=.*multiValued=\"true\").*/>");
- assertTrue(newfield2StoredTrueIndexedTrueMultiValuedTruePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/fields/newfield2?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/lst[@name='field']/str[@name='name'] = 'newfield2'",
- "/response/lst[@name='field']/str[@name='type'] = 'text_en'",
- "/response/lst[@name='field']/bool[@name='indexed'] = 'true'",
- "/response/lst[@name='field']/bool[@name='stored'] = 'true'",
- "/response/lst[@name='field']/bool[@name='multiValued'] = 'true'");
-
- assertU(adoc("newfield2", "value1 value2", "newfield2", "value3 value4", "id", "5678"));
- assertU(commit());
-
- assertQ("/select?q=newfield2:value3",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='5678']");
- }
-
- @Test
- public void testAddFieldCollectionWithMultipleOptions() throws Exception {
- assertQ("/schema/fields?indent=on&wt=xml",
- "count(/response/arr[@name='fields']/lst/str[@name]) > 0", // there are fields
- "count(/response/arr[@name='fields']/lst/str[starts-with(@name,'newfield')]) = 0"); // but none named newfield*
-
- assertJPost("/schema/fields",
- json("[{'name':'newfield','type':'text_en','stored':true,'indexed':false}]"),
- "/responseHeader/status==0");
-
- File managedSchemaFile = new File(tmpConfDir, "managed-schema");
- assertTrue(managedSchemaFile.exists());
- String managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newfieldStoredTrueIndexedFalsePattern
- = Pattern.compile( "<field name=\"newfield\" type=\"text_en\" "
- + "(?=.*stored=\"true\")(?=.*indexed=\"false\").*/>");
- assertTrue(newfieldStoredTrueIndexedFalsePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/fields?indent=on&wt=xml",
- "/response/arr[@name='fields']/lst"
- + "[str[@name='name']='newfield' and str[@name='type']='text_en'"
- + " and bool[@name='stored']='true' and bool[@name='indexed']='false']");
-
- assertU(adoc("newfield", "value1 value2", "id", "789"));
- assertU(commit());
-
- assertJPost("/schema/fields",
- json("[{'name':'newfield2','type':'text_en','stored':true,'indexed':true,'multiValued':true}]"),
- "/responseHeader/status==0");
-
- managedSchemaContents = FileUtils.readFileToString(managedSchemaFile, "UTF-8");
- Pattern newfield2StoredTrueIndexedTrueMultiValuedTruePattern
- = Pattern.compile( "<field name=\"newfield2\" type=\"text_en\" "
- + "(?=.*stored=\"true\")(?=.*indexed=\"true\")(?=.*multiValued=\"true\").*/>");
- assertTrue(newfield2StoredTrueIndexedTrueMultiValuedTruePattern.matcher(managedSchemaContents).find());
-
- assertQ("/schema/fields?indent=on&wt=xml",
- "/response/arr[@name='fields']/lst"
- + "[str[@name='name']='newfield2' and str[@name='type']='text_en'"
- + " and bool[@name='stored']='true' and bool[@name='indexed']='true' and bool[@name='multiValued']='true']");
-
- assertU(adoc("newfield2", "value1 value2", "newfield2", "value3 value4", "id", "790"));
- assertU(commit());
-
- assertQ("/select?q=newfield2:value3",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='790']");
- }
-
-
- @Test
- public void testAddCopyField() throws Exception {
- assertQ("/schema/fields/newfield2?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPut("/schema/fields/fieldA",
- json("{'type':'text','stored':false}"),
- "/responseHeader/status==0");
- assertJPut("/schema/fields/fieldB",
- json("{'type':'text','stored':false, 'copyFields':['fieldA']}"),
- "/responseHeader/status==0");
- assertJPut("/schema/fields/fieldC",
- json("{'type':'text','stored':false, 'copyFields':'fieldA'}"),
- "/responseHeader/status==0");
-
- assertQ("/schema/fields/fieldB?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldB",
- "count(/response/arr[@name='copyFields']/lst) = 1"
- );
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldC",
- "count(/response/arr[@name='copyFields']/lst) = 1"
- );
- //fine to pass in empty list, just won't do anything
- assertJPut("/schema/fields/fieldD",
- json("{'type':'text','stored':false, 'copyFields':[]}"),
- "/responseHeader/status==0");
- //some bad usages
- assertJPut("/schema/fields/fieldF",
- json("{'type':'text','stored':false, 'copyFields':['some_nonexistent_field_ignore_exception']}"),
- "/error/msg==\"copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.\"");
- }
-
- @Test
- public void testPostMultipleFields() throws Exception {
- assertQ("/schema/fields/newfield1?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertQ("/schema/fields/newfield2?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 0",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '404'",
- "/response/lst[@name='error']/int[@name='code'] = '404'");
-
- assertJPost("/schema/fields",
- json( "[{'name':'newfield1','type':'text','stored':false},"
- + " {'name':'newfield2','type':'text','stored':false}]"),
- "/responseHeader/status==0");
-
- assertQ("/schema/fields/newfield1?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- assertQ("/schema/fields/newfield2?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- assertU(adoc("newfield1", "value1 value2", "id", "123"));
- assertU(adoc("newfield2", "value3 value4", "id", "456"));
- assertU(commit());
-
- assertQ("/select?q=newfield1:value1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc/*) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='123']");
- assertQ("/select?q=newfield2:value3",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'",
- "/response/result[@name='response'][@numFound='1']",
- "count(/response/result[@name='response']/doc/*) = 1",
- "/response/result[@name='response']/doc/str[@name='id'][.='456']");
- }
-
- @Test
- public void testPostCopy() throws Exception {
- assertJPost("/schema/fields",
- json( "[{'name':'fieldA','type':'text','stored':false},"
- + " {'name':'fieldB','type':'text','stored':false},"
- + " {'name':'fieldC','type':'text','stored':false, 'copyFields':['fieldB']}]"),
- "/responseHeader/status==0");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldC",
- "count(/response/arr[@name='copyFields']/lst) = 1"
- );
- assertJPost("/schema/fields",
- json( "[{'name':'fieldD','type':'text','stored':false},"
- + " {'name':'fieldE','type':'text','stored':false},"
- + " {'name':'fieldF','type':'text','stored':false, 'copyFields':['fieldD','fieldE']},"
- + " {'name':'fieldG','type':'text','stored':false, 'copyFields':'fieldD'}]"),//single
- "/responseHeader/status==0");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldF",
- "count(/response/arr[@name='copyFields']/lst) = 2"
- );
- //passing in an empty list is perfectly acceptable, it just won't do anything
- assertJPost("/schema/fields",
- json( "[{'name':'fieldX','type':'text','stored':false},"
- + " {'name':'fieldY','type':'text','stored':false},"
- + " {'name':'fieldZ','type':'text','stored':false, 'copyFields':[]}]"),
- "/responseHeader/status==0");
- //some bad usages
-
- assertJPost("/schema/fields",
- json( "[{'name':'fieldH','type':'text','stored':false},"
- + " {'name':'fieldI','type':'text','stored':false},"
- + " {'name':'fieldJ','type':'text','stored':false, 'copyFields':['some_nonexistent_field_ignore_exception']}]"),
- "/error/msg=='copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.'");
- }
-
- @Test
- public void testPostCopyFields() throws Exception {
- assertJPost("/schema/fields",
- json( "[{'name':'fieldA','type':'text','stored':false},"
- + " {'name':'fieldB','type':'text','stored':false},"
- + " {'name':'fieldC','type':'text','stored':false},"
- + " {'name':'fieldD','type':'text','stored':false},"
- + " {'name':'fieldE','type':'text','stored':false}]"),
- "/responseHeader/status==0");
- assertJPost("/schema/copyfields",
- json( "[{'source':'fieldA', 'dest':'fieldB'},"
- + " {'source':'fieldD', 'dest':['fieldC', 'fieldE']}]"),
- "/responseHeader/status==0");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldA",
- "count(/response/arr[@name='copyFields']/lst) = 1");
- assertQ("/schema/copyfields/?indent=on&wt=xml&source.fl=fieldD",
- "count(/response/arr[@name='copyFields']/lst) = 2");
- assertJPost("/schema/copyfields",
- json("[{'source':'some_nonexistent_field_ignore_exception', 'dest':['fieldA']}]"),
- "/error/msg=='copyField source :\\'some_nonexistent_field_ignore_exception\\' is not a glob and doesn\\'t match any explicit field or dynamicField.'");
- assertJPost("/schema/copyfields",
- json("[{'source':'fieldD', 'dest':['some_nonexistent_field_ignore_exception']}]"),
- "/error/msg=='copyField dest :\\'some_nonexistent_field_ignore_exception\\' is not an explicit field and doesn\\'t match a dynamicField.'");
- }
-}
-
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f2c281ab/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldTypeResource.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldTypeResource.java b/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldTypeResource.java
deleted file mode 100644
index a0f4e25..0000000
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestManagedSchemaFieldTypeResource.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.rest.schema;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.solr.util.RestTestBase;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.noggit.JSONUtil;
-import org.restlet.ext.servlet.ServerServlet;
-
-public class TestManagedSchemaFieldTypeResource extends RestTestBase {
-
- private static File tmpSolrHome;
- private static File tmpConfDir;
-
- private static final String collection = "collection1";
- private static final String confDir = collection + "/conf";
-
- @Before
- public void before() throws Exception {
- tmpSolrHome = createTempDir().toFile();
- tmpConfDir = new File(tmpSolrHome, confDir);
- FileUtils.copyDirectory(new File(TEST_HOME()), tmpSolrHome.getAbsoluteFile());
-
- final SortedMap<ServletHolder,String> extraServlets = new TreeMap<>();
- final ServletHolder solrRestApi = new ServletHolder("SolrSchemaRestApi", ServerServlet.class);
- solrRestApi.setInitParameter("org.restlet.application", "org.apache.solr.rest.SolrSchemaRestApi");
- extraServlets.put(solrRestApi, "/schema/*"); // '/schema/*' matches '/schema', '/schema/', and '/schema/whatever...'
-
- System.setProperty("managed.schema.mutable", "true");
- System.setProperty("enable.update.log", "false");
-
- createJettyAndHarness(tmpSolrHome.getAbsolutePath(), "solrconfig-managed-schema.xml", "schema-rest.xml",
- "/solr", true, extraServlets);
- }
-
- @After
- private void after() throws Exception {
- jetty.stop();
- jetty = null;
- System.clearProperty("managed.schema.mutable");
- System.clearProperty("enable.update.log");
-
- if (restTestHarness != null) {
- restTestHarness.close();
- }
- restTestHarness = null;
- }
-
- @Test
- public void testAddFieldTypes() throws Exception {
-
- // name mismatch
- assertJPut("/schema/fieldtypes/myIntFieldType",
- json("{'name':'badNameEh','class':'solr.TrieIntField','stored':false}"),
- "/responseHeader/status==400");
-
- // no class
- assertJPut("/schema/fieldtypes/myIntFieldType",
- json("{'stored':false}"),
- "/responseHeader/status==400");
-
- // invalid attribute
- assertJPut("/schema/fieldtypes/myIntFieldType",
- json("{'foo':'bar'}"),
- "/responseHeader/status==400");
-
- // empty analyzer
- String ftdef = "";
- ftdef += "{";
- ftdef += " 'class':'solr.TextField','positionIncrementGap':'100',";
- ftdef += " 'analyzer':''";
- ftdef += "}";
- assertJPut("/schema/fieldtypes/emptyAnalyzerFieldType",
- json(ftdef),
- "/responseHeader/status==400");
-
- // basic field types
- assertJPut("/schema/fieldtypes/myIntFieldType",
- json("{'name':'myIntFieldType','class':'solr.TrieIntField','stored':false}"),
- "/responseHeader/status==0");
- checkFieldTypeProps(getExpectedProps("myIntFieldType", "solr.TrieIntField", true, false), 16);
-
- assertJPut("/schema/fieldtypes/myDoubleFieldType",
- json("{'class':'solr.TrieDoubleField','precisionStep':'0','positionIncrementGap':'0'}"),
- "/responseHeader/status==0");
- Map<String,Object> expProps =
- getExpectedProps("myDoubleFieldType", "solr.TrieDoubleField", true, true);
- // add some additional expected props for this type
- expProps.put("precisionStep", "0");
- expProps.put("positionIncrementGap", "0");
- checkFieldTypeProps(expProps, 18);
-
- assertJPut("/schema/fieldtypes/myBoolFieldType",
- json("{'class':'solr.BoolField','sortMissingLast':true}"),
- "/responseHeader/status==0");
- expProps = getExpectedProps("myBoolFieldType", "solr.BoolField", true, true);
- expProps.put("sortMissingLast", true);
- checkFieldTypeProps(expProps, 17);
-
- // a text analyzing field type
- ftdef = "{";
- ftdef += " 'class':'solr.TextField','positionIncrementGap':'100',";
- ftdef += " 'analyzer':{";
- ftdef += " 'charFilters':[";
- ftdef += " {'class':'solr.PatternReplaceCharFilterFactory','replacement':'$1$1','pattern':'([a-zA-Z])\\\\1+'}";
- ftdef += " ],";
- ftdef += " 'tokenizer':{'class':'solr.WhitespaceTokenizerFactory'},";
- ftdef += " 'filters':[";
- ftdef += " {'class':'solr.WordDelimiterFilterFactory','preserveOriginal':'0'},";
- ftdef += " {'class':'solr.StopFilterFactory','words':'stopwords.txt','ignoreCase':'true'},";
- ftdef += " {'class':'solr.LowerCaseFilterFactory'},";
- ftdef += " {'class':'solr.ASCIIFoldingFilterFactory'},";
- ftdef += " {'class':'solr.KStemFilterFactory'}";
- ftdef += " ]";
- ftdef += " }";
- ftdef += "}";
-
- assertJPut("/schema/fieldtypes/myTextFieldType", json(ftdef), "/responseHeader/status==0");
-
- expProps = getExpectedProps("myTextFieldType", "solr.TextField", true, true);
- expProps.put("autoGeneratePhraseQueries", false);
- expProps.put("omitNorms", false);
- expProps.put("omitTermFreqAndPositions", false);
- expProps.put("omitPositions", false);
- expProps.put("storeOffsetsWithPositions", false);
- expProps.put("tokenized", true);
-
- List<String> analyzerTests = new ArrayList<>();
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='charFilters']/lst[1]/str[@name='class'] = 'solr.PatternReplaceCharFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/lst[@name='tokenizer']/str[@name='class'] = 'solr.WhitespaceTokenizerFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[1]/str[@name='class'] = 'solr.WordDelimiterFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[2]/str[@name='class'] = 'solr.StopFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[3]/str[@name='class'] = 'solr.LowerCaseFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[4]/str[@name='class'] = 'solr.ASCIIFoldingFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[5]/str[@name='class'] = 'solr.KStemFilterFactory'");
- checkFieldTypeProps(expProps, 19, analyzerTests);
-
- // now add a field type that uses managed resources and a field that uses that type
-
- String piglatinStopWordEndpoint = "/schema/analysis/stopwords/piglatin";
- String piglatinSynonymEndpoint = "/schema/analysis/synonyms/piglatin";
-
- // now define a new FieldType that uses the managed piglatin endpoints
- // the managed endpoints will be autovivified as needed
- ftdef = "{";
- ftdef += " 'class':'solr.TextField',";
- ftdef += " 'analyzer':{";
- ftdef += " 'tokenizer':{'class':'solr.StandardTokenizerFactory'},";
- ftdef += " 'filters':[";
- ftdef += " {'class':'solr.ManagedStopFilterFactory','managed':'piglatin'},";
- ftdef += " {'class':'solr.ManagedSynonymFilterFactory','managed':'piglatin'}";
- ftdef += " ]";
- ftdef += " }";
- ftdef += "}";
- assertJPut("/schema/fieldtypes/piglatinFieldType", json(ftdef), "/responseHeader/status==0");
-
- expProps = getExpectedProps("piglatinFieldType", "solr.TextField", true, true);
- expProps.put("autoGeneratePhraseQueries", false);
- expProps.put("omitNorms", false);
- expProps.put("omitTermFreqAndPositions", false);
- expProps.put("omitPositions", false);
- expProps.put("storeOffsetsWithPositions", false);
- expProps.put("tokenized", true);
-
- analyzerTests = new ArrayList<>();
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/lst[@name='tokenizer']/str[@name='class'] = 'solr.StandardTokenizerFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[1]/str[@name='class'] = 'solr.ManagedStopFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[2]/str[@name='class'] = 'solr.ManagedSynonymFilterFactory'");
- checkFieldTypeProps(expProps, 18, analyzerTests);
-
- assertJQ(piglatinSynonymEndpoint,
- "/synonymMappings/initArgs/ignoreCase==false",
- "/synonymMappings/managedMap=={}");
-
- // add some piglatin synonyms
- Map<String,List<String>> syns = new HashMap<>();
- syns.put("appyhay", Arrays.asList("ladgay","oyfuljay"));
- assertJPut(piglatinSynonymEndpoint,
- JSONUtil.toJSON(syns),
- "/responseHeader/status==0");
- assertJQ(piglatinSynonymEndpoint,
- "/synonymMappings/managedMap/appyhay==['ladgay','oyfuljay']");
-
- // add some piglatin stopwords
- assertJPut(piglatinStopWordEndpoint,
- JSONUtil.toJSON(Arrays.asList("hetay")),
- "/responseHeader/status==0");
-
- assertJQ(piglatinStopWordEndpoint + "/hetay", "/hetay=='hetay'");
-
- // add a field that uses our new type
- assertJPut("/schema/fields/newManagedField",
- json("{'type':'piglatinFieldType','stored':false}"),
- "/responseHeader/status==0");
-
- assertQ("/schema/fields/newManagedField?indent=on&wt=xml",
- "count(/response/lst[@name='field']) = 1",
- "/response/lst[@name='responseHeader']/int[@name='status'] = '0'");
-
- // try to delete the managed synonyms endpoint, which should fail because it is being used
- assertJDelete(piglatinSynonymEndpoint, "/responseHeader/status==403");
-
- // test adding multiple field types at once
- ftdef = "[";
- ftdef += "{";
- ftdef += " 'name':'textFieldType1',";
- ftdef += " 'class':'solr.TextField','positionIncrementGap':'100',";
- ftdef += " 'analyzer':{";
- ftdef += " 'tokenizer':{'class':'solr.WhitespaceTokenizerFactory'},";
- ftdef += " 'filters':[";
- ftdef += " {'class':'solr.WordDelimiterFilterFactory','preserveOriginal':'0'},";
- ftdef += " {'class':'solr.StopFilterFactory','words':'stopwords.txt','ignoreCase':'true'},";
- ftdef += " {'class':'solr.LowerCaseFilterFactory'}";
- ftdef += " ]";
- ftdef += " }";
- ftdef += "},{";
- ftdef += " 'name':'textFieldType2',";
- ftdef += " 'class':'solr.TextField','positionIncrementGap':'100',";
- ftdef += " 'analyzer':{";
- ftdef += " 'tokenizer':{'class':'solr.WhitespaceTokenizerFactory'},";
- ftdef += " 'filters':[";
- ftdef += " {'class':'solr.WordDelimiterFilterFactory','preserveOriginal':'0'},";
- ftdef += " {'class':'solr.StopFilterFactory','words':'stopwords.txt','ignoreCase':'true'},";
- ftdef += " {'class':'solr.LowerCaseFilterFactory'},";
- ftdef += " {'class':'solr.ASCIIFoldingFilterFactory'}";
- ftdef += " ]";
- ftdef += " }";
- ftdef += "}";
- ftdef += "]";
-
- assertJPost("/schema/fieldtypes", json(ftdef), "/responseHeader/status==0");
-
- expProps = getExpectedProps("textFieldType1", "solr.TextField", true, true);
- expProps.put("autoGeneratePhraseQueries", false);
- expProps.put("omitNorms", false);
- expProps.put("omitTermFreqAndPositions", false);
- expProps.put("omitPositions", false);
- expProps.put("storeOffsetsWithPositions", false);
- expProps.put("tokenized", true);
-
- analyzerTests = new ArrayList<>();
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/lst[@name='tokenizer']/str[@name='class'] = 'solr.WhitespaceTokenizerFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[1]/str[@name='class'] = 'solr.WordDelimiterFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[2]/str[@name='class'] = 'solr.StopFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[3]/str[@name='class'] = 'solr.LowerCaseFilterFactory'");
- checkFieldTypeProps(expProps, 19, analyzerTests);
-
- expProps = getExpectedProps("textFieldType2", "solr.TextField", true, true);
- expProps.put("autoGeneratePhraseQueries", false);
- expProps.put("omitNorms", false);
- expProps.put("omitTermFreqAndPositions", false);
- expProps.put("omitPositions", false);
- expProps.put("storeOffsetsWithPositions", false);
- expProps.put("tokenized", true);
-
- analyzerTests = new ArrayList<>();
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/lst[@name='tokenizer']/str[@name='class'] = 'solr.WhitespaceTokenizerFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[1]/str[@name='class'] = 'solr.WordDelimiterFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[2]/str[@name='class'] = 'solr.StopFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[3]/str[@name='class'] = 'solr.LowerCaseFilterFactory'");
- analyzerTests.add("/response/lst[@name='fieldType']/lst[@name='analyzer']/arr[@name='filters']/lst[4]/str[@name='class'] = 'solr.ASCIIFoldingFilterFactory'");
- checkFieldTypeProps(expProps, 19, analyzerTests);
- }
-
- /**
- * Helper function to check fieldType settings against a set of expected values.
- */
- protected void checkFieldTypeProps(Map<String,Object> expected, int expectedChildCount) {
- checkFieldTypeProps(expected, expectedChildCount, null);
- }
-
- protected void checkFieldTypeProps(Map<String,Object> expected, int expectedChildCount, List<String> addlTests) {
- String fieldTypeName = (String)expected.get("name");
-
- List<String> tests = new ArrayList<>();
- tests.add("count(/response/lst[@name='fieldType']) = 1");
- tests.add("count(/response/lst[@name='fieldType']/*) = "+expectedChildCount);
- tests.add("count(/response/lst[@name='fieldType']/arr[@name='fields']/*) = 0");
- tests.add("count(/response/lst[@name='fieldType']/arr[@name='dynamicFields']/*) = 0");
- for (Map.Entry<String,Object> next : expected.entrySet()) {
- Object val = next.getValue();
- String pathType = null;
- if (val instanceof Boolean)
- pathType = "bool";
- else if (val instanceof String)
- pathType = "str";
- else
- fail("Unexpected value type "+val.getClass().getName());
- // NOTE: it seems like the fieldtypes endpoint only returns strings or booleans
-
- String xpath =
- "/response/lst[@name='fieldType']/"+pathType+"[@name='"+next.getKey()+"']";
- tests.add(xpath+" = '"+val+"'");
- }
-
- if (addlTests != null)
- tests.addAll(addlTests);
-
- assertQ("/schema/fieldtypes/"+fieldTypeName+"?indent=on&wt=xml&showDefaults=true",
- tests.toArray(new String[0]));
- }
-
- /**
- * Builds a map containing expected values for a field type created by this test.
- */
- protected Map<String,Object> getExpectedProps(String name, String className, boolean indexed, boolean stored) {
- Map<String,Object> map = new HashMap<>();
- map.put("name", name);
- map.put("class", className);
- map.put("indexed", indexed);
- map.put("stored", stored);
- map.put("docValues", false);
- map.put("termVectors", false);
- map.put("termPositions", false);
- map.put("termOffsets", false);
- map.put("omitNorms", true);
- map.put("omitTermFreqAndPositions", true);
- map.put("omitPositions", false);
- map.put("storeOffsetsWithPositions", false);
- map.put("multiValued", false);
- map.put("tokenized", false);
- return map;
- }
-}
[08/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java
new file mode 100755
index 0000000..f5a148f
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoBBoxTest.java
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoBBoxTest {
+
+ protected final double DEGREES_TO_RADIANS = Math.PI / 180.0;
+
+ @Test
+ public void testBBoxDegenerate() {
+ GeoBBox box;
+ GeoConvexPolygon cp;
+ int relationship;
+ List<GeoPoint> points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, 24 * DEGREES_TO_RADIANS, -30 * DEGREES_TO_RADIANS));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -11 * DEGREES_TO_RADIANS, 101 * DEGREES_TO_RADIANS));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -49 * DEGREES_TO_RADIANS, -176 * DEGREES_TO_RADIANS));
+ GeoMembershipShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -64 * DEGREES_TO_RADIANS, -64 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, 180 * DEGREES_TO_RADIANS);
+ relationship = box.getRelationship(shape);
+ assertEquals(GeoArea.CONTAINS, relationship);
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, -61.85 * DEGREES_TO_RADIANS, -67.5 * DEGREES_TO_RADIANS, -180 * DEGREES_TO_RADIANS, -168.75 * DEGREES_TO_RADIANS);
+ //System.out.println("Shape = " + shape + " Rect = " + box);
+ relationship = box.getRelationship(shape);
+ assertEquals(GeoArea.CONTAINS, relationship);
+ }
+
+ @Test
+ public void testBBoxPointWithin() {
+ GeoBBox box;
+ GeoPoint gp;
+
+ // Standard normal Rect box, not crossing dateline
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 0.0);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.1);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.1);
+ assertFalse(box.isWithin(gp));
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.ARC,gp),1e-2);
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
+ assertEquals(0.1,box.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-2);
+
+ // Standard normal Rect box, crossing dateline
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 1.0, -Math.PI + 1.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertFalse(box.isWithin(gp));
+
+ // Latitude zone rectangle
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI, Math.PI);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertTrue(box.isWithin(gp));
+
+ // World
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, Math.PI);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, -Math.PI);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -Math.PI + 1.1);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, (-Math.PI - 1.1) + Math.PI * 2.0);
+ assertTrue(box.isWithin(gp));
+
+ }
+
+ @Test
+ public void testBBoxExpand() {
+ GeoBBox box;
+ GeoPoint gp;
+ // Standard normal Rect box, not crossing dateline
+ box = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+ box = box.expand(0.1);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.0);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, 0.0);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.15, 0.0);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.05);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.15);
+ assertFalse(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.05);
+ assertTrue(box.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, 1.15);
+ assertFalse(box.isWithin(gp));
+ }
+
+ @Test
+ public void testBBoxBounds() {
+ GeoBBox c;
+ LatLonBounds b;
+ XYZBounds xyzb;
+ GeoArea solid;
+ GeoPoint point;
+ int relationship;
+
+ c= GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.7570958596622309, -0.7458670829264561, -0.9566079379002148, 1.4802570961901191);
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,0.10922258701604912,0.1248184603754517,-0.8172414690802067,0.9959041483215542,-0.6136586624726926,0.6821740363641521);
+ point = new GeoPoint(PlanetModel.SPHERE, 0.3719987557178081, 1.4529582778845198);
+ assertTrue(c.isWithin(point));
+ assertTrue(solid.isWithin(point));
+ relationship = solid.getRelationship(c);
+ assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.CONTAINS || relationship == GeoArea.WITHIN);
+
+ c= GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.006607096847842122, -0.002828135860810422, -0.0012934461873348349, 0.006727418645092394);
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,0.9999995988328008,1.0000000002328306,-0.0012934708508166816,0.006727393021214471,-0.002828157275369464,0.006607074060760007);
+ point = new GeoPoint(PlanetModel.SPHERE, -5.236470872437899E-4, 3.992578692654256E-4);
+ assertTrue(c.isWithin(point));
+ assertTrue(solid.isWithin(point));
+ relationship = solid.getRelationship(c);
+ assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.CONTAINS || relationship == GeoArea.WITHIN);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.25, -Math.PI * 0.25, -1.0, 1.0);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
+ assertEquals(1.0, b.getRightLongitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.25, b.getMaxLatitude(), 0.000001);
+ assertEquals(0.382051, xyzb.getMinimumX(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
+ assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(0.707107, xyzb.getMaximumZ(), 0.000001);
+
+ GeoArea area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX() - 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMaximumX() + 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMinimumY() - 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMaximumY() + 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMinimumZ() - 2.0 * Vector.MINIMUM_RESOLUTION,
+ xyzb.getMaximumZ() + 2.0 * Vector.MINIMUM_RESOLUTION);
+ assertEquals(GeoArea.WITHIN, area.getRelationship(c));
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -1.0, 1.0);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
+ assertEquals(1.0, b.getRightLongitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+ assertEquals(0.382051, xyzb.getMinimumX(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
+ assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(0.0, xyzb.getMaximumZ(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, 1.0, -1.0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ //assertEquals(1.0,b.getLeftLongitude(),0.000001);
+ //assertEquals(-1.0,b.getRightLongitude(),0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumX(), 0.000001);
+ assertEquals(0.540303, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumY(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-0.707107, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(0.0, xyzb.getMaximumZ(), 0.000001);
+
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -1.0, 1.0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-1.0, b.getLeftLongitude(), 0.000001);
+ //assertEquals(1.0, b.getRightLongitude(), 0.000001);
+ assertEquals(0.0, xyzb.getMinimumX(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-0.841471, xyzb.getMinimumY(), 0.000001);
+ assertEquals(0.841471, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumZ(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 1.0, -1.0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(1.0,b.getLeftLongitude(),0.000001);
+ //assertEquals(-1.0,b.getRightLongitude(),0.000001);
+ assertEquals(-1.0, xyzb.getMinimumX(), 0.000001);
+ assertEquals(0.540303, xyzb.getMaximumX(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumY(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumY(), 0.000001);
+ assertEquals(-1.0, xyzb.getMinimumZ(), 0.000001);
+ assertEquals(1.0, xyzb.getMaximumZ(), 0.000001);
+
+ // Check wide variants of rectangle and longitude slice
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, -Math.PI + 0.1, Math.PI - 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 0.0, -Math.PI * 0.25, Math.PI - 0.1, -Math.PI + 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
+ assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25, b.getMinLatitude(), 0.000001);
+ assertEquals(0.0, b.getMaxLatitude(), 0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI + 0.1, Math.PI - 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI+0.1,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI-0.1,b.getRightLongitude(),0.000001);
+
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, Math.PI - 0.1, -Math.PI + 0.1);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
+ //assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
+
+ // Check latitude zone
+ c = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, 1.0, -1.0, -Math.PI, Math.PI);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-1.0, b.getMinLatitude(), 0.000001);
+ assertEquals(1.0, b.getMaxLatitude(), 0.000001);
+
+ // Now, combine a few things to test the bounds object
+ GeoBBox c1;
+ GeoBBox c2;
+
+ c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
+ c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
+
+ b = new LatLonBounds();
+ c1.getBounds(b);
+ c2.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+
+ c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI, 0.0);
+ c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI * 0.5);
+
+ b = new LatLonBounds();
+ c1.getBounds(b);
+ c2.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI*0.5,b.getRightLongitude(),0.000001);
+
+ c1 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, -Math.PI * 0.5, 0.0);
+ c2 = GeoBBoxFactory.makeGeoBBox(PlanetModel.SPHERE, Math.PI * 0.5, -Math.PI * 0.5, 0.0, Math.PI);
+
+ b = new LatLonBounds();
+ c1.getBounds(b);
+ c2.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ //assertEquals(-Math.PI * 0.5,b.getLeftLongitude(),0.000001);
+ //assertEquals(Math.PI,b.getRightLongitude(),0.000001);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java
new file mode 100755
index 0000000..186bf4c
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoCircleTest.java
@@ -0,0 +1,410 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+public class GeoCircleTest extends LuceneTestCase {
+
+ @Test
+ public void testCircleDistance() {
+ GeoCircle c;
+ GeoPoint gp;
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
+ assertEquals(Double.MAX_VALUE, c.computeDistance(DistanceStyle.NORMAL,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ assertEquals(0.0, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertEquals(0.05, c.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ assertEquals(0.049995, c.computeDistance(DistanceStyle.LINEAR,gp), 0.000001);
+ assertEquals(0.049979, c.computeDistance(DistanceStyle.NORMAL,gp), 0.000001);
+ }
+
+ @Test
+ public void testCircleFullWorld() {
+ GeoCircle c;
+ GeoPoint gp;
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, Math.PI);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertTrue(c.isWithin(gp));
+ LatLonBounds b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ }
+
+ @Test
+ public void testCirclePointWithin() {
+ GeoCircle c;
+ GeoPoint gp;
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
+ assertEquals(0.12,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),0.01);
+ assertEquals(0.4,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),0.01);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+ }
+
+ @Test
+ public void testCircleBounds() {
+ GeoCircle c;
+ LatLonBounds b;
+ XYZBounds xyzb;
+ GeoArea area;
+ GeoPoint p1;
+ GeoPoint p2;
+ int relationship;
+
+ // ...
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, -0.005931145568901605, -0.001942031539653079, 1.2991918568260272E-4);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84, 1.001098377143621, 1.001100011578687, -0.00207467080358696, -0.0018136665346280983, -0.006067808248760161, -0.005807683665759485);
+ p1 = new GeoPoint(PlanetModel.WGS84, -0.00591253844632244, -0.0020069187259065093);
+ p2 = new GeoPoint(1.001099185736782, -0.0020091272069679327, -0.005919118245803968);
+ assertTrue(c.isWithin(p1));
+ assertTrue(area.isWithin(p1));
+ relationship = area.getRelationship(c);
+ assertTrue(relationship != GeoArea.DISJOINT);
+
+ // Twelfth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.00824379317765984,-0.0011677469001838581,0.0011530035396910402);
+ p1 = new GeoPoint(PlanetModel.WGS84,-0.006505092992723671,0.007654282718327381);
+ p2 = new GeoPoint(1.0010681673665647,0.007662608264336381,-0.006512324005914593);
+ assertTrue(!c.isWithin(p1));
+ assertTrue(!c.isWithin(p2));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.OVERLAPS || relationship == GeoArea.WITHIN);
+ // Point is actually outside the bounds, and outside the shape
+ assertTrue(!area.isWithin(p1));
+ // Approximate point the same
+ assertTrue(!area.isWithin(p2));
+
+ // Eleventh BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-0.004431288600558495,-0.003687846671278374,1.704543429364245E-8);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Tenth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.0018829770647349636,-0.001969499061382591,1.3045439293158305E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Ninth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-4.211990380885122E-5,-0.0022958453508173044,1.4318475623498535E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Eighth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,0.005321278689117842,-0.00216937368755372,1.5306034422500785E-4);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Seventh BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE,-0.0021627146783861745, -0.0017298167021592304,2.0818312293195752E-4);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println(area);
+ relationship = area.getRelationship(c);
+ assertTrue(GeoArea.WITHIN == relationship || GeoArea.OVERLAPS == relationship);
+
+ // Sixth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84,-0.006450320645814321,0.004660694205115142,0.00489710732634323);
+ //xyzb = new XYZBounds();
+ //c.getBounds(xyzb);
+ //System.err.println("xmin="+xyzb.getMinimumX()+", xmax="+xyzb.getMaximumX()+",ymin="+xyzb.getMinimumY()+", ymax="+xyzb.getMaximumY()+",zmin="+xyzb.getMinimumZ()+", zmax="+xyzb.getMaximumZ());
+ //xmin=1.0010356621420726, xmax=1.0011141249179447,ymin=-2.5326643901354566E-4, ymax=0.009584741915757169,zmin=-0.011359874956269283, zmax=-0.0015549504447452225
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,1.0010822580620098,1.0010945779732867,0.007079167343247293,0.007541006774427837,-0.0021855011220022575,-0.001896122718181518);
+ assertTrue(GeoArea.CONTAINS != area.getRelationship(c));
+ /*
+ p1 = new GeoPoint(1.0010893045436076,0.007380935180644008,-0.002140671370616495);
+ // This has a different bounding box, so we can't use it.
+ //p2 = new GeoPoint(PlanetModel.WGS84,-0.002164069780096702, 0.007505617500830066);
+ p2 = new GeoPoint(PlanetModel.WGS84,p1.getLatitude(),p1.getLongitude());
+ assertTrue(PlanetModel.WGS84.pointOnSurface(p2));
+ assertTrue(!c.isWithin(p2));
+ assertTrue(!area.isWithin(p2));
+ assertTrue(!c.isWithin(p1));
+ assertTrue(PlanetModel.WGS84.pointOnSurface(p1)); // This fails
+ assertTrue(!area.isWithin(p1)); // This fails
+ */
+
+ // Fifth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.004282454525970269, -1.6739831367422277E-4, 1.959639723134033E-6);
+ assertTrue(c.isWithin(c.getEdgePoints()[0]));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ assertTrue(GeoArea.WITHIN == area.getRelationship(c) || GeoArea.OVERLAPS == area.getRelationship(c));
+
+ // Fourth BKD discovered failure
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.0048795517261255, 0.004053904306995974, 5.93699764258874E-6);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ assertTrue(GeoArea.WITHIN == area.getRelationship(c) || GeoArea.OVERLAPS == area.getRelationship(c));
+
+ // Yet another test case from BKD
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, 0.006229478708446979, 0.005570196723795424, 3.840276763694387E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ p1 = new GeoPoint(PlanetModel.WGS84, 0.006224927111830945, 0.005597367237251763);
+ p2 = new GeoPoint(1.0010836083810235, 0.005603490759433942, 0.006231850560862502);
+ assertTrue(PlanetModel.WGS84.pointOnSurface(p1));
+ //assertTrue(PlanetModel.WGS84.pointOnSurface(p2));
+ assertTrue(c.isWithin(p1));
+ assertTrue(c.isWithin(p2));
+ assertTrue(area.isWithin(p1));
+ assertTrue(area.isWithin(p2));
+
+ // Another test case from BKD
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.005955031040627789, -0.0029274772647399153, 1.601488279374338E-5);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+
+ // Test case from BKD
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.765816119338, 0.991848766844, 0.8153163226330487);
+ p1 = new GeoPoint(0.7692262265236023, -0.055089298115534646, -0.6365973465711254);
+ assertTrue(c.isWithin(p1));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ assertTrue(p1.x >= xyzb.getMinimumX() && p1.x <= xyzb.getMaximumX());
+ assertTrue(p1.y >= xyzb.getMinimumY() && p1.y <= xyzb.getMaximumY());
+ assertTrue(p1.z >= xyzb.getMinimumZ() && p1.z <= xyzb.getMaximumZ());
+
+ // Vertical circle cases
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, -0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.4, b.getLeftLongitude(), 0.000001);
+ assertEquals(0.6, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.1, b.getLeftLongitude(), 0.000001);
+ assertEquals(0.1, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.000001);
+ assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ // Horizontal circle cases
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertTrue(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI * 0.5 - 0.1, b.getMinLatitude(), 0.000001);
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertTrue(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertTrue(b.checkNoBottomLatitudeBound());
+ assertEquals(-Math.PI * 0.5 + 0.1, b.getMaxLatitude(), 0.000001);
+
+ // Now do a somewhat tilted plane, facing different directions.
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, 0.0, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI * 0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.5 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(Math.PI * 0.5 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -Math.PI * 0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-Math.PI * 0.5 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI * 0.5 + 0.1, b.getRightLongitude(), 0.00001);
+
+ // Slightly tilted, PI/4 direction.
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.01, Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.09, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.11, b.getMinLatitude(), 0.000001);
+ assertEquals(Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, -0.01, -Math.PI * 0.25, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.09, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.11, b.getMinLatitude(), 0.000001);
+ assertEquals(-Math.PI * 0.25 - 0.1, b.getLeftLongitude(), 0.00001);
+ assertEquals(-Math.PI * 0.25 + 0.1, b.getRightLongitude(), 0.00001);
+
+ // Now do a somewhat tilted plane.
+ c = GeoCircleFactory.makeGeoCircle(PlanetModel.SPHERE, 0.01, -0.5, 0.1);
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(0.11, b.getMaxLatitude(), 0.000001);
+ assertEquals(-0.09, b.getMinLatitude(), 0.000001);
+ assertEquals(-0.6, b.getLeftLongitude(), 0.00001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.00001);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java
new file mode 100755
index 0000000..a6ca404
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoConvexPolygonTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoConvexPolygonTest {
+
+
+ @Test
+ public void testPolygonPointWithin() {
+ GeoConvexPolygon c;
+ GeoPoint gp;
+ c = new GeoConvexPolygon(PlanetModel.SPHERE, -0.1, -0.5);
+ c.addPoint(0.0, -0.6, false);
+ c.addPoint(0.1, -0.5, false);
+ c.addPoint(0.0, -0.4, false);
+ c.done(false);
+ // Sample some points within
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ // Sample some nearby points outside, and compute distance-to-shape for them as well
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
+ assertFalse(c.isWithin(gp));
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.ARC,gp),1e-12);
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.NORMAL,gp),1e-3);
+ assertEquals(0.05,c.computeOutsideDistance(DistanceStyle.LINEAR,gp),1e-3);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ // Random points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+ }
+
+ @Test
+ public void testPolygonBounds() {
+ GeoConvexPolygon c;
+ LatLonBounds b;
+
+ c = new GeoConvexPolygon(PlanetModel.SPHERE, -0.1, -0.5);
+ c.addPoint(0.0, -0.6, false);
+ c.addPoint(0.1, -0.5, false);
+ c.addPoint(0.0, -0.4, false);
+ c.done(false);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java
new file mode 100644
index 0000000..d5fcbdd
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoModelTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test basic plane functionality.
+ */
+public class GeoModelTest {
+
+ protected final static PlanetModel scaledModel = new PlanetModel(1.2,1.5);
+
+ @Test
+ public void testBasicCircle() {
+ // The point of this test is just to make sure nothing blows up doing normal things with a quite non-spherical model
+ // Make sure that the north pole is in the circle, and south pole isn't
+ final GeoPoint northPole = new GeoPoint(scaledModel, Math.PI * 0.5, 0.0);
+ final GeoPoint southPole = new GeoPoint(scaledModel, -Math.PI * 0.5, 0.0);
+ final GeoPoint point1 = new GeoPoint(scaledModel, Math.PI * 0.25, 0.0);
+ final GeoPoint point2 = new GeoPoint(scaledModel, Math.PI * 0.125, 0.0);
+
+ GeoCircle circle = new GeoStandardCircle(scaledModel, Math.PI * 0.5, 0.0, 0.01);
+ assertTrue(circle.isWithin(northPole));
+ assertFalse(circle.isWithin(southPole));
+ assertFalse(circle.isWithin(point1));
+ LatLonBounds bounds;
+ bounds = new LatLonBounds();
+ circle.getBounds(bounds);
+ assertTrue(bounds.checkNoLongitudeBound());
+ assertTrue(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI * 0.5 - 0.01, bounds.getMinLatitude(), 0.01);
+
+ circle = new GeoStandardCircle(scaledModel, Math.PI * 0.25, 0.0, 0.01);
+ assertTrue(circle.isWithin(point1));
+ assertFalse(circle.isWithin(northPole));
+ assertFalse(circle.isWithin(southPole));
+ bounds = new LatLonBounds();
+ circle.getBounds(bounds);
+ assertFalse(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoLongitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ assertEquals(Math.PI * 0.25 + 0.01, bounds.getMaxLatitude(), 0.00001);
+ assertEquals(Math.PI * 0.25 - 0.01, bounds.getMinLatitude(), 0.00001);
+ assertEquals(-0.0125, bounds.getLeftLongitude(), 0.0001);
+ assertEquals(0.0125, bounds.getRightLongitude(), 0.0001);
+
+ circle = new GeoStandardCircle(scaledModel, Math.PI * 0.125, 0.0, 0.01);
+ assertTrue(circle.isWithin(point2));
+ assertFalse(circle.isWithin(northPole));
+ assertFalse(circle.isWithin(southPole));
+ bounds = new LatLonBounds();
+ circle.getBounds(bounds);
+ assertFalse(bounds.checkNoLongitudeBound());
+ assertFalse(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ // Symmetric, as expected
+ assertEquals(Math.PI * 0.125 - 0.01, bounds.getMinLatitude(), 0.00001);
+ assertEquals(Math.PI * 0.125 + 0.01, bounds.getMaxLatitude(), 0.00001);
+ assertEquals(-0.0089, bounds.getLeftLongitude(), 0.0001);
+ assertEquals(0.0089, bounds.getRightLongitude(), 0.0001);
+
+ }
+
+ @Test
+ public void testBasicRectangle() {
+ final GeoBBox bbox = GeoBBoxFactory.makeGeoBBox(scaledModel, 1.0, 0.0, 0.0, 1.0);
+ final GeoPoint insidePoint = new GeoPoint(scaledModel, 0.5, 0.5);
+ assertTrue(bbox.isWithin(insidePoint));
+ final GeoPoint topOutsidePoint = new GeoPoint(scaledModel, 1.01, 0.5);
+ assertFalse(bbox.isWithin(topOutsidePoint));
+ final GeoPoint bottomOutsidePoint = new GeoPoint(scaledModel, -0.01, 0.5);
+ assertFalse(bbox.isWithin(bottomOutsidePoint));
+ final GeoPoint leftOutsidePoint = new GeoPoint(scaledModel, 0.5, -0.01);
+ assertFalse(bbox.isWithin(leftOutsidePoint));
+ final GeoPoint rightOutsidePoint = new GeoPoint(scaledModel, 0.5, 1.01);
+ assertFalse(bbox.isWithin(rightOutsidePoint));
+ final LatLonBounds bounds = new LatLonBounds();
+ bbox.getBounds(bounds);
+ assertFalse(bounds.checkNoLongitudeBound());
+ assertFalse(bounds.checkNoTopLatitudeBound());
+ assertFalse(bounds.checkNoBottomLatitudeBound());
+ assertEquals(1.0, bounds.getMaxLatitude(), 0.00001);
+ assertEquals(0.0, bounds.getMinLatitude(), 0.00001);
+ assertEquals(1.0, bounds.getRightLongitude(), 0.00001);
+ assertEquals(0.0, bounds.getLeftLongitude(), 0.00001);
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java
new file mode 100755
index 0000000..3746069
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPathTest.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.junit.Test;
+
+import static java.lang.Math.toRadians;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoPathTest {
+
+ @Test
+ public void testPathDistance() {
+ // Start with a really simple case
+ GeoPath p;
+ GeoPoint gp;
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(0.0, 0.0);
+ p.addPoint(0.0, 0.1);
+ p.addPoint(0.0, 0.2);
+ p.done();
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.15);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
+ assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
+ assertEquals(0.12 + 0.0, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, 0.05);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.25);
+ assertEquals(0.20 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.05);
+ assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+
+ // Compute path distances now
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(0.0, 0.0);
+ p.addPoint(0.0, 0.1);
+ p.addPoint(0.0, 0.2);
+ p.done();
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, 0.15);
+ assertEquals(0.15 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.12);
+ assertEquals(0.12, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+
+ // Now try a vertical path, and make sure distances are as expected
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(-Math.PI * 0.25, -0.5);
+ p.addPoint(Math.PI * 0.25, -0.5);
+ p.done();
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.1, -1.0);
+ assertEquals(Double.MAX_VALUE, p.computeDistance(DistanceStyle.ARC,gp), 0.0);
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.25 + 0.05, -0.5);
+ assertEquals(Math.PI * 0.5 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.25 - 0.05, -0.5);
+ assertEquals(0.0 + 0.05, p.computeDistance(DistanceStyle.ARC,gp), 0.000001);
+ }
+
+ @Test
+ public void testPathPointWithin() {
+ // Tests whether we can properly detect whether a point is within a path or not
+ GeoPath p;
+ GeoPoint gp;
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ // Build a diagonal path crossing the equator
+ p.addPoint(-0.2, -0.2);
+ p.addPoint(0.2, 0.2);
+ p.done();
+ // Test points on the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, -0.2);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, 0.1);
+ assertTrue(p.isWithin(gp));
+ // Test points off the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, 0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.2, -0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(p.isWithin(gp));
+ // Repeat the test, but across the terminator
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ // Build a diagonal path crossing the equator
+ p.addPoint(-0.2, Math.PI - 0.2);
+ p.addPoint(0.2, -Math.PI + 0.2);
+ p.done();
+ // Test points on the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, Math.PI - 0.2);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertTrue(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.1, -Math.PI + 0.1);
+ assertTrue(p.isWithin(gp));
+ // Test points off the path
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.2, -Math.PI + 0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.2, Math.PI - 0.2);
+ assertFalse(p.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(p.isWithin(gp));
+
+ }
+
+ @Test
+ public void testGetRelationship() {
+ GeoArea rect;
+ GeoPath p;
+ GeoPath c;
+ GeoPoint point;
+ GeoPoint pointApprox;
+ int relationship;
+ GeoArea area;
+ PlanetModel planetModel;
+
+ planetModel = new PlanetModel(1.151145876105594, 0.8488541238944061);
+ c = new GeoPath(planetModel, 0.008726646259971648);
+ c.addPoint(-0.6925658899376476, 0.6316613927914589);
+ c.addPoint(0.27828548161836364, 0.6785795524104564);
+ c.done();
+ point = new GeoPoint(planetModel,-0.49298555067758226, 0.9892440995026406);
+ pointApprox = new GeoPoint(0.5110940362119821, 0.7774603209946239, -0.49984312299556544);
+ area = GeoAreaFactory.makeGeoArea(planetModel, 0.49937141144985997, 0.5161765426256085, 0.3337218719537796,0.8544419570901649, -0.6347692823688085, 0.3069696588119369);
+ assertTrue(!c.isWithin(point));
+
+ // Start by testing the basic kinds of relationship, increasing in order of difficulty.
+
+ p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(-0.3, -0.3);
+ p.addPoint(0.3, 0.3);
+ p.done();
+ // Easiest: The path is wholly contains the georect
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.05, 0.05);
+ assertEquals(GeoArea.CONTAINS, rect.getRelationship(p));
+ // Next easiest: Some endpoints of the rectangle are inside, and some are outside.
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.05, 0.5);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ // Now, all points are outside, but the figures intersect
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.05, -0.05, -0.5, 0.5);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ // Finally, all points are outside, and the figures *do not* intersect
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, 0.5);
+ assertEquals(GeoArea.WITHIN, rect.getRelationship(p));
+ // Check that segment edge overlap detection works
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.1, 0.0, -0.1, 0.0);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.2, 0.1, -0.2, -0.1);
+ assertEquals(GeoArea.DISJOINT, rect.getRelationship(p));
+ // Check if overlap at endpoints behaves as expected next
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, -0.35);
+ assertEquals(GeoArea.OVERLAPS, rect.getRelationship(p));
+ rect = new GeoRectangle(PlanetModel.SPHERE, 0.5, -0.5, -0.5, -0.45);
+ assertEquals(GeoArea.DISJOINT, rect.getRelationship(p));
+
+ }
+
+ @Test
+ public void testPathBounds() {
+ GeoPath c;
+ LatLonBounds b;
+ XYZBounds xyzb;
+ GeoPoint point;
+ int relationship;
+ GeoArea area;
+ PlanetModel planetModel;
+
+ planetModel = new PlanetModel(0.751521665790406,1.248478334209594);
+ c = new GeoPath(planetModel, 0.7504915783575618);
+ c.addPoint(0.10869761172400265, 0.08895880215465272);
+ c.addPoint(0.22467878641991612, 0.10972973084229565);
+ c.addPoint(-0.7398772468744732, -0.4465812941383364);
+ c.addPoint(-0.18462055300079366, -0.6713857796763727);
+ c.done();
+ point = new GeoPoint(planetModel,-0.626645355125733,-1.409304625439381);
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(planetModel,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+ assertTrue(area.isWithin(point));
+ // No longer true due to fixed GeoPath waypoints.
+ //assertTrue(c.isWithin(point));
+
+ c = new GeoPath(PlanetModel.WGS84, 0.6894050545377601);
+ c.addPoint(-0.0788176065762948, 0.9431251741731624);
+ c.addPoint(0.510387871458147, 0.5327078872484678);
+ c.addPoint(-0.5624521609859962, 1.5398841746888388);
+ c.addPoint(-0.5025171434638661, -0.5895998642788894);
+ c.done();
+ point = new GeoPoint(PlanetModel.WGS84, 0.023652082107211682, 0.023131910152748437);
+ //System.err.println("Point.x = "+point.x+"; point.y="+point.y+"; point.z="+point.z);
+ assertTrue(c.isWithin(point));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println("minx="+xyzb.getMinimumX()+" maxx="+xyzb.getMaximumX()+" miny="+xyzb.getMinimumY()+" maxy="+xyzb.getMaximumY()+" minz="+xyzb.getMinimumZ()+" maxz="+xyzb.getMaximumZ());
+ //System.err.println("point.x="+point.x+" point.y="+point.y+" point.z="+point.z);
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+ assertTrue(area.isWithin(point));
+
+ c = new GeoPath(PlanetModel.WGS84, 0.7766715171374766);
+ c.addPoint(-0.2751718361148076, -0.7786721269011477);
+ c.addPoint(0.5728375851539309, -1.2700115736820465);
+ c.done();
+ point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
+ assertTrue(c.isWithin(point));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ //System.err.println("minx="+xyzb.getMinimumX()+" maxx="+xyzb.getMaximumX()+" miny="+xyzb.getMinimumY()+" maxy="+xyzb.getMaximumY()+" minz="+xyzb.getMinimumZ()+" maxz="+xyzb.getMaximumZ());
+ //System.err.println("point.x="+point.x+" point.y="+point.y+" point.z="+point.z);
+ relationship = area.getRelationship(c);
+ assertTrue(relationship == GeoArea.WITHIN || relationship == GeoArea.OVERLAPS);
+ assertTrue(area.isWithin(point));
+
+ c = new GeoPath(PlanetModel.SPHERE, 0.1);
+ c.addPoint(-0.3, -0.3);
+ c.addPoint(0.3, 0.3);
+ c.done();
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.4046919, b.getLeftLongitude(), 0.000001);
+ assertEquals(0.4046919, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.3999999, b.getMinLatitude(), 0.000001);
+ assertEquals(0.3999999, b.getMaxLatitude(), 0.000001);
+
+ }
+
+ @Test
+ public void testCoLinear() {
+ // p1: (12,-90), p2: (11, -55), (129, -90)
+ GeoPath p = new GeoPath(PlanetModel.SPHERE, 0.1);
+ p.addPoint(toRadians(-90), toRadians(12));//south pole
+ p.addPoint(toRadians(-55), toRadians(11));
+ p.addPoint(toRadians(-90), toRadians(129));//south pole again
+ p.done();//at least test this doesn't bomb like it used too -- LUCENE-6520
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java
new file mode 100644
index 0000000..ed17928
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPointTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+import static com.carrotsearch.randomizedtesting.RandomizedTest.randomFloat;
+
+/**
+ * Test basic GeoPoint functionality.
+ */
+public class GeoPointTest extends LuceneTestCase {
+ static final double DEGREES_TO_RADIANS = Math.PI / 180;
+
+ @Test
+ public void testConversion() {
+ testPointRoundTrip(PlanetModel.SPHERE, 90 * DEGREES_TO_RADIANS, 0, 1e-6);
+ testPointRoundTrip(PlanetModel.SPHERE, -90 * DEGREES_TO_RADIANS, 0, 1e-6);
+ testPointRoundTrip(PlanetModel.WGS84, 90 * DEGREES_TO_RADIANS, 0, 1e-6);
+ testPointRoundTrip(PlanetModel.WGS84, -90 * DEGREES_TO_RADIANS, 0, 1e-6);
+
+ final int times = atLeast(100);
+ for (int i = 0; i < times; i++) {
+ final double pLat = (randomFloat() * 180.0 - 90.0) * DEGREES_TO_RADIANS;
+ final double pLon = (randomFloat() * 360.0 - 180.0) * DEGREES_TO_RADIANS;
+ testPointRoundTrip(PlanetModel.SPHERE, pLat, pLon, 1e-6);//1e-6 since there's a square root in there (Karl says)
+ testPointRoundTrip(PlanetModel.WGS84, pLat, pLon, 1e-6);
+ }
+ }
+
+ protected void testPointRoundTrip(PlanetModel planetModel, double pLat, double pLon, double epsilon) {
+ final GeoPoint p1 = new GeoPoint(planetModel, pLat, pLon);
+ // In order to force the reverse conversion, we have to construct a geopoint from just x,y,z
+ final GeoPoint p2 = new GeoPoint(p1.x, p1.y, p1.z);
+ // Now, construct the final point based on getLatitude() and getLongitude()
+ final GeoPoint p3 = new GeoPoint(planetModel, p2.getLatitude(), p2.getLongitude());
+ double dist = p1.arcDistance(p3);
+ assertEquals(0, dist, epsilon);
+ }
+
+ @Test
+ public void testSurfaceDistance() {
+ final int times = atLeast(100);
+ for (int i = 0; i < times; i++) {
+ final double p1Lat = (randomFloat() * 180.0 - 90.0) * DEGREES_TO_RADIANS;
+ final double p1Lon = (randomFloat() * 360.0 - 180.0) * DEGREES_TO_RADIANS;
+ final double p2Lat = (randomFloat() * 180.0 - 90.0) * DEGREES_TO_RADIANS;
+ final double p2Lon = (randomFloat() * 360.0 - 180.0) * DEGREES_TO_RADIANS;
+ final GeoPoint p1 = new GeoPoint(PlanetModel.SPHERE, p1Lat, p1Lon);
+ final GeoPoint p2 = new GeoPoint(PlanetModel.SPHERE, p2Lat, p2Lon);
+ final double arcDistance = p1.arcDistance(p2);
+ // Compute ellipsoid distance; it should agree for a sphere
+ final double surfaceDistance = PlanetModel.SPHERE.surfaceDistance(p1,p2);
+ assertEquals(arcDistance, surfaceDistance, 1e-6);
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadLatLon() {
+ new GeoPoint(PlanetModel.SPHERE, 50.0, 32.2);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
new file mode 100755
index 0000000..d9b220d
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GeoPolygonTest {
+
+
+ @Test
+ public void testPolygonPointWithin() {
+ GeoMembershipShape c;
+ GeoPoint gp;
+ List<GeoPoint> points;
+
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+ // Sample some points within
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ // Sample some nearby points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.65);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ // Random points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.01, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.7));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.8));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.7));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.01, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
+
+ /*
+ System.out.println("Points: ");
+ for (GeoPoint p : points) {
+ System.out.println(" "+p);
+ }
+ */
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+ // Sample some points within
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.55);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.45);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.05, -0.5);
+ assertTrue(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.7);
+ assertTrue(c.isWithin(gp));
+ // Sample some nearby points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, -0.35);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, -0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.15, -0.5);
+ assertFalse(c.isWithin(gp));
+ // Random points outside
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, Math.PI * 0.5, 0.0);
+ assertFalse(c.isWithin(gp));
+ gp = new GeoPoint(PlanetModel.SPHERE, 0.0, Math.PI);
+ assertFalse(c.isWithin(gp));
+
+ }
+
+ @Test
+ public void testPolygonBounds() {
+ GeoMembershipShape c;
+ LatLonBounds b;
+ List<GeoPoint> points;
+ XYZBounds xyzb;
+ GeoPoint point;
+ GeoArea area;
+
+ // BKD failure
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.WGS84, -0.36716183577912814, 1.4836349969188696));
+ points.add(new GeoPoint(PlanetModel.WGS84, 0.7846038240742979, -0.02743348424931823));
+ points.add(new GeoPoint(PlanetModel.WGS84, -0.7376479402362607, -0.5072961758807019));
+ points.add(new GeoPoint(PlanetModel.WGS84, -0.3760415907667887, 1.4970455334565513));
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, 1);
+
+ point = new GeoPoint(PlanetModel.WGS84, -0.01580760332365284, -0.03956004622490505);
+ assertTrue(c.isWithin(point));
+ xyzb = new XYZBounds();
+ c.getBounds(xyzb);
+ area = GeoAreaFactory.makeGeoArea(PlanetModel.WGS84,
+ xyzb.getMinimumX(), xyzb.getMaximumX(), xyzb.getMinimumY(), xyzb.getMaximumY(), xyzb.getMinimumZ(), xyzb.getMaximumZ());
+ assertTrue(area.isWithin(point));
+
+ points = new ArrayList<GeoPoint>();
+ points.add(new GeoPoint(PlanetModel.SPHERE, -0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.6));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.1, -0.5));
+ points.add(new GeoPoint(PlanetModel.SPHERE, 0.0, -0.4));
+
+ c = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points, 0);
+
+ b = new LatLonBounds();
+ c.getBounds(b);
+ assertFalse(b.checkNoLongitudeBound());
+ assertFalse(b.checkNoTopLatitudeBound());
+ assertFalse(b.checkNoBottomLatitudeBound());
+ assertEquals(-0.6, b.getLeftLongitude(), 0.000001);
+ assertEquals(-0.4, b.getRightLongitude(), 0.000001);
+ assertEquals(-0.1, b.getMinLatitude(), 0.000001);
+ assertEquals(0.1, b.getMaxLatitude(), 0.000001);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
new file mode 100644
index 0000000..91bd0c3
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test basic plane functionality.
+ */
+public class PlaneTest {
+
+
+ @Test
+ public void testIdenticalPlanes() {
+ final GeoPoint p = new GeoPoint(PlanetModel.SPHERE, 0.123, -0.456);
+ final Plane plane1 = new Plane(p, 0.0);
+ final Plane plane2 = new Plane(p, 0.0);
+ assertTrue(plane1.isNumericallyIdentical(plane2));
+ final Plane plane3 = new Plane(p, 0.1);
+ assertFalse(plane1.isNumericallyIdentical(plane3));
+ final Vector v1 = new Vector(0.1, -0.732, 0.9);
+ final double constant = 0.432;
+ final Vector v2 = new Vector(v1.x * constant, v1.y * constant, v1.z * constant);
+ final Plane p1 = new Plane(v1, 0.2);
+ final Plane p2 = new Plane(v2, 0.2 * constant);
+ assertTrue(p1.isNumericallyIdentical(p2));
+ }
+
+ @Test
+ public void testInterpolation() {
+ // [X=0.35168818443386646, Y=-0.19637966197066342, Z=0.9152870857244183],
+ // [X=0.5003343189532654, Y=0.522128543226148, Z=0.6906861469771293],
+
+ final GeoPoint start = new GeoPoint(0.35168818443386646, -0.19637966197066342, 0.9152870857244183);
+ final GeoPoint end = new GeoPoint(0.5003343189532654, 0.522128543226148, 0.6906861469771293);
+
+ // [A=-0.6135342247741855, B=0.21504338363863665, C=0.28188192383666794, D=0.0, side=-1.0] internal? false;
+ final Plane p = new Plane(-0.6135342247741855, 0.21504338363863665, 0.28188192383666794, 0.0);
+
+ final GeoPoint[] points = p.interpolate(start, end, new double[]{0.25, 0.50, 0.75});
+
+ for (GeoPoint point : points) {
+ assertTrue(p.evaluateIsZero(point));
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java
new file mode 100644
index 0000000..98c616e
--- /dev/null
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/XYZSolidTest.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+public class XYZSolidTest extends LuceneTestCase {
+
+ @Test
+ public void testNonDegenerateRelationships() {
+ XYZSolid s;
+ GeoShape shape;
+ // Something bigger than the world
+ s = new StandardXYZSolid(PlanetModel.SPHERE, -2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
+ // Any shape, except whole world, should be within.
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.WITHIN, s.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ // An XYZSolid represents a surface shape, which when larger than the world is in fact
+ // the entire world, so it should overlap the world.
+ assertEquals(GeoArea.OVERLAPS, s.getRelationship(shape));
+
+ // Something overlapping the world on only one side
+ s = new StandardXYZSolid(PlanetModel.SPHERE, -2.0, 0.0, -2.0, 2.0, -2.0, 2.0);
+ // Some things should be disjoint...
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
+ // And, some things should be within...
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.WITHIN, s.getRelationship(shape));
+ // And, some things should overlap.
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, s.getRelationship(shape));
+
+ // Partial world should be contained by GeoWorld object...
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, s.getRelationship(shape));
+
+ // Something inside the world
+ s = new StandardXYZSolid(PlanetModel.SPHERE, -0.1, 0.1, -0.1, 0.1, -0.1, 0.1);
+ // All shapes should be disjoint
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, s.getRelationship(shape));
+
+ }
+
+ @Test
+ public void testDegenerateRelationships() {
+ GeoArea solid;
+ GeoShape shape;
+
+ // Basic test of the factory method - non-degenerate
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, -2.0, 2.0, -2.0, 2.0, -2.0, 2.0);
+ // Any shape, except whole world, should be within.
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.WITHIN, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ // An XYZSolid represents a surface shape, which when larger than the world is in fact
+ // the entire world, so it should overlap the world.
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // Build a degenerate point, not on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a degenerate point that IS on the sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y), which has no points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -0.1, 0.1);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y) which has one point on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -0.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y) which has two points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 0.0, -1.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,z), which has no points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, 0.0, 0.0);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,z) which has one point on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 1.1, 0.0, 0.0);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape degenerate in (x,y) which has two points on sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -1.1, 1.1, 0.0, 0.0);
+ // inside everything that it touches?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // MHL for y-z check
+
+ // Build a shape that is degenerate in x, which has zero points intersecting sphere
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, -0.1, 0.1);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape that is degenerate in x, which has zero points intersecting sphere, second variation
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -0.1, 0.1, 1.1, 1.2);
+ // disjoint with everything?
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+
+ // Build a shape that is disjoint in X but intersects sphere in a complete circle
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, -1.1, 1.1, -1.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // Build a shape that is disjoint in X but intersects sphere in a half circle in Y
+ solid = GeoAreaFactory.makeGeoArea(PlanetModel.SPHERE, 0.0, 0.0, 0.0, 1.1, -1.1, 1.1);
+ // inside everything that it touches?
+ shape = new GeoWorld(PlanetModel.SPHERE);
+ assertEquals(GeoArea.CONTAINS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, 0.0, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, 0.0, -Math.PI * 0.5, 0.1);
+ assertEquals(GeoArea.DISJOINT, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+ shape = new GeoStandardCircle(PlanetModel.SPHERE, -Math.PI * 0.5, 0.0, 0.1);
+ assertEquals(GeoArea.OVERLAPS, solid.getRelationship(shape));
+
+ // MHL for degenerate Y
+ // MHL for degenerate Z
+
+ }
+
+}
[26/50] [abbrv] lucene-solr git commit: Merge branch 'SOLR-8782'
Posted by no...@apache.org.
Merge branch 'SOLR-8782'
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/406a1635
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/406a1635
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/406a1635
Branch: refs/heads/apiv2
Commit: 406a1635c11919cbd167eb5ea87461472dbc8d53
Parents: a0a571c 5b7be9d
Author: Alan Woodward <ro...@apache.org>
Authored: Tue Mar 8 10:53:39 2016 +0000
Committer: Alan Woodward <ro...@apache.org>
Committed: Tue Mar 8 10:53:39 2016 +0000
----------------------------------------------------------------------
solr/CHANGES.txt | 4 +
.../configsets/cloud-minimal/conf/schema.xml | 32 +
.../cloud-minimal/conf/solrconfig.xml | 48 ++
.../CollectionsAPIAsyncDistributedZkTest.java | 174 ++---
.../solr/security/BasicAuthIntegrationTest.java | 2 +-
.../solrj/request/CollectionAdminRequest.java | 691 +++++++++++++------
6 files changed, 622 insertions(+), 329 deletions(-)
----------------------------------------------------------------------
[36/50] [abbrv] lucene-solr git commit: LUCENE-7075: clean up
LegacyNumerics* usage in queries/ tests
Posted by no...@apache.org.
LUCENE-7075: clean up LegacyNumerics* usage in queries/ tests
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/f9fbf8bc
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/f9fbf8bc
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/f9fbf8bc
Branch: refs/heads/apiv2
Commit: f9fbf8bc1d6fa7667d260ed48428ffefc8fc3c5d
Parents: 75f18ad
Author: Robert Muir <rm...@apache.org>
Authored: Tue Mar 8 11:17:12 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Tue Mar 8 11:17:12 2016 -0500
----------------------------------------------------------------------
.../lucene/queries/function/FunctionTestSetup.java | 8 +++-----
.../queries/function/TestFunctionQuerySort.java | 4 ++--
.../lucene/queries/function/TestValueSources.java | 16 ----------------
3 files changed, 5 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9fbf8bc/lucene/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java b/lucene/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java
index d5a587d..2764a8f 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/FunctionTestSetup.java
@@ -21,12 +21,10 @@ import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.LegacyFloatField;
-import org.apache.lucene.document.LegacyIntField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
+import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
-import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
@@ -143,11 +141,11 @@ public abstract class FunctionTestSetup extends LuceneTestCase {
f = newField(TEXT_FIELD, "text of doc" + scoreAndID + textLine(i), customType2); // for regular search
d.add(f);
- f = new LegacyIntField(INT_FIELD, scoreAndID, Store.YES); // for function scoring
+ f = new StoredField(INT_FIELD, scoreAndID); // for function scoring
d.add(f);
d.add(new NumericDocValuesField(INT_FIELD, scoreAndID));
- f = new LegacyFloatField(FLOAT_FIELD, scoreAndID, Store.YES); // for function scoring
+ f = new StoredField(FLOAT_FIELD, scoreAndID); // for function scoring
d.add(f);
d.add(new NumericDocValuesField(FLOAT_FIELD, Float.floatToRawIntBits(scoreAndID)));
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9fbf8bc/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java
index b9e1eb2..67f67b2 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java
@@ -20,8 +20,8 @@ import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
-import org.apache.lucene.document.LegacyIntField;
import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter;
@@ -102,7 +102,7 @@ public class TestFunctionQuerySort extends LuceneTestCase {
RandomIndexWriter writer = new RandomIndexWriter(random(), dir, iwc);
Document doc = new Document();
- Field field = new LegacyIntField("value", 0, Field.Store.YES);
+ Field field = new StoredField("value", 0);
Field dvField = new NumericDocValuesField("value", 0);
doc.add(field);
doc.add(dvField);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9fbf8bc/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
----------------------------------------------------------------------
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
index 37a32da..509e0ab 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
@@ -24,11 +24,7 @@ import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.LegacyDoubleField;
import org.apache.lucene.document.Field;
-import org.apache.lucene.document.LegacyFloatField;
-import org.apache.lucene.document.LegacyIntField;
-import org.apache.lucene.document.LegacyLongField;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.document.StringField;
@@ -120,20 +116,12 @@ public class TestValueSources extends LuceneTestCase {
document.add(idField);
Field idDVField = new SortedDocValuesField("id", new BytesRef());
document.add(idDVField);
- Field doubleField = new LegacyDoubleField("double", 0d, Field.Store.NO);
- document.add(doubleField);
Field doubleDVField = new NumericDocValuesField("double", 0);
document.add(doubleDVField);
- Field floatField = new LegacyFloatField("float", 0f, Field.Store.NO);
- document.add(floatField);
Field floatDVField = new NumericDocValuesField("float", 0);
document.add(floatDVField);
- Field intField = new LegacyIntField("int", 0, Field.Store.NO);
- document.add(intField);
Field intDVField = new NumericDocValuesField("int", 0);
document.add(intDVField);
- Field longField = new LegacyLongField("long", 0L, Field.Store.NO);
- document.add(longField);
Field longDVField = new NumericDocValuesField("long", 0);
document.add(longDVField);
Field stringField = new StringField("string", "", Field.Store.NO);
@@ -146,13 +134,9 @@ public class TestValueSources extends LuceneTestCase {
for (String [] doc : documents) {
idField.setStringValue(doc[0]);
idDVField.setBytesValue(new BytesRef(doc[0]));
- doubleField.setDoubleValue(Double.valueOf(doc[1]));
doubleDVField.setLongValue(Double.doubleToRawLongBits(Double.valueOf(doc[1])));
- floatField.setFloatValue(Float.valueOf(doc[2]));
floatDVField.setLongValue(Float.floatToRawIntBits(Float.valueOf(doc[2])));
- intField.setIntValue(Integer.valueOf(doc[3]));
intDVField.setLongValue(Integer.valueOf(doc[3]));
- longField.setLongValue(Long.valueOf(doc[4]));
longDVField.setLongValue(Long.valueOf(doc[4]));
stringField.setStringValue(doc[5]);
stringDVField.setBytesValue(new BytesRef(doc[5]));
[06/50] [abbrv] lucene-solr git commit: LUCENE-7073: fix FieldType
issues with Points
Posted by no...@apache.org.
LUCENE-7073: fix FieldType issues with Points
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/4df4cb07
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/4df4cb07
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/4df4cb07
Branch: refs/heads/apiv2
Commit: 4df4cb07ac6bfe1a652bb784cb1a7f58e415701e
Parents: b87e392
Author: Robert Muir <rm...@apache.org>
Authored: Mon Mar 7 16:12:15 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Mon Mar 7 16:13:05 2016 -0500
----------------------------------------------------------------------
.../lucene/benchmark/byTask/feeds/DocMaker.java | 44 +++++++++-----------
.../benchmark/byTask/tasks/ReadTokensTask.java | 13 ++----
.../lucene/codecs/lucene60/package-info.java | 7 +++-
.../org/apache/lucene/document/FieldType.java | 24 +++++++----
.../document/SortedNumericDocValuesField.java | 4 +-
.../apache/lucene/document/TestFieldType.java | 15 +++++--
.../apache/lucene/index/TestPointValues.java | 3 +-
.../apache/lucene/facet/range/DoubleRange.java | 3 +-
8 files changed, 59 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java
----------------------------------------------------------------------
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java
index f2c863c..4afafc3 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/DocMaker.java
@@ -35,13 +35,12 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.lucene.benchmark.byTask.utils.Config;
import org.apache.lucene.document.Document;
+import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType.LegacyNumericType;
+import org.apache.lucene.document.FloatPoint;
+import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.LegacyIntField;
-import org.apache.lucene.document.LegacyDoubleField;
-import org.apache.lucene.document.LegacyLongField;
-import org.apache.lucene.document.LegacyFloatField;
+import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
@@ -119,8 +118,8 @@ public class DocMaker implements Closeable {
fields.put(ID_FIELD, new StringField(ID_FIELD, "", Field.Store.YES));
fields.put(NAME_FIELD, new Field(NAME_FIELD, "", ft));
- numericFields.put(DATE_MSEC_FIELD, new LegacyLongField(DATE_MSEC_FIELD, 0L, Field.Store.NO));
- numericFields.put(TIME_SEC_FIELD, new LegacyIntField(TIME_SEC_FIELD, 0, Field.Store.NO));
+ numericFields.put(DATE_MSEC_FIELD, new LongPoint(DATE_MSEC_FIELD, 0L));
+ numericFields.put(TIME_SEC_FIELD, new IntPoint(TIME_SEC_FIELD, 0));
doc = new Document();
} else {
@@ -148,7 +147,7 @@ public class DocMaker implements Closeable {
return f;
}
- Field getNumericField(String name, LegacyNumericType type) {
+ Field getNumericField(String name, Class<? extends Number> numericType) {
Field f;
if (reuseFields) {
f = numericFields.get(name);
@@ -157,21 +156,16 @@ public class DocMaker implements Closeable {
}
if (f == null) {
- switch(type) {
- case INT:
- f = new LegacyIntField(name, 0, Field.Store.NO);
- break;
- case LONG:
- f = new LegacyLongField(name, 0L, Field.Store.NO);
- break;
- case FLOAT:
- f = new LegacyFloatField(name, 0.0F, Field.Store.NO);
- break;
- case DOUBLE:
- f = new LegacyDoubleField(name, 0.0, Field.Store.NO);
- break;
- default:
- throw new AssertionError("Cannot get here");
+ if (numericType.equals(Integer.class)) {
+ f = new IntPoint(name, 0);
+ } else if (numericType.equals(Long.class)) {
+ f = new LongPoint(name, 0L);
+ } else if (numericType.equals(Float.class)) {
+ f = new FloatPoint(name, 0.0F);
+ } else if (numericType.equals(Double.class)) {
+ f = new DoublePoint(name, 0.0);
+ } else {
+ throw new UnsupportedOperationException("Unsupported numeric type: " + numericType);
}
if (reuseFields) {
numericFields.put(name, f);
@@ -278,14 +272,14 @@ public class DocMaker implements Closeable {
date = new Date();
}
- Field dateField = ds.getNumericField(DATE_MSEC_FIELD, FieldType.LegacyNumericType.LONG);
+ Field dateField = ds.getNumericField(DATE_MSEC_FIELD, Long.class);
dateField.setLongValue(date.getTime());
doc.add(dateField);
util.cal.setTime(date);
final int sec = util.cal.get(Calendar.HOUR_OF_DAY)*3600 + util.cal.get(Calendar.MINUTE)*60 + util.cal.get(Calendar.SECOND);
- Field timeSecField = ds.getNumericField(TIME_SEC_FIELD, LegacyNumericType.INT);
+ Field timeSecField = ds.getNumericField(TIME_SEC_FIELD, Integer.class);
timeSecField.setIntValue(sec);
doc.add(timeSecField);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java
----------------------------------------------------------------------
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java
index 4950d41..2e44b99 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTokensTask.java
@@ -26,11 +26,7 @@ import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.feeds.DocMaker;
import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.LegacyDoubleField;
-import org.apache.lucene.document.LegacyFloatField;
-import org.apache.lucene.document.LegacyIntField;
-import org.apache.lucene.document.LegacyLongField;
+import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexableField;
/**
@@ -73,11 +69,8 @@ public class ReadTokensTask extends PerfTask {
Analyzer analyzer = getRunData().getAnalyzer();
int tokenCount = 0;
for(final IndexableField field : fields) {
- if (!field.fieldType().tokenized() ||
- field instanceof LegacyIntField ||
- field instanceof LegacyLongField ||
- field instanceof LegacyFloatField ||
- field instanceof LegacyDoubleField) {
+ if (field.fieldType().indexOptions() == IndexOptions.NONE ||
+ field.fieldType().tokenized() == false) {
continue;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/core/src/java/org/apache/lucene/codecs/lucene60/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene60/package-info.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene60/package-info.java
index 64531f5..03a17ba 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene60/package-info.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene60/package-info.java
@@ -194,9 +194,9 @@
* </li>
* <li>
* {@link org.apache.lucene.codecs.lucene60.Lucene60PointsFormat Point values}.
- * Optional pair of files, recording dimesionally indexed fields, to enable fast
+ * Optional pair of files, recording dimensionally indexed fields, to enable fast
* numeric range filtering and large numeric values like BigInteger and BigDecimal (1D)
- * and geo shape intersection (2D, 3D).
+ * and geographic shape intersection (2D, 3D).
* </li>
* </ul>
* <p>Details on each of these are provided in their linked pages.</p>
@@ -396,6 +396,9 @@
* contain the zlib-crc32 checksum of the file.</li>
* <li>In version 4.9, DocValues has a new multi-valued numeric type (SortedNumeric)
* that is suitable for faceting/sorting/analytics.
+ * <li>In version 5.4, DocValues have been improved to store more information on disk:
+ * addresses for binary fields and ord indexes for multi-valued fields.
+ * <li>In version 6.0, Points were added, for multi-dimensional range/distance search.
* </li>
* </ul>
* <a name="Limitations"></a>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/core/src/java/org/apache/lucene/document/FieldType.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/FieldType.java b/lucene/core/src/java/org/apache/lucene/document/FieldType.java
index 1dfa879..ae84016 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FieldType.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FieldType.java
@@ -21,6 +21,7 @@ import org.apache.lucene.analysis.Analyzer; // javadocs
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexableFieldType;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.util.LegacyNumericUtils;
/**
@@ -75,8 +76,8 @@ public class FieldType implements IndexableFieldType {
this.numericType = ref.numericType();
this.numericPrecisionStep = ref.numericPrecisionStep();
this.docValuesType = ref.docValuesType();
- this.dimensionCount = dimensionCount;
- this.dimensionNumBytes = dimensionNumBytes;
+ this.dimensionCount = ref.dimensionCount;
+ this.dimensionNumBytes = ref.dimensionNumBytes;
// Do not copy frozen!
}
@@ -365,18 +366,24 @@ public class FieldType implements IndexableFieldType {
*/
public void setDimensions(int dimensionCount, int dimensionNumBytes) {
if (dimensionCount < 0) {
- throw new IllegalArgumentException("pointDimensionCount must be >= 0; got " + dimensionCount);
+ throw new IllegalArgumentException("dimensionCount must be >= 0; got " + dimensionCount);
+ }
+ if (dimensionCount > PointValues.MAX_DIMENSIONS) {
+ throw new IllegalArgumentException("dimensionCount must be <= " + PointValues.MAX_DIMENSIONS + "; got " + dimensionCount);
}
if (dimensionNumBytes < 0) {
- throw new IllegalArgumentException("pointNumBytes must be >= 0; got " + dimensionNumBytes);
+ throw new IllegalArgumentException("dimensionNumBytes must be >= 0; got " + dimensionNumBytes);
+ }
+ if (dimensionCount > PointValues.MAX_NUM_BYTES) {
+ throw new IllegalArgumentException("dimensionNumBytes must be <= " + PointValues.MAX_NUM_BYTES + "; got " + dimensionNumBytes);
}
if (dimensionCount == 0) {
if (dimensionNumBytes != 0) {
- throw new IllegalArgumentException("when pointDimensionCount is 0 pointNumBytes must 0; got " + dimensionNumBytes);
+ throw new IllegalArgumentException("when dimensionCount is 0, dimensionNumBytes must 0; got " + dimensionNumBytes);
}
} else if (dimensionNumBytes == 0) {
if (dimensionCount != 0) {
- throw new IllegalArgumentException("when pointNumBytes is 0 pointDimensionCount must 0; got " + dimensionCount);
+ throw new IllegalArgumentException("when dimensionNumBytes is 0, dimensionCount must 0; got " + dimensionCount);
}
}
@@ -484,6 +491,8 @@ public class FieldType implements IndexableFieldType {
public int hashCode() {
final int prime = 31;
int result = 1;
+ result = prime * result + dimensionCount;
+ result = prime * result + dimensionNumBytes;
result = prime * result + ((docValuesType == null) ? 0 : docValuesType.hashCode());
result = prime * result + indexOptions.hashCode();
result = prime * result + numericPrecisionStep;
@@ -504,6 +513,8 @@ public class FieldType implements IndexableFieldType {
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
FieldType other = (FieldType) obj;
+ if (dimensionCount != other.dimensionCount) return false;
+ if (dimensionNumBytes != other.dimensionNumBytes) return false;
if (docValuesType != other.docValuesType) return false;
if (indexOptions != other.indexOptions) return false;
if (numericPrecisionStep != other.numericPrecisionStep) return false;
@@ -517,5 +528,4 @@ public class FieldType implements IndexableFieldType {
if (tokenized != other.tokenized) return false;
return true;
}
-
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesField.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesField.java b/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesField.java
index 40ceb25..cbba218 100644
--- a/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesField.java
+++ b/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesField.java
@@ -31,10 +31,10 @@ import org.apache.lucene.index.DocValuesType;
*
* <p>
* Note that if you want to encode doubles or floats with proper sort order,
- * you will need to encode them with {@link org.apache.lucene.util.LegacyNumericUtils}:
+ * you will need to encode them with {@link org.apache.lucene.util.NumericUtils}:
*
* <pre class="prettyprint">
- * document.add(new SortedNumericDocValuesField(name, LegacyNumericUtils.floatToSortableInt(-5.3f)));
+ * document.add(new SortedNumericDocValuesField(name, NumericUtils.floatToSortableInt(-5.3f)));
* </pre>
*
* <p>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java b/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java
index 65f32d8..c49d4e0 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestFieldType.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Modifier;
import org.apache.lucene.document.FieldType.LegacyNumericType;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.index.PointValues;
import org.apache.lucene.util.LuceneTestCase;
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
@@ -70,6 +71,10 @@ public class TestFieldType extends LuceneTestCase {
FieldType ft10 = new FieldType();
ft10.setStoreTermVectors(true);
assertFalse(ft10.equals(ft));
+
+ FieldType ft11 = new FieldType();
+ ft11.setDimensions(1, 4);
+ assertFalse(ft11.equals(ft));
}
public void testPointsToString() {
@@ -90,14 +95,16 @@ public class TestFieldType extends LuceneTestCase {
}
private static FieldType randomFieldType() throws Exception {
+ // setDimensions handled special as values must be in-bounds.
+ Method setDimensionsMethod = FieldType.class.getMethod("setDimensions", int.class, int.class);
FieldType ft = new FieldType();
for (Method method : FieldType.class.getMethods()) {
- if ((method.getModifiers() & Modifier.PUBLIC) != 0 && method.getName().startsWith("set")) {
+ if (method.getName().startsWith("set")) {
final Class<?>[] parameterTypes = method.getParameterTypes();
final Object[] args = new Object[parameterTypes.length];
- if (method.getName().equals("setPointDimensions")) {
- args[0] = 1 + random().nextInt(15);
- args[1] = 1 + random().nextInt(100);
+ if (method.equals(setDimensionsMethod)) {
+ args[0] = 1 + random().nextInt(PointValues.MAX_DIMENSIONS);
+ args[1] = 1 + random().nextInt(PointValues.MAX_NUM_BYTES);
} else {
for (int i = 0; i < args.length; ++i) {
args[i] = randomValue(parameterTypes[i]);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
index 9faa0bc..7231b1a 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java
@@ -385,9 +385,8 @@ public class TestPointValues extends LuceneTestCase {
for(int i=0;i<values.length;i++) {
values[i] = new byte[4];
}
- doc.add(new BinaryPoint("dim", values));
expectThrows(IllegalArgumentException.class, () -> {
- w.addDocument(doc);
+ doc.add(new BinaryPoint("dim", values));
});
Document doc2 = new Document();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4df4cb07/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java b/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
index 7585708..6f005ed 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
@@ -32,7 +32,6 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
import org.apache.lucene.search.Weight;
-import org.apache.lucene.util.LegacyNumericUtils;
import org.apache.lucene.util.NumericUtils;
/** Represents a range over double values.
@@ -50,7 +49,7 @@ public final class DoubleRange extends Range {
super(label);
// TODO: if DoubleDocValuesField used
- // LegacyNumericUtils.doubleToSortableLong format (instead of
+ // NumericUtils.doubleToSortableLong format (instead of
// Double.doubleToRawLongBits) we could do comparisons
// in long space
[13/50] [abbrv] lucene-solr git commit: LUCENE-7056: Geo3D package
re-org
Posted by no...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
new file mode 100644
index 0000000..da9799a
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWideSouthRectangle.java
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box wider than PI but limited on three sides (top lat,
+ * left lon, right lon).
+ *
+ * @lucene.internal
+ */
+public class GeoWideSouthRectangle extends GeoBaseBBox {
+ /** Top latitude of rect */
+ protected final double topLat;
+ /** Left longitude of rect */
+ protected final double leftLon;
+ /** Right longitude of rect */
+ protected final double rightLon;
+
+ /** Cosine of middle latitude */
+ protected final double cosMiddleLat;
+
+ /** Upper left hand corner */
+ protected final GeoPoint ULHC;
+ /** Upper right hand corner */
+ protected final GeoPoint URHC;
+
+ /** The top plane */
+ protected final SidedPlane topPlane;
+ /** The left plane */
+ protected final SidedPlane leftPlane;
+ /** The right plane */
+ protected final SidedPlane rightPlane;
+
+ /** Notable points for top plane */
+ protected final GeoPoint[] topPlanePoints;
+ /** Notable points for left plane */
+ protected final GeoPoint[] leftPlanePoints;
+ /** Notable points for right plane */
+ protected final GeoPoint[] rightPlanePoints;
+
+ /** Center point */
+ protected final GeoPoint centerPoint;
+
+ /** Left/right bounds */
+ protected final EitherBound eitherBound;
+
+ /** A point on the edge */
+ protected final GeoPoint[] edgePoints;
+
+ /**
+ * Accepts only values in the following ranges: lat: {@code -PI/2 -> PI/2}, lon: {@code -PI -> PI}.
+ * Horizontal angle must be greater than or equal to PI.
+ */
+ public GeoWideSouthRectangle(final PlanetModel planetModel, final double topLat, final double leftLon, double rightLon) {
+ super(planetModel);
+ // Argument checking
+ if (topLat > Math.PI * 0.5 || topLat < -Math.PI * 0.5)
+ throw new IllegalArgumentException("Top latitude out of range");
+ if (leftLon < -Math.PI || leftLon > Math.PI)
+ throw new IllegalArgumentException("Left longitude out of range");
+ if (rightLon < -Math.PI || rightLon > Math.PI)
+ throw new IllegalArgumentException("Right longitude out of range");
+ double extent = rightLon - leftLon;
+ if (extent < 0.0) {
+ extent += 2.0 * Math.PI;
+ }
+ if (extent < Math.PI)
+ throw new IllegalArgumentException("Width of rectangle too small");
+
+ this.topLat = topLat;
+ this.leftLon = leftLon;
+ this.rightLon = rightLon;
+
+ final double sinTopLat = Math.sin(topLat);
+ final double cosTopLat = Math.cos(topLat);
+ final double sinLeftLon = Math.sin(leftLon);
+ final double cosLeftLon = Math.cos(leftLon);
+ final double sinRightLon = Math.sin(rightLon);
+ final double cosRightLon = Math.cos(rightLon);
+
+ // Now build the four points
+ this.ULHC = new GeoPoint(planetModel, sinTopLat, sinLeftLon, cosTopLat, cosLeftLon, topLat, leftLon);
+ this.URHC = new GeoPoint(planetModel, sinTopLat, sinRightLon, cosTopLat, cosRightLon, topLat, rightLon);
+
+ final double middleLat = (topLat - Math.PI * 0.5) * 0.5;
+ final double sinMiddleLat = Math.sin(middleLat);
+ this.cosMiddleLat = Math.cos(middleLat);
+ // Normalize
+ while (leftLon > rightLon) {
+ rightLon += Math.PI * 2.0;
+ }
+ final double middleLon = (leftLon + rightLon) * 0.5;
+ final double sinMiddleLon = Math.sin(middleLon);
+ final double cosMiddleLon = Math.cos(middleLon);
+
+ this.centerPoint = new GeoPoint(planetModel, sinMiddleLat, sinMiddleLon, cosMiddleLat, cosMiddleLon);
+
+ this.topPlane = new SidedPlane(centerPoint, planetModel, sinTopLat);
+ this.leftPlane = new SidedPlane(centerPoint, cosLeftLon, sinLeftLon);
+ this.rightPlane = new SidedPlane(centerPoint, cosRightLon, sinRightLon);
+
+ this.topPlanePoints = new GeoPoint[]{ULHC, URHC};
+ this.leftPlanePoints = new GeoPoint[]{ULHC, planetModel.SOUTH_POLE};
+ this.rightPlanePoints = new GeoPoint[]{URHC, planetModel.SOUTH_POLE};
+
+ this.eitherBound = new EitherBound();
+
+ this.edgePoints = new GeoPoint[]{planetModel.SOUTH_POLE};
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ final double newTopLat = topLat + angle;
+ final double newBottomLat = -Math.PI * 0.5;
+ // Figuring out when we escalate to a special case requires some prefiguring
+ double currentLonSpan = rightLon - leftLon;
+ if (currentLonSpan < 0.0)
+ currentLonSpan += Math.PI * 2.0;
+ double newLeftLon = leftLon - angle;
+ double newRightLon = rightLon + angle;
+ if (currentLonSpan + 2.0 * angle >= Math.PI * 2.0) {
+ newLeftLon = -Math.PI;
+ newRightLon = Math.PI;
+ }
+ return GeoBBoxFactory.makeGeoBBox(planetModel, newTopLat, newBottomLat, newLeftLon, newRightLon);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return topPlane.isWithin(x, y, z) &&
+ (leftPlane.isWithin(x, y, z) ||
+ rightPlane.isWithin(x, y, z));
+ }
+
+ @Override
+ public double getRadius() {
+ // Here we compute the distance from the middle point to one of the corners. However, we need to be careful
+ // to use the longest of three distances: the distance to a corner on the top; the distnace to a corner on the bottom, and
+ // the distance to the right or left edge from the center.
+ final double centerAngle = (rightLon - (rightLon + leftLon) * 0.5) * cosMiddleLat;
+ final double topAngle = centerPoint.arcDistance(URHC);
+ return Math.max(centerAngle, topAngle);
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ return centerPoint;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ // Right and left bounds are essentially independent hemispheres; crossing into the wrong part of one
+ // requires crossing into the right part of the other. So intersection can ignore the left/right bounds.
+ return p.intersects(planetModel, topPlane, notablePoints, topPlanePoints, bounds, eitherBound) ||
+ p.intersects(planetModel, leftPlane, notablePoints, leftPlanePoints, bounds, topPlane) ||
+ p.intersects(planetModel, rightPlane, notablePoints, rightPlanePoints, bounds, topPlane);
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ bounds.isWide()
+ .addHorizontalPlane(planetModel, topLat, topPlane, eitherBound)
+ .addVerticalPlane(planetModel, rightLon, rightPlane, topPlane)
+ .addVerticalPlane(planetModel, leftLon, leftPlane, topPlane)
+ .addPoint(ULHC).addPoint(URHC).addPoint(planetModel.SOUTH_POLE);
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ //System.err.println(this+" comparing to "+path);
+ final int insideRectangle = isShapeInsideBBox(path);
+ if (insideRectangle == SOME_INSIDE) {
+ //System.err.println(" some inside");
+ return OVERLAPS;
+ }
+
+ final boolean insideShape = path.isWithin(planetModel.SOUTH_POLE);
+
+ if (insideRectangle == ALL_INSIDE && insideShape) {
+ //System.err.println(" both inside each other");
+ return OVERLAPS;
+ }
+
+ if (path.intersects(topPlane, topPlanePoints, eitherBound) ||
+ path.intersects(leftPlane, leftPlanePoints, topPlane) ||
+ path.intersects(rightPlane, rightPlanePoints, topPlane)) {
+ //System.err.println(" edges intersect");
+ return OVERLAPS;
+ }
+
+ if (insideRectangle == ALL_INSIDE) {
+ //System.err.println(" shape inside rectangle");
+ return WITHIN;
+ }
+
+ if (insideShape) {
+ //System.err.println(" rectangle inside shape");
+ return CONTAINS;
+ }
+
+ //System.err.println(" disjoint");
+ return DISJOINT;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ final double topDistance = distanceStyle.computeDistance(planetModel, topPlane, x,y,z, eitherBound);
+ // Because the rectangle exceeds 180 degrees, it is safe to compute the horizontally
+ // unbounded distance to both the left and the right and only take the minimum of the two.
+ final double leftDistance = distanceStyle.computeDistance(planetModel, leftPlane, x,y,z, topPlane);
+ final double rightDistance = distanceStyle.computeDistance(planetModel, rightPlane, x,y,z, topPlane);
+
+ final double ULHCDistance = distanceStyle.computeDistance(ULHC, x,y,z);
+ final double URHCDistance = distanceStyle.computeDistance(URHC, x,y,z);
+
+ return Math.min(
+ Math.min(
+ topDistance,
+ Math.min(leftDistance, rightDistance)),
+ Math.min(ULHCDistance, URHCDistance));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWideSouthRectangle))
+ return false;
+ GeoWideSouthRectangle other = (GeoWideSouthRectangle) o;
+ return super.equals(o) && other.ULHC.equals(ULHC) && other.URHC.equals(URHC);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + ULHC.hashCode();
+ result = 31 * result + URHC.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWideSouthRectangle: {planetmodel="+planetModel+", toplat=" + topLat + "(" + topLat * 180.0 / Math.PI + "), leftlon=" + leftLon + "(" + leftLon * 180.0 / Math.PI + "), rightlon=" + rightLon + "(" + rightLon * 180.0 / Math.PI + ")}";
+ }
+
+ /** Membership implementation representing width more than 180.
+ */
+ protected class EitherBound implements Membership {
+ /** Constructor.
+ */
+ public EitherBound() {
+ }
+
+ @Override
+ public boolean isWithin(final Vector v) {
+ return leftPlane.isWithin(v) || rightPlane.isWithin(v);
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return leftPlane.isWithin(x, y, z) || rightPlane.isWithin(x, y, z);
+ }
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
new file mode 100755
index 0000000..25bdc96
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoWorld.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Bounding box including the entire world.
+ *
+ * @lucene.internal
+ */
+public class GeoWorld extends GeoBaseBBox {
+ /** No points on the edge of the shape */
+ protected final static GeoPoint[] edgePoints = new GeoPoint[0];
+ /** Point in the middle of the world */
+ protected final GeoPoint originPoint;
+
+ /** Constructor.
+ *@param planetModel is the planet model.
+ */
+ public GeoWorld(final PlanetModel planetModel) {
+ super(planetModel);
+ originPoint = new GeoPoint(planetModel.ab, 1.0, 0.0, 0.0);
+ }
+
+ @Override
+ public GeoBBox expand(final double angle) {
+ return this;
+ }
+
+ @Override
+ public double getRadius() {
+ return Math.PI;
+ }
+
+ @Override
+ public GeoPoint getCenter() {
+ // Totally arbitrary
+ return originPoint;
+ }
+
+ @Override
+ public boolean isWithin(final double x, final double y, final double z) {
+ return true;
+ }
+
+ @Override
+ public GeoPoint[] getEdgePoints() {
+ return edgePoints;
+ }
+
+ @Override
+ public boolean intersects(final Plane p, final GeoPoint[] notablePoints, final Membership... bounds) {
+ return false;
+ }
+
+ @Override
+ public void getBounds(Bounds bounds) {
+ super.getBounds(bounds);
+ // Unnecessary
+ //bounds.noLongitudeBound().noTopLatitudeBound().noBottomLatitudeBound();
+ }
+
+ @Override
+ public int getRelationship(final GeoShape path) {
+ if (path.getEdgePoints().length > 0)
+ // Path is always within the world
+ return WITHIN;
+
+ return OVERLAPS;
+ }
+
+ @Override
+ protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
+ return 0.0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeoWorld))
+ return false;
+ return super.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "GeoWorld: {planetmodel="+planetModel+"}";
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LatLonBounds.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LatLonBounds.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LatLonBounds.java
new file mode 100644
index 0000000..627fdae
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LatLonBounds.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * An object for accumulating latitude/longitude bounds information.
+ *
+ * @lucene.experimental
+ */
+public class LatLonBounds implements Bounds {
+
+ /** Set to true if no longitude bounds can be stated */
+ protected boolean noLongitudeBound = false;
+ /** Set to true if no top latitude bound can be stated */
+ protected boolean noTopLatitudeBound = false;
+ /** Set to true if no bottom latitude bound can be stated */
+ protected boolean noBottomLatitudeBound = false;
+
+ /** If non-null, the minimum latitude bound */
+ protected Double minLatitude = null;
+ /** If non-null, the maximum latitude bound */
+ protected Double maxLatitude = null;
+
+ // For longitude bounds, this class needs to worry about keeping track of the distinction
+ // between left-side bounds and right-side bounds. Points are always submitted in pairs
+ // which have a maximum longitude separation of Math.PI. It's therefore always possible
+ // to determine which point represents a left bound, and which point represents a right
+ // bound.
+ //
+ // The next problem is how to compare two of the same kind of bound, e.g. two left bounds.
+ // We need to keep track of the leftmost longitude of the shape, but since this is a circle,
+ // this is arbitrary. What we could try to do instead would be to find a pair of (left,right) bounds such
+ // that:
+ // (1) all other bounds are within, and
+ // (2) the left minus right distance is minimized
+ // Unfortunately, there are still shapes that cannot be summarized in this way correctly.
+ // For example. consider a spiral that entirely circles the globe; we might arbitrarily choose
+ // lat/lon bounds that do not in fact circle the globe.
+ //
+ // One way to handle the longitude issue correctly is therefore to stipulate that we
+ // walk the bounds of the shape in some kind of connected order. Each point or circle is therefore
+ // added in a sequence. We also need an interior point to make sure we have the right
+ // choice of longitude bounds. But even with this, we still can't always choose whether the actual shape
+ // goes right or left.
+ //
+ // We can make the specification truly general by submitting the following in order:
+ // addSide(PlaneSide side, Membership... constraints)
+ // ...
+ // This is unambiguous, but I still can't see yet how this would help compute the bounds. The plane
+ // solution would in general seem to boil down to the same logic that relies on points along the path
+ // to define the shape boundaries. I guess the one thing that you do know for a bounded edge is that
+ // the endpoints are actually connected. But it is not clear whether relationship helps in any way.
+ //
+ // In any case, if we specify shapes by a sequence of planes, we should stipulate that multiple sequences
+ // are allowed, provided they progressively tile an area of the sphere that is connected and sequential.
+ // For example, paths do alternating rectangles and circles, in sequence. Each sequence member is
+ // described by a sequence of planes. I think it would also be reasonable to insist that the first segment
+ // of a shape overlap or adjoin the previous shape.
+ //
+ // Here's a way to think about it that might help: Traversing every edge should grow the longitude bounds
+ // in the direction of the traversal. So if the traversal is always known to be less than PI in total longitude
+ // angle, then it is possible to use the endpoints to determine the unambiguous extension of the envelope.
+ // For example, say you are currently at longitude -0.5. The next point is at longitude PI-0.1. You could say
+ // that the difference in longitude going one way around would be beter than the distance the other way
+ // around, and therefore the longitude envelope should be extended accordingly. But in practice, when an
+ // edge goes near a pole and may be inclined as well, the longer longitude change might be the right path, even
+ // if the arc length is short. So this too doesn't work.
+ //
+ // Given we have a hard time making an exact match, here's the current proposal. The proposal is a
+ // heuristic, based on the idea that most areas are small compared to the circumference of the globe.
+ // We keep track of the last point we saw, and take each point as it arrives, and compute its longitude.
+ // Then, we have a choice as to which way to expand the envelope: we can expand by going to the left or
+ // to the right. We choose the direction with the least longitude difference. (If we aren't sure,
+ // and can recognize that, we can set "unconstrained in longitude".)
+
+ /** If non-null, the left longitude bound */
+ protected Double leftLongitude = null;
+ /** If non-null, the right longitude bound */
+ protected Double rightLongitude = null;
+
+ /** Construct an empty bounds object */
+ public LatLonBounds() {
+ }
+
+ // Accessor methods
+
+ /** Get maximum latitude, if any.
+ *@return maximum latitude or null.
+ */
+ public Double getMaxLatitude() {
+ return maxLatitude;
+ }
+
+ /** Get minimum latitude, if any.
+ *@return minimum latitude or null.
+ */
+ public Double getMinLatitude() {
+ return minLatitude;
+ }
+
+ /** Get left longitude, if any.
+ *@return left longitude, or null.
+ */
+ public Double getLeftLongitude() {
+ return leftLongitude;
+ }
+
+ /** Get right longitude, if any.
+ *@return right longitude, or null.
+ */
+ public Double getRightLongitude() {
+ return rightLongitude;
+ }
+
+ // Degenerate case check
+
+ /** Check if there's no longitude bound.
+ *@return true if no longitude bound.
+ */
+ public boolean checkNoLongitudeBound() {
+ return noLongitudeBound;
+ }
+
+ /** Check if there's no top latitude bound.
+ *@return true if no top latitude bound.
+ */
+ public boolean checkNoTopLatitudeBound() {
+ return noTopLatitudeBound;
+ }
+
+ /** Check if there's no bottom latitude bound.
+ *@return true if no bottom latitude bound.
+ */
+ public boolean checkNoBottomLatitudeBound() {
+ return noBottomLatitudeBound;
+ }
+
+ // Modification methods
+
+ @Override
+ public Bounds addPlane(final PlanetModel planetModel, final Plane plane, final Membership... bounds) {
+ plane.recordBounds(planetModel, this, bounds);
+ return this;
+ }
+
+ @Override
+ public Bounds addHorizontalPlane(final PlanetModel planetModel,
+ final double latitude,
+ final Plane horizontalPlane,
+ final Membership... bounds) {
+ if (!noTopLatitudeBound || !noBottomLatitudeBound) {
+ addLatitudeBound(latitude);
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addVerticalPlane(final PlanetModel planetModel,
+ final double longitude,
+ final Plane verticalPlane,
+ final Membership... bounds) {
+ if (!noLongitudeBound) {
+ addLongitudeBound(longitude);
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds isWide() {
+ return noLongitudeBound();
+ }
+
+ @Override
+ public Bounds addXValue(final GeoPoint point) {
+ if (!noLongitudeBound) {
+ // Get a longitude value
+ addLongitudeBound(point.getLongitude());
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addYValue(final GeoPoint point) {
+ if (!noLongitudeBound) {
+ // Get a longitude value
+ addLongitudeBound(point.getLongitude());
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addZValue(final GeoPoint point) {
+ if (!noTopLatitudeBound || !noBottomLatitudeBound) {
+ // Compute a latitude value
+ double latitude = point.getLatitude();
+ addLatitudeBound(latitude);
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds addPoint(GeoPoint point) {
+ if (!noLongitudeBound) {
+ // Get a longitude value
+ addLongitudeBound(point.getLongitude());
+ }
+ if (!noTopLatitudeBound || !noBottomLatitudeBound) {
+ // Compute a latitude value
+ addLatitudeBound(point.getLatitude());
+ }
+ return this;
+ }
+
+ @Override
+ public Bounds noLongitudeBound() {
+ noLongitudeBound = true;
+ leftLongitude = null;
+ rightLongitude = null;
+ return this;
+ }
+
+ @Override
+ public Bounds noTopLatitudeBound() {
+ noTopLatitudeBound = true;
+ maxLatitude = null;
+ return this;
+ }
+
+ @Override
+ public Bounds noBottomLatitudeBound() {
+ noBottomLatitudeBound = true;
+ minLatitude = null;
+ return this;
+ }
+
+ // Protected methods
+
+ /** Update latitude bound.
+ *@param latitude is the latitude.
+ */
+ protected void addLatitudeBound(double latitude) {
+ if (!noTopLatitudeBound && (maxLatitude == null || latitude > maxLatitude))
+ maxLatitude = latitude;
+ if (!noBottomLatitudeBound && (minLatitude == null || latitude < minLatitude))
+ minLatitude = latitude;
+ }
+
+ /** Update longitude bound.
+ *@param longitude is the new longitude value.
+ */
+ protected void addLongitudeBound(double longitude) {
+ // If this point is within the current bounds, we're done; otherwise
+ // expand one side or the other.
+ if (leftLongitude == null && rightLongitude == null) {
+ leftLongitude = longitude;
+ rightLongitude = longitude;
+ } else {
+ // Compute whether we're to the right of the left value. But the left value may be greater than
+ // the right value.
+ double currentLeftLongitude = leftLongitude;
+ double currentRightLongitude = rightLongitude;
+ if (currentRightLongitude < currentLeftLongitude)
+ currentRightLongitude += 2.0 * Math.PI;
+ // We have a range to look at that's going in the right way.
+ // Now, do the same trick with the computed longitude.
+ if (longitude < currentLeftLongitude)
+ longitude += 2.0 * Math.PI;
+
+ if (longitude < currentLeftLongitude || longitude > currentRightLongitude) {
+ // Outside of current bounds. Consider carefully how we'll expand.
+ double leftExtensionAmt;
+ double rightExtensionAmt;
+ if (longitude < currentLeftLongitude) {
+ leftExtensionAmt = currentLeftLongitude - longitude;
+ } else {
+ leftExtensionAmt = currentLeftLongitude + 2.0 * Math.PI - longitude;
+ }
+ if (longitude > currentRightLongitude) {
+ rightExtensionAmt = longitude - currentRightLongitude;
+ } else {
+ rightExtensionAmt = longitude + 2.0 * Math.PI - currentRightLongitude;
+ }
+ if (leftExtensionAmt < rightExtensionAmt) {
+ currentLeftLongitude = leftLongitude - leftExtensionAmt;
+ while (currentLeftLongitude <= -Math.PI) {
+ currentLeftLongitude += 2.0 * Math.PI;
+ }
+ leftLongitude = currentLeftLongitude;
+ } else {
+ currentRightLongitude = rightLongitude + rightExtensionAmt;
+ while (currentRightLongitude > Math.PI) {
+ currentRightLongitude -= 2.0 * Math.PI;
+ }
+ rightLongitude = currentRightLongitude;
+ }
+ }
+ }
+ double testRightLongitude = rightLongitude;
+ if (testRightLongitude < leftLongitude)
+ testRightLongitude += Math.PI * 2.0;
+ if (testRightLongitude - leftLongitude >= Math.PI) {
+ noLongitudeBound = true;
+ leftLongitude = null;
+ rightLongitude = null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
new file mode 100644
index 0000000..0c89a16
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Linear distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class LinearDistance implements DistanceStyle {
+
+ /** A convenient instance */
+ public final static LinearDistance INSTANCE = new LinearDistance();
+
+ /** Constructor.
+ */
+ public LinearDistance() {
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.linearDistance(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.linearDistance(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.linearDistance(planetModel, point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.linearDistance(planetModel, x,y,z, bounds);
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
new file mode 100644
index 0000000..3fc37da
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Linear squared distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class LinearSquaredDistance implements DistanceStyle {
+
+ /** A convenient instance */
+ public final static LinearSquaredDistance INSTANCE = new LinearSquaredDistance();
+
+ /** Constructor.
+ */
+ public LinearSquaredDistance() {
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.linearDistanceSquared(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.linearDistanceSquared(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.linearDistanceSquared(planetModel, point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.linearDistanceSquared(planetModel, x,y,z, bounds);
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Membership.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Membership.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Membership.java
new file mode 100755
index 0000000..0cf6ff0
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Membership.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Implemented by Geo3D shapes that can calculate if a point is within it or not.
+ *
+ * @lucene.experimental
+ */
+public interface Membership {
+
+ /**
+ * Check if a point is within this shape.
+ *
+ * @param point is the point to check.
+ * @return true if the point is within this shape
+ */
+ public default boolean isWithin(final Vector point) {
+ return isWithin(point.x, point.y, point.z);
+ }
+
+ /**
+ * Check if a point is within this shape.
+ *
+ * @param x is x coordinate of point to check.
+ * @param y is y coordinate of point to check.
+ * @param z is z coordinate of point to check.
+ * @return true if the point is within this shape
+ */
+ public boolean isWithin(final double x, final double y, final double z);
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
new file mode 100644
index 0000000..50b2c7f
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Normal distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class NormalDistance implements DistanceStyle {
+
+ /** A convenient instance */
+ public final static NormalDistance INSTANCE = new NormalDistance();
+
+ /** Constructor.
+ */
+ public NormalDistance() {
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.normalDistance(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.normalDistance(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.normalDistance(point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.normalDistance(x,y,z, bounds);
+ }
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f7f81c32/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
new file mode 100644
index 0000000..a355d09
--- /dev/null
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.spatial3d.geom;
+
+/**
+ * Normal squared distance computation style.
+ *
+ * @lucene.experimental
+ */
+public class NormalSquaredDistance implements DistanceStyle {
+
+ /** A convenient instance */
+ public final static NormalSquaredDistance INSTANCE = new NormalSquaredDistance();
+
+ /** Constructor.
+ */
+ public NormalSquaredDistance() {
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final GeoPoint point2) {
+ return point1.normalDistanceSquared(point2);
+ }
+
+ @Override
+ public double computeDistance(final GeoPoint point1, final double x2, final double y2, final double z2) {
+ return point1.normalDistanceSquared(x2,y2,z2);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final GeoPoint point, final Membership... bounds) {
+ return plane.normalDistanceSquared(point, bounds);
+ }
+
+ @Override
+ public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds) {
+ return plane.normalDistanceSquared(x,y,z, bounds);
+ }
+
+}
+
+