You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2016/03/08 02:19:51 UTC
[10/32] lucene-solr git commit: LUCENE-7056: Geo3D package re-org
(cherry picked from commit 0093e26)
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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/3a31a8c7/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);
+
+}