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/04/07 22:30:15 UTC
[43/50] [abbrv] lucene-solr:apiv2: LUCENE-7173: Bring polygon API
into compliance with 2D version.
LUCENE-7173: Bring polygon API into compliance with 2D version.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/7289bc36
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/7289bc36
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/7289bc36
Branch: refs/heads/apiv2
Commit: 7289bc36f6eed387629f2a04ff140cc6d1f0959e
Parents: 9bef6c0
Author: Karl Wright <Da...@gmail.com>
Authored: Mon Apr 4 18:56:59 2016 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Mon Apr 4 18:56:59 2016 -0400
----------------------------------------------------------------------
.../org/apache/lucene/spatial3d/Geo3DPoint.java | 122 ++++++++++---------
1 file changed, 62 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/7289bc36/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 f0f2020..944ce39 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java
@@ -22,6 +22,8 @@ import java.util.ArrayList;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.PointValues;
+import org.apache.lucene.geo.Polygon;
+import org.apache.lucene.geo.GeoUtils;
import org.apache.lucene.spatial3d.geom.Vector;
import org.apache.lucene.spatial3d.geom.GeoPoint;
import org.apache.lucene.spatial3d.geom.GeoShape;
@@ -30,6 +32,8 @@ import org.apache.lucene.spatial3d.geom.GeoCircleFactory;
import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
import org.apache.lucene.spatial3d.geom.GeoPath;
+import org.apache.lucene.spatial3d.geom.GeoCompositePolygon;
+import org.apache.lucene.spatial3d.geom.GeoPolygon;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;
@@ -64,8 +68,8 @@ public final class Geo3DPoint extends Field {
*/
public Geo3DPoint(String name, double latitude, double longitude) {
super(name, TYPE);
- checkLatitude(latitude);
- checkLongitude(longitude);
+ GeoUtils.checkLatitude(latitude);
+ GeoUtils.checkLongitude(longitude);
// Translate latitude/longitude to x,y,z:
final GeoPoint point = new GeoPoint(PlanetModel.WGS84, fromDegrees(latitude), fromDegrees(longitude));
fillFieldsData(point.x, point.y, point.z);
@@ -94,8 +98,8 @@ public final class Geo3DPoint extends Field {
* @throws IllegalArgumentException if {@code field} is null, location has invalid coordinates, or radius is invalid.
*/
public static Query newDistanceQuery(final String field, final double latitude, final double longitude, final double radiusMeters) {
- checkLatitude(latitude);
- checkLongitude(longitude);
+ GeoUtils.checkLatitude(latitude);
+ GeoUtils.checkLongitude(longitude);
final GeoShape shape = GeoCircleFactory.makeGeoCircle(PlanetModel.WGS84, fromDegrees(latitude), fromDegrees(longitude), fromMeters(radiusMeters));
return newShapeQuery(field, shape);
}
@@ -113,10 +117,10 @@ public final class Geo3DPoint extends Field {
* @throws IllegalArgumentException if {@code field} is null, or the box has invalid coordinates.
*/
public static Query newBoxQuery(final String field, final double minLatitude, final double maxLatitude, final double minLongitude, final double maxLongitude) {
- checkLatitude(minLatitude);
- checkLongitude(minLongitude);
- checkLatitude(maxLatitude);
- checkLongitude(maxLongitude);
+ GeoUtils.checkLatitude(minLatitude);
+ GeoUtils.checkLongitude(minLongitude);
+ GeoUtils.checkLatitude(maxLatitude);
+ GeoUtils.checkLongitude(maxLongitude);
final GeoShape shape = GeoBBoxFactory.makeGeoBBox(PlanetModel.WGS84,
fromDegrees(maxLatitude), fromDegrees(minLatitude), fromDegrees(minLongitude), fromDegrees(maxLongitude));
return newShapeQuery(field, shape);
@@ -125,36 +129,28 @@ public final class Geo3DPoint extends Field {
/**
* Create a query for matching a polygon.
* <p>
- * The supplied {@code polyLatitudes}/{@code polyLongitudes} must be clockwise or counter-clockwise.
+ * The supplied {@code polygons} must be clockwise on the outside level, counterclockwise on the next level in, etc.
* @param field field name. must not be null.
- * @param polyLatitudes latitude values for points of the polygon: must be within standard +/-90 coordinate bounds.
- * @param polyLongitudes longitude values for points of the polygon: must be within standard +/-180 coordinate bounds.
+ * @param polygons is the list of polygons to use to construct the query; must be at least one.
* @return query matching points within this polygon
*/
- public static Query newPolygonQuery(final String field, final double[] polyLatitudes, final double[] polyLongitudes) {
- if (polyLatitudes.length != polyLongitudes.length) {
- throw new IllegalArgumentException("same number of latitudes and longitudes required");
- }
- if (polyLatitudes.length < 4) {
- throw new IllegalArgumentException("need three or more points");
- }
- if (polyLatitudes[0] != polyLatitudes[polyLatitudes.length-1] || polyLongitudes[0] != polyLongitudes[polyLongitudes.length-1]) {
- throw new IllegalArgumentException("last point must equal first point");
+ public static Query newPolygonQuery(final String field, final Polygon... polygons) {
+ if (polygons.length < 1) {
+ throw new IllegalArgumentException("need at least one polygon");
}
-
- final List<GeoPoint> polyPoints = new ArrayList<>(polyLatitudes.length-1);
- for (int i = 0; i < polyLatitudes.length-1; i++) {
- final double latitude = polyLatitudes[i];
- final double longitude = polyLongitudes[i];
- checkLatitude(latitude);
- checkLongitude(longitude);
- polyPoints.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(latitude), fromDegrees(longitude)));
+ final GeoShape shape;
+ if (polygons.length == 1) {
+ shape = fromPolygon(polygons[0], false);
+ } else {
+ final GeoCompositePolygon poly = new GeoCompositePolygon();
+ for (final Polygon p : polygons) {
+ poly.addShape(fromPolygon(p, false));
+ }
+ shape = poly;
}
- // We use the polygon constructor that looks at point order.
- final GeoShape shape = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, polyPoints, null);
return newShapeQuery(field, shape);
}
-
+
/**
* Create a query for matching a path.
* <p>
@@ -172,14 +168,47 @@ public final class Geo3DPoint extends Field {
for (int i = 0; i < pathLatitudes.length; i++) {
final double latitude = pathLatitudes[i];
final double longitude = pathLongitudes[i];
- checkLatitude(latitude);
- checkLongitude(longitude);
+ GeoUtils.checkLatitude(latitude);
+ GeoUtils.checkLongitude(longitude);
points[i] = new GeoPoint(PlanetModel.WGS84, fromDegrees(latitude), fromDegrees(longitude));
}
final GeoShape shape = new GeoPath(PlanetModel.WGS84, fromMeters(pathWidthMeters), points);
return newShapeQuery(field, shape);
}
+ /**
+ * Convert a Polygon object into a GeoPolygon.
+ * This method uses
+ * @param polygon is the Polygon object.
+ * @param reverseMe is true if the order of the points should be reversed.
+ * @return the GeoPolygon.
+ */
+ protected static GeoPolygon fromPolygon(final Polygon polygon, final boolean reverseMe) {
+ // First, assemble the "holes". The geo3d convention is to use the same polygon sense on the inner ring as the
+ // outer ring, so we process these recursively with reverseMe flipped.
+ final Polygon[] theHoles = polygon.getHoles();
+ final List<GeoPolygon> holeList = new ArrayList<>(theHoles.length);
+ for (final Polygon hole : theHoles) {
+ holeList.add(fromPolygon(hole, !reverseMe));
+ }
+ // Now do the polygon itself
+ final double[] polyLats = polygon.getPolyLats();
+ final double[] polyLons = polygon.getPolyLons();
+
+ // I presume the arguments have already been checked
+ final List<GeoPoint> points = new ArrayList<>(polyLats.length-1);
+ // We skip the last point anyway because the API requires it to be repeated, and geo3d doesn't repeat it.
+ for (int i = 0; i < polyLats.length - 1; i++) {
+ if (reverseMe) {
+ points.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(polyLats[i]), fromDegrees(polyLons[i])));
+ } else {
+ final int index = polyLats.length - 2 - i;
+ points.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(polyLats[index]), fromDegrees(polyLons[index])));
+ }
+ }
+ return GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, holeList);
+ }
+
/**
* Creates a new Geo3DPoint field with the specified x,y,z.
*
@@ -235,31 +264,4 @@ public final class Geo3DPoint extends Field {
return result.toString();
}
- // TODO LUCENE-7152: share this with GeoUtils.java from spatial module
-
- /** Minimum longitude value. */
- private static final double MIN_LON_INCL = -180.0D;
-
- /** Maximum longitude value. */
- private static final double MAX_LON_INCL = 180.0D;
-
- /** Minimum latitude value. */
- private static final double MIN_LAT_INCL = -90.0D;
-
- /** Maximum latitude value. */
- private static final double MAX_LAT_INCL = 90.0D;
-
- /** validates latitude value is within standard +/-90 coordinate bounds */
- private static void checkLatitude(double latitude) {
- if (Double.isNaN(latitude) || latitude < MIN_LAT_INCL || latitude > MAX_LAT_INCL) {
- throw new IllegalArgumentException("invalid latitude " + latitude + "; must be between " + MIN_LAT_INCL + " and " + MAX_LAT_INCL);
- }
- }
-
- /** validates longitude value is within standard +/-180 coordinate bounds */
- private static void checkLongitude(double longitude) {
- if (Double.isNaN(longitude) || longitude < MIN_LON_INCL || longitude > MAX_LON_INCL) {
- throw new IllegalArgumentException("invalid longitude " + longitude + "; must be between " + MIN_LON_INCL + " and " + MAX_LON_INCL);
- }
- }
}