You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by is...@apache.org on 2017/02/12 13:18:38 UTC
[14/18] lucene-solr:jira/solr-5944: Updating branch by merging latest
changes from master
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java
new file mode 100644
index 0000000..e38d9fe
--- /dev/null
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java
@@ -0,0 +1,132 @@
+/*
+ * 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.document;
+
+import java.io.IOException;
+
+import org.apache.lucene.geo.GeoEncodingUtils;
+import org.apache.lucene.geo.GeoUtils;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.SortedNumericDocValues;
+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.TwoPhaseIterator;
+import org.apache.lucene.search.Weight;
+
+/** Distance query for {@link LatLonDocValuesField}. */
+final class LatLonDocValuesDistanceQuery extends Query {
+
+ private final String field;
+ private final double latitude, longitude;
+ private final double radiusMeters;
+
+ LatLonDocValuesDistanceQuery(String field, double latitude, double longitude, double radiusMeters) {
+ if (Double.isFinite(radiusMeters) == false || radiusMeters < 0) {
+ throw new IllegalArgumentException("radiusMeters: '" + radiusMeters + "' is invalid");
+ }
+ GeoUtils.checkLatitude(latitude);
+ GeoUtils.checkLongitude(longitude);
+ if (field == null) {
+ throw new IllegalArgumentException("field must not be null");
+ }
+ this.field = field;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.radiusMeters = radiusMeters;
+ }
+
+ @Override
+ public String toString(String field) {
+ StringBuilder sb = new StringBuilder();
+ if (!this.field.equals(field)) {
+ sb.append(this.field);
+ sb.append(':');
+ }
+ sb.append(latitude);
+ sb.append(",");
+ sb.append(longitude);
+ sb.append(" +/- ");
+ sb.append(radiusMeters);
+ sb.append(" meters");
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (sameClassAs(obj) == false) {
+ return false;
+ }
+ LatLonDocValuesDistanceQuery other = (LatLonDocValuesDistanceQuery) obj;
+ return field.equals(other.field) &&
+ Double.doubleToLongBits(latitude) == Double.doubleToLongBits(other.latitude) &&
+ Double.doubleToLongBits(longitude) == Double.doubleToLongBits(other.longitude) &&
+ Double.doubleToLongBits(radiusMeters) == Double.doubleToLongBits(other.radiusMeters);
+ }
+
+ @Override
+ public int hashCode() {
+ int h = classHash();
+ h = 31 * h + field.hashCode();
+ h = 31 * h + Double.hashCode(latitude);
+ h = 31 * h + Double.hashCode(longitude);
+ h = 31 * h + Double.hashCode(radiusMeters);
+ return h;
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
+ return new ConstantScoreWeight(this, boost) {
+
+ private final GeoEncodingUtils.DistancePredicate distancePredicate = GeoEncodingUtils.createDistancePredicate(latitude, longitude, radiusMeters);
+
+ @Override
+ public Scorer scorer(LeafReaderContext context) throws IOException {
+ final SortedNumericDocValues values = context.reader().getSortedNumericDocValues(field);
+ if (values == null) {
+ return null;
+ }
+
+ final TwoPhaseIterator iterator = new TwoPhaseIterator(values) {
+
+ @Override
+ public boolean matches() throws IOException {
+ for (int i = 0, count = values.docValueCount(); i < count; ++i) {
+ final long value = values.nextValue();
+ final int lat = (int) (value >>> 32);
+ final int lon = (int) (value & 0xFFFFFFFF);
+ if (distancePredicate.test(lat, lon)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public float matchCost() {
+ return 100f; // TODO: what should it be?
+ }
+
+ };
+ return new ConstantScoreScorer(this, boost, iterator);
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesField.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesField.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesField.java
index 20154d2..08a7da7 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesField.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonDocValuesField.java
@@ -24,6 +24,9 @@ import static org.apache.lucene.geo.GeoEncodingUtils.encodeLongitude;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.search.FieldDoc;
+import org.apache.lucene.search.IndexOrDocValuesQuery;
+import org.apache.lucene.search.MatchNoDocsQuery;
+import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
/**
@@ -132,4 +135,47 @@ public class LatLonDocValuesField extends Field {
public static SortField newDistanceSort(String field, double latitude, double longitude) {
return new LatLonPointSortField(field, latitude, longitude);
}
+
+ /**
+ * Create a query for matching a bounding box using doc values.
+ * This query is usually slow as it does not use an index structure and needs
+ * to verify documents one-by-one in order to know whether they match. It is
+ * best used wrapped in an {@link IndexOrDocValuesQuery} alongside a
+ * {@link LatLonPoint#newBoxQuery}.
+ */
+ public static Query newBoxQuery(String field, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) {
+ // exact double values of lat=90.0D and lon=180.0D must be treated special as they are not represented in the encoding
+ // and should not drag in extra bogus junk! TODO: should encodeCeil just throw ArithmeticException to be less trappy here?
+ if (minLatitude == 90.0) {
+ // range cannot match as 90.0 can never exist
+ return new MatchNoDocsQuery("LatLonDocValuesField.newBoxQuery with minLatitude=90.0");
+ }
+ if (minLongitude == 180.0) {
+ if (maxLongitude == 180.0) {
+ // range cannot match as 180.0 can never exist
+ return new MatchNoDocsQuery("LatLonDocValuesField.newBoxQuery with minLongitude=maxLongitude=180.0");
+ } else if (maxLongitude < minLongitude) {
+ // encodeCeil() with dateline wrapping!
+ minLongitude = -180.0;
+ }
+ }
+ return new LatLonDocValuesBoxQuery(field, minLatitude, maxLatitude, minLongitude, maxLongitude);
+ }
+
+ /**
+ * Create a query for matching points within the specified distance of the supplied location.
+ * This query is usually slow as it does not use an index structure and needs
+ * to verify documents one-by-one in order to know whether they match. It is
+ * best used wrapped in an {@link IndexOrDocValuesQuery} alongside a
+ * {@link LatLonPoint#newDistanceQuery}.
+ * @param field field name. must not be null.
+ * @param latitude latitude at the center: must be within standard +/-90 coordinate bounds.
+ * @param longitude longitude at the center: must be within standard +/-180 coordinate bounds.
+ * @param radiusMeters maximum distance from the center in meters: must be non-negative and finite.
+ * @return query matching points within this distance
+ * @throws IllegalArgumentException if {@code field} is null, location has invalid coordinates, or radius is invalid.
+ */
+ public static Query newDistanceQuery(String field, double latitude, double longitude, double radiusMeters) {
+ return new LatLonDocValuesDistanceQuery(field, latitude, longitude, radiusMeters);
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
index 7a00cef..71ddf3d 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
@@ -18,6 +18,7 @@ package org.apache.lucene.document;
import java.io.IOException;
+import org.apache.lucene.geo.GeoEncodingUtils;
import org.apache.lucene.geo.GeoUtils;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.index.FieldInfo;
@@ -31,10 +32,10 @@ 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.ScorerSupplier;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.DocIdSetBuilder;
import org.apache.lucene.util.NumericUtils;
-import org.apache.lucene.util.SloppyMath;
import org.apache.lucene.util.StringHelper;
import static org.apache.lucene.geo.GeoEncodingUtils.decodeLatitude;
@@ -102,8 +103,19 @@ final class LatLonPointDistanceQuery extends Query {
return new ConstantScoreWeight(this, boost) {
+ final GeoEncodingUtils.DistancePredicate distancePredicate = GeoEncodingUtils.createDistancePredicate(latitude, longitude, radiusMeters);
+
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
+ ScorerSupplier scorerSupplier = scorerSupplier(context);
+ if (scorerSupplier == null) {
+ return null;
+ }
+ return scorerSupplier.get(false);
+ }
+
+ @Override
+ public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOException {
LeafReader reader = context.reader();
PointValues values = reader.getPointValues(field);
if (values == null) {
@@ -119,8 +131,7 @@ final class LatLonPointDistanceQuery extends Query {
// matching docids
DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field);
-
- values.intersect(
+ final IntersectVisitor visitor =
new IntersectVisitor() {
DocIdSetBuilder.BulkAdder adder;
@@ -151,11 +162,9 @@ final class LatLonPointDistanceQuery extends Query {
return;
}
- double docLatitude = decodeLatitude(packedValue, 0);
- double docLongitude = decodeLongitude(packedValue, Integer.BYTES);
-
- // its a match only if its sortKey <= our sortKey
- if (SloppyMath.haversinSortKey(latitude, longitude, docLatitude, docLongitude) <= sortKey) {
+ int docLatitude = NumericUtils.sortableBytesToInt(packedValue, 0);
+ int docLongitude = NumericUtils.sortableBytesToInt(packedValue, Integer.BYTES);
+ if (distancePredicate.test(docLatitude, docLongitude)) {
adder.add(docID);
}
}
@@ -185,32 +194,30 @@ final class LatLonPointDistanceQuery extends Query {
double latMax = decodeLatitude(maxPackedValue, 0);
double lonMax = decodeLongitude(maxPackedValue, Integer.BYTES);
- if ((longitude < lonMin || longitude > lonMax) && (axisLat+ Rectangle.AXISLAT_ERROR < latMin || axisLat- Rectangle.AXISLAT_ERROR > latMax)) {
- // circle not fully inside / crossing axis
- if (SloppyMath.haversinSortKey(latitude, longitude, latMin, lonMin) > sortKey &&
- SloppyMath.haversinSortKey(latitude, longitude, latMin, lonMax) > sortKey &&
- SloppyMath.haversinSortKey(latitude, longitude, latMax, lonMin) > sortKey &&
- SloppyMath.haversinSortKey(latitude, longitude, latMax, lonMax) > sortKey) {
- // no points inside
- return Relation.CELL_OUTSIDE_QUERY;
- }
- }
-
- if (lonMax - longitude < 90 && longitude - lonMin < 90 &&
- SloppyMath.haversinSortKey(latitude, longitude, latMin, lonMin) <= sortKey &&
- SloppyMath.haversinSortKey(latitude, longitude, latMin, lonMax) <= sortKey &&
- SloppyMath.haversinSortKey(latitude, longitude, latMax, lonMin) <= sortKey &&
- SloppyMath.haversinSortKey(latitude, longitude, latMax, lonMax) <= sortKey) {
- // we are fully enclosed, collect everything within this subtree
- return Relation.CELL_INSIDE_QUERY;
- } else {
- // recurse: its inside our bounding box(es), but not fully, or it wraps around.
- return Relation.CELL_CROSSES_QUERY;
- }
+ return GeoUtils.relate(latMin, latMax, lonMin, lonMax, latitude, longitude, sortKey, axisLat);
}
- });
+ };
+ final Weight weight = this;
+ return new ScorerSupplier() {
+
+ long cost = -1;
+
+ @Override
+ public Scorer get(boolean randomAccess) throws IOException {
+ values.intersect(visitor);
+ return new ConstantScoreScorer(weight, score(), result.build().iterator());
+ }
+
+ @Override
+ public long cost() {
+ if (cost == -1) {
+ cost = values.estimatePointCount(visitor);
+ }
+ assert cost >= 0;
+ return cost;
+ }
+ };
- return new ConstantScoreScorer(this, score(), result.build().iterator());
}
};
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
index ec7c682..c272b4d 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
@@ -35,6 +35,7 @@ import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.util.DocIdSetBuilder;
import org.apache.lucene.util.NumericUtils;
import org.apache.lucene.util.StringHelper;
+import org.apache.lucene.geo.GeoEncodingUtils;
import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Polygon2D;
@@ -92,6 +93,7 @@ final class LatLonPointInPolygonQuery extends Query {
NumericUtils.intToSortableBytes(encodeLongitude(box.maxLon), maxLon, 0);
final Polygon2D tree = Polygon2D.create(polygons);
+ final GeoEncodingUtils.PolygonPredicate polygonPredicate = GeoEncodingUtils.createPolygonPredicate(polygons, tree);
return new ConstantScoreWeight(this, boost) {
@@ -130,8 +132,8 @@ final class LatLonPointInPolygonQuery extends Query {
@Override
public void visit(int docID, byte[] packedValue) {
- if (tree.contains(decodeLatitude(packedValue, 0),
- decodeLongitude(packedValue, Integer.BYTES))) {
+ if (polygonPredicate.test(NumericUtils.sortableBytesToInt(packedValue, 0),
+ NumericUtils.sortableBytesToInt(packedValue, Integer.BYTES))) {
adder.add(docID);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
index fbf3dc3..04c8736 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
@@ -378,7 +378,7 @@ public class TermAutomatonQuery extends Query {
boolean any = false;
for(Map.Entry<Integer,TermContext> ent : termStates.entrySet()) {
TermContext termContext = ent.getValue();
- assert termContext.topReaderContext == ReaderUtil.getTopLevelContext(context) : "The top-reader used to create Weight (" + termContext.topReaderContext + ") is not the same as the current reader's top-reader (" + ReaderUtil.getTopLevelContext(context);
+ assert termContext.wasBuiltFor(ReaderUtil.getTopLevelContext(context)) : "The top-reader used to create Weight is not the same as the current reader's top-reader (" + ReaderUtil.getTopLevelContext(context);
BytesRef term = idToTerm.get(ent.getKey());
TermState state = termContext.get(context.ord);
if (state != null) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonDocValuesQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonDocValuesQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonDocValuesQueries.java
new file mode 100644
index 0000000..3c8bf4e
--- /dev/null
+++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestLatLonDocValuesQueries.java
@@ -0,0 +1,62 @@
+/*
+ * 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.search;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.LatLonDocValuesField;
+import org.apache.lucene.geo.BaseGeoPointTestCase;
+import org.apache.lucene.geo.GeoEncodingUtils;
+import org.apache.lucene.geo.Polygon;
+
+public class TestLatLonDocValuesQueries extends BaseGeoPointTestCase {
+
+ @Override
+ protected boolean supportsPolygons() {
+ return false;
+ }
+
+ @Override
+ protected void addPointToDoc(String field, Document doc, double lat, double lon) {
+ doc.add(new LatLonDocValuesField(field, lat, lon));
+ }
+
+ @Override
+ protected Query newRectQuery(String field, double minLat, double maxLat, double minLon, double maxLon) {
+ return LatLonDocValuesField.newBoxQuery(field, minLat, maxLat, minLon, maxLon);
+ }
+
+ @Override
+ protected Query newDistanceQuery(String field, double centerLat, double centerLon, double radiusMeters) {
+ return LatLonDocValuesField.newDistanceQuery(field, centerLat, centerLon, radiusMeters);
+ }
+
+ @Override
+ protected Query newPolygonQuery(String field, Polygon... polygons) {
+ fail();
+ return null;
+ }
+
+ @Override
+ protected double quantizeLat(double latRaw) {
+ return GeoEncodingUtils.decodeLatitude(GeoEncodingUtils.encodeLatitude(latRaw));
+ }
+
+ @Override
+ protected double quantizeLon(double lonRaw) {
+ return GeoEncodingUtils.decodeLongitude(GeoEncodingUtils.encodeLongitude(lonRaw));
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/site/changes/changes2html.pl
----------------------------------------------------------------------
diff --git a/lucene/site/changes/changes2html.pl b/lucene/site/changes/changes2html.pl
index 5b866fc..dcdcaa4 100755
--- a/lucene/site/changes/changes2html.pl
+++ b/lucene/site/changes/changes2html.pl
@@ -44,7 +44,11 @@ my @lines = <STDIN>; # Get all input at once
#
# Cmdline args: <LUCENE|SOLR> <project-DOAP-rdf-file> <lucene-javadoc-url>(only from Solr)
#
-my $product = $ARGV[0];
+my $product = uc($ARGV[0]);
+if ($product !~ /^(LUCENE|SOLR)$/) {
+ print STDERR "Unknown product name '$ARGV[0]'\n";
+ exit(1);
+}
my %release_dates = &setup_release_dates($ARGV[1]);
my $lucene_javadoc_url = ($product eq 'SOLR' ? $ARGV[2] : ''); # Only Solr supplies this on the cmdline
my $in_major_component_versions_section = 0;
@@ -825,7 +829,6 @@ sub get_release_date {
sub setup_release_dates {
my %release_dates = ();
my $file = shift;
-print STDERR "file: $file\n";
open(FILE, "<$file") || die "could not open $file: $!";
my $version_list = <FILE>;
my $created_list = <FILE>;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
deleted file mode 100644
index 9bc2408..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointField.java
+++ /dev/null
@@ -1,266 +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.geopoint.document;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.DocValuesType;
-import org.apache.lucene.index.IndexOptions;
-import org.apache.lucene.geo.GeoUtils;
-import org.apache.lucene.util.BitUtil;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefBuilder;
-
-import static org.apache.lucene.spatial.util.MortonEncoder.encode;
-import static org.apache.lucene.geo.GeoUtils.MIN_LAT_INCL;
-import static org.apache.lucene.geo.GeoUtils.MIN_LON_INCL;
-
-/**
- * <p>
- * Field that indexes <code>latitude</code> <code>longitude</code> decimal-degree values
- * for efficient encoding, sorting, and querying. This Geo capability is intended
- * to provide a basic and efficient out of the box field type for indexing and
- * querying 2 dimensional points in WGS-84 decimal degrees. An example usage is as follows:
- *
- * <pre class="prettyprint">
- * document.add(new GeoPointField(name, -96.33, 32.66, Field.Store.NO));
- * </pre>
- *
- * <p>To perform simple geospatial queries against a <code>GeoPointField</code>,
- * see {@link org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery}, {@link org.apache.lucene.spatial.geopoint.search.GeoPointInPolygonQuery},
- * or {@link org.apache.lucene.spatial.geopoint.search.GeoPointDistanceQuery}
- *
- * @lucene.experimental
- */
-public final class GeoPointField extends Field {
- /** encoding step value for GeoPoint prefix terms */
- public static final int PRECISION_STEP = 9;
-
- /** number of bits used for quantizing latitude and longitude values */
- public static final short BITS = 31;
- /** scaling factors to convert lat/lon into unsigned space */
- private static final double LAT_SCALE = (0x1L<<BITS)/180.0D;
- private static final double LON_SCALE = (0x1L<<BITS)/360.0D;
-
- /**
- * The maximum term length (used for <code>byte[]</code> buffer size)
- * for encoding <code>geoEncoded</code> values.
- * @see #geoCodedToPrefixCodedBytes(long, int, BytesRefBuilder)
- */
- private static final int BUF_SIZE_LONG = 28/8 + 1;
-
- /**
- * Type for a GeoPointField that is not stored:
- * normalization factors, frequencies, and positions are omitted.
- */
- public static final FieldType TYPE_NOT_STORED = new FieldType();
- static {
- TYPE_NOT_STORED.setTokenized(false);
- TYPE_NOT_STORED.setOmitNorms(true);
- TYPE_NOT_STORED.setIndexOptions(IndexOptions.DOCS);
- TYPE_NOT_STORED.setDocValuesType(DocValuesType.SORTED_NUMERIC);
- TYPE_NOT_STORED.freeze();
- }
-
- /**
- * Type for a stored GeoPointField:
- * normalization factors, frequencies, and positions are omitted.
- */
- public static final FieldType TYPE_STORED = new FieldType();
- static {
- TYPE_STORED.setTokenized(false);
- TYPE_STORED.setOmitNorms(true);
- TYPE_STORED.setIndexOptions(IndexOptions.DOCS);
- TYPE_STORED.setDocValuesType(DocValuesType.SORTED_NUMERIC);
- TYPE_STORED.setStored(true);
- TYPE_STORED.freeze();
- }
-
- /** Creates a stored or un-stored GeoPointField
- * @param name field name
- * @param latitude latitude double value [-90.0 : 90.0]
- * @param longitude longitude double value [-180.0 : 180.0]
- * @param stored Store.YES if the content should also be stored
- * @throws IllegalArgumentException if the field name is null.
- */
- public GeoPointField(String name, double latitude, double longitude, Store stored) {
- this(name, latitude, longitude, getFieldType(stored));
- }
-
- /** Expert: allows you to customize the {@link
- * FieldType}.
- * @param name field name
- * @param latitude latitude double value [-90.0 : 90.0]
- * @param longitude longitude double value [-180.0 : 180.0]
- * @param type customized field type
- * @throws IllegalArgumentException if the field name or type is null
- */
- public GeoPointField(String name, double latitude, double longitude, FieldType type) {
- super(name, type);
-
- GeoUtils.checkLatitude(latitude);
- GeoUtils.checkLongitude(longitude);
-
- // field must be indexed
- // todo does it make sense here to provide the ability to store a GeoPointField but not index?
- if (type.indexOptions() == IndexOptions.NONE && type.stored() == false) {
- throw new IllegalArgumentException("type.indexOptions() is set to NONE but type.stored() is false");
- } else if (type.indexOptions() == IndexOptions.DOCS) {
- if (type.docValuesType() != DocValuesType.SORTED_NUMERIC) {
- throw new IllegalArgumentException("type.docValuesType() must be SORTED_NUMERIC but got " + type.docValuesType());
- }
- } else {
- throw new IllegalArgumentException("type.indexOptions() must be one of NONE or DOCS but got " + type.indexOptions());
- }
-
- // set field data
- fieldsData = encodeLatLon(latitude, longitude);
- }
-
- /**
- * Static helper method for returning a valid FieldType based on termEncoding and stored options
- */
- private static FieldType getFieldType(Store stored) {
- if (stored == Store.YES) {
- return TYPE_STORED;
- } else if (stored == Store.NO) {
- return TYPE_NOT_STORED;
- } else {
- throw new IllegalArgumentException("stored option must be NO or YES but got " + stored);
- }
- }
-
- @Override
- public TokenStream tokenStream(Analyzer analyzer, TokenStream reuse) {
- if (fieldType().indexOptions() == IndexOptions.NONE) {
- // not indexed
- return null;
- }
-
- if (reuse instanceof GeoPointTokenStream == false) {
- reuse = new GeoPointTokenStream();
- }
-
- final GeoPointTokenStream gpts = (GeoPointTokenStream)reuse;
- gpts.setGeoCode(((Number) fieldsData).longValue());
-
- return reuse;
- }
-
- /** access latitude value */
- public double getLat() {
- return decodeLatitude((long) fieldsData);
- }
-
- /** access longitude value */
- public double getLon() {
- return decodeLongitude((long) fieldsData);
- }
-
- @Override
- public String toString() {
- if (fieldsData == null) {
- return null;
- }
- StringBuilder sb = new StringBuilder();
- sb.append(decodeLatitude((long) fieldsData));
- sb.append(',');
- sb.append(decodeLongitude((long) fieldsData));
- return sb.toString();
- }
-
- /*************************
- * 31 bit encoding utils *
- *************************/
- public static long encodeLatLon(final double lat, final double lon) {
- long result = encode(lat, lon);
- if (result == 0xFFFFFFFFFFFFFFFFL) {
- return result & 0xC000000000000000L;
- }
- return result >>> 2;
- }
-
- /** decode longitude value from morton encoded geo point */
- public static final double decodeLongitude(final long hash) {
- return unscaleLon(BitUtil.deinterleave(hash));
- }
-
- /** decode latitude value from morton encoded geo point */
- public static final double decodeLatitude(final long hash) {
- return unscaleLat(BitUtil.deinterleave(hash >>> 1));
- }
-
- private static final double unscaleLon(final long val) {
- return (val / LON_SCALE) + MIN_LON_INCL;
- }
-
- private static final double unscaleLat(final long val) {
- return (val / LAT_SCALE) + MIN_LAT_INCL;
- }
-
- /** Convert a geocoded morton long into a prefix coded geo term */
- public static void geoCodedToPrefixCoded(long hash, int shift, BytesRefBuilder bytes) {
- geoCodedToPrefixCodedBytes(hash, shift, bytes);
- }
-
- /** Convert a prefix coded geo term back into the geocoded morton long */
- public static long prefixCodedToGeoCoded(final BytesRef val) {
- final long result = 0L
- | (val.bytes[val.offset+0] & 255L) << 24
- | (val.bytes[val.offset+1] & 255L) << 16
- | (val.bytes[val.offset+2] & 255L) << 8
- | val.bytes[val.offset+3] & 255L;
-
- return result << 32;
- }
-
- /**
- * GeoTerms are coded using 4 prefix bytes + 1 byte to record number of prefix bits
- *
- * example prefix at shift 54 (yields 10 significant prefix bits):
- * pppppppp pp000000 00000000 00000000 00001010
- * (byte 1) (byte 2) (byte 3) (byte 4) (sigbits)
- */
- private static void geoCodedToPrefixCodedBytes(final long hash, final int shift, final BytesRefBuilder bytes) {
- // ensure shift is 32..63
- if (shift < 32 || shift > 63) {
- throw new IllegalArgumentException("Illegal shift value, must be 32..63; got shift=" + shift);
- }
- int nChars = BUF_SIZE_LONG + 1; // one extra for the byte that contains the number of significant bits
- bytes.setLength(nChars);
- bytes.grow(nChars--);
- final int sigBits = 64 - shift;
- bytes.setByteAt(BUF_SIZE_LONG, (byte)(sigBits));
- long sortableBits = hash;
- sortableBits >>>= shift;
- sortableBits <<= 32 - sigBits;
- do {
- bytes.setByteAt(--nChars, (byte)(sortableBits));
- sortableBits >>>= 8;
- } while (nChars > 0);
- }
-
- /** Get the prefix coded geo term shift value */
- public static int getPrefixCodedShift(final BytesRef val) {
- final int shift = val.bytes[val.offset + BUF_SIZE_LONG];
- if (shift > 63 || shift < 0)
- throw new NumberFormatException("Invalid shift value (" + shift + ") in prefixCoded bytes (is encoded value really a geo point?)");
- return shift;
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointTokenStream.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointTokenStream.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointTokenStream.java
deleted file mode 100644
index 87b228b..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/GeoPointTokenStream.java
+++ /dev/null
@@ -1,218 +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.geopoint.document;
-
-import java.util.Objects;
-
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
-import org.apache.lucene.util.Attribute;
-import org.apache.lucene.util.AttributeFactory;
-import org.apache.lucene.util.AttributeImpl;
-import org.apache.lucene.util.AttributeReflector;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.BytesRefBuilder;
-
-import static org.apache.lucene.spatial.geopoint.document.GeoPointField.geoCodedToPrefixCoded;
-import static org.apache.lucene.spatial.geopoint.document.GeoPointField.PRECISION_STEP;
-
-/**
- * <b>Expert:</b> This class provides a {@link TokenStream} used by {@link GeoPointField}
- * for encoding GeoPoint terms.
- *
- * This class encodes terms up to a maximum of {@link #MAX_SHIFT} using a fixed precision step defined by
- * {@link GeoPointField#PRECISION_STEP}. This yields a total of 4 terms per GeoPoint
- * each consisting of 5 bytes (4 prefix bytes + 1 precision byte).
- *
- * Here's an example usage:
- *
- * <pre class="prettyprint">
- * // using prefix terms
- * GeoPointField geoPointField = new GeoPointField(fieldName1, lat, lon, GeoPointField.TYPE_NOT_STORED);
- * document.add(geoPointField);
- *
- * // query by bounding box
- * Query q = new GeoPointInBBoxQuery(fieldName1, minLat, maxLat, minLon, maxLon);
- *
- * // query by distance
- * q = new GeoPointDistanceQuery(fieldName2, centerLat, centerLon, radiusMeters);
- * </pre>
- *
- * @lucene.experimental
- */
-final class GeoPointTokenStream extends TokenStream {
- private static final int MAX_SHIFT = PRECISION_STEP * 4;
-
- private final GeoPointTermAttribute geoPointTermAtt = addAttribute(GeoPointTermAttribute.class);
- private final PositionIncrementAttribute posIncrAtt = addAttribute(PositionIncrementAttribute.class);
-
- private boolean isInit = false;
-
- /**
- * Expert: Creates a token stream for geo point fields with the specified
- * <code>precisionStep</code> using the given
- * {@link org.apache.lucene.util.AttributeFactory}.
- * The stream is not yet initialized,
- * before using set a value using the various setGeoCode method.
- */
- public GeoPointTokenStream() {
- super(new GeoPointAttributeFactory(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY));
- assert PRECISION_STEP > 0;
- }
-
- public GeoPointTokenStream setGeoCode(final long geoCode) {
- geoPointTermAtt.init(geoCode, MAX_SHIFT-PRECISION_STEP);
- isInit = true;
- return this;
- }
-
- @Override
- public void reset() {
- if (isInit == false) {
- throw new IllegalStateException("call setGeoCode() before usage");
- }
- }
-
- @Override
- public boolean incrementToken() {
- if (isInit == false) {
- throw new IllegalStateException("call setGeoCode() before usage");
- }
-
- // this will only clear all other attributes in this TokenStream
- clearAttributes();
-
- final int shift = geoPointTermAtt.incShift();
- posIncrAtt.setPositionIncrement((shift == MAX_SHIFT) ? 1 : 0);
- return (shift < 63);
- }
-
- /**
- * Tracks shift values during encoding
- */
- public interface GeoPointTermAttribute extends Attribute {
- /** Returns current shift value, undefined before first token */
- int getShift();
-
- /** <em>Don't call this method!</em>
- * @lucene.internal */
- void init(long value, int shift);
-
- /** <em>Don't call this method!</em>
- * @lucene.internal */
- int incShift();
- }
-
- // just a wrapper to prevent adding CTA
- private static final class GeoPointAttributeFactory extends AttributeFactory {
- private final AttributeFactory delegate;
-
- GeoPointAttributeFactory(AttributeFactory delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public AttributeImpl createAttributeInstance(Class<? extends Attribute> attClass) {
- if (CharTermAttribute.class.isAssignableFrom(attClass)) {
- throw new IllegalArgumentException("GeoPointTokenStream does not support CharTermAttribute.");
- }
- return delegate.createAttributeInstance(attClass);
- }
- }
-
- public static final class GeoPointTermAttributeImpl extends AttributeImpl implements GeoPointTermAttribute,TermToBytesRefAttribute {
- private long value = 0L;
- private int shift = 0;
- private BytesRefBuilder bytes = new BytesRefBuilder();
-
- public GeoPointTermAttributeImpl() {
- this.shift = MAX_SHIFT-PRECISION_STEP;
- }
-
- @Override
- public BytesRef getBytesRef() {
- geoCodedToPrefixCoded(value, shift, bytes);
- return bytes.get();
- }
-
- @Override
- public void init(long value, int shift) {
- this.value = value;
- this.shift = shift;
- }
-
- @Override
- public int getShift() { return shift; }
-
- @Override
- public int incShift() {
- return (shift += PRECISION_STEP);
- }
-
- @Override
- public void clear() {
- // this attribute has no contents to clear!
- // we keep it untouched as it's fully controlled by outer class.
- }
-
- @Override
- public void reflectWith(AttributeReflector reflector) {
- reflector.reflect(TermToBytesRefAttribute.class, "bytes", getBytesRef());
- reflector.reflect(GeoPointTermAttribute.class, "shift", shift);
- }
-
- @Override
- public void copyTo(AttributeImpl target) {
- final GeoPointTermAttribute a = (GeoPointTermAttribute) target;
- a.init(value, shift);
- }
-
- @Override
- public GeoPointTermAttributeImpl clone() {
- GeoPointTermAttributeImpl t = (GeoPointTermAttributeImpl)super.clone();
- // Do a deep clone
- t.bytes = new BytesRefBuilder();
- t.bytes.copyBytes(getBytesRef());
- return t;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(shift, value);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- GeoPointTermAttributeImpl other = (GeoPointTermAttributeImpl) obj;
- if (shift != other.shift) return false;
- if (value != other.value) return false;
- return true;
- }
- }
-
- /** override toString because it can throw cryptic "illegal shift value": */
- @Override
- public String toString() {
- return getClass().getSimpleName() + "(precisionStep=" + PRECISION_STEP + " shift=" + geoPointTermAtt.getShift() + ")";
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/package-info.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/package-info.java
deleted file mode 100644
index 2d23448..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/document/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.
- */
-
-/**
- * Geospatial Field Implementations for Core Lucene
- */
-package org.apache.lucene.spatial.geopoint.document;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
deleted file mode 100644
index 743c116..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQuery.java
+++ /dev/null
@@ -1,171 +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.geopoint.search;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.geo.Rectangle;
-import org.apache.lucene.geo.GeoUtils;
-
-/** Implements a simple point distance query on a GeoPoint field. This is based on
- * {@link GeoPointInBBoxQuery} and is implemented using a two phase approach. First,
- * like {@code GeoPointInBBoxQueryImpl} candidate terms are queried using the numeric ranges based on
- * the morton codes of the min and max lat/lon pairs that intersect the boundary of the point-radius
- * circle. Terms
- * passing this initial filter are then passed to a secondary {@code postFilter} method that verifies whether the
- * decoded lat/lon point fall within the specified query distance (see {@link org.apache.lucene.util.SloppyMath#haversinMeters(double, double, double, double)}.
- * Distance comparisons are subject to the accuracy of the haversine formula
- * (from R.W. Sinnott, "Virtues of the Haversine", Sky and Telescope, vol. 68, no. 2, 1984, p. 159)
- *
- * <p>Note: This query currently uses haversine which is a sloppy distance calculation (see above reference). For large
- * queries one can expect upwards of 400m error. Vincenty shrinks this to ~40m error but pays a penalty for computing
- * using the spheroid
- *
- * @lucene.experimental */
-public class GeoPointDistanceQuery extends GeoPointInBBoxQuery {
- /** latitude value (in degrees) for query location */
- protected final double centerLat;
- /** longitude value (in degrees) for query location */
- protected final double centerLon;
- /** distance (in meters) from lat, lon center location */
- protected final double radiusMeters;
- /** partial haversin computation */
- protected final double sortKey;
-
- // we must check these before passing to superclass or circleToBBox, or users can get a strange exception!
- private static double checkRadius(double radiusMeters) {
- if (Double.isFinite(radiusMeters) == false || radiusMeters < 0) {
- throw new IllegalArgumentException("invalid radiusMeters " + radiusMeters);
- }
- return radiusMeters;
- }
-
- /**
- * Constructs a Query for all {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} types within a
- * distance (in meters) from a given point
- **/
- public GeoPointDistanceQuery(final String field, final double centerLat, final double centerLon, final double radiusMeters) {
- this(field, Rectangle.fromPointDistance(centerLat, centerLon, checkRadius(radiusMeters)), centerLat, centerLon, radiusMeters);
- }
-
- private GeoPointDistanceQuery(final String field, final Rectangle bbox,
- final double centerLat, final double centerLon, final double radiusMeters) {
- super(field, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
-
- this.centerLat = centerLat;
- this.centerLon = centerLon;
- this.radiusMeters = radiusMeters;
- this.sortKey = GeoUtils.distanceQuerySortKey(radiusMeters);
- }
-
- @Override
- public Query rewrite(IndexReader reader) {
- // query crosses dateline; split into left and right queries
- if (maxLon < minLon) {
- BooleanQuery.Builder bqb = new BooleanQuery.Builder();
-
- // unwrap the longitude iff outside the specified min/max lon range
- double unwrappedLon = centerLon;
- if (unwrappedLon > maxLon) {
- // unwrap left
- unwrappedLon += -360.0D;
- }
- GeoPointDistanceQueryImpl left = new GeoPointDistanceQueryImpl(field, this, unwrappedLon,
- new Rectangle(minLat, maxLat, GeoUtils.MIN_LON_INCL, maxLon));
- bqb.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
-
- if (unwrappedLon < maxLon) {
- // unwrap right
- unwrappedLon += 360.0D;
- }
- GeoPointDistanceQueryImpl right = new GeoPointDistanceQueryImpl(field, this, unwrappedLon,
- new Rectangle(minLat, maxLat, minLon, GeoUtils.MAX_LON_INCL));
- bqb.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
-
- return bqb.build();
- }
- return new GeoPointDistanceQueryImpl(field, this, centerLon,
- new Rectangle(this.minLat, this.maxLat, this.minLon, this.maxLon));
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof GeoPointDistanceQuery)) return false;
- if (!super.equals(o)) return false;
-
- GeoPointDistanceQuery that = (GeoPointDistanceQuery) o;
-
- if (Double.compare(that.centerLat, centerLat) != 0) return false;
- if (Double.compare(that.centerLon, centerLon) != 0) return false;
- if (Double.compare(that.radiusMeters, radiusMeters) != 0) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp;
- temp = Double.doubleToLongBits(centerLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(centerLat);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(radiusMeters);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString(String field) {
- final StringBuilder sb = new StringBuilder();
- sb.append(getClass().getSimpleName());
- sb.append(':');
- if (!this.field.equals(field)) {
- sb.append(" field=");
- sb.append(this.field);
- sb.append(':');
- }
- return sb.append( " Center: [")
- .append(centerLat)
- .append(',')
- .append(centerLon)
- .append(']')
- .append(" Distance: ")
- .append(radiusMeters)
- .append(" meters")
- .append("]")
- .toString();
- }
-
- /** getter method for center longitude value */
- public double getCenterLon() {
- return this.centerLon;
- }
-
- /** getter method for center latitude value */
- public double getCenterLat() {
- return this.centerLat;
- }
-
- /** getter method for distance value (in meters) */
- public double getRadiusMeters() {
- return this.radiusMeters;
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
deleted file mode 100644
index ea85240..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointDistanceQueryImpl.java
+++ /dev/null
@@ -1,132 +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.geopoint.search;
-
-import org.apache.lucene.geo.Rectangle;
-import org.apache.lucene.index.PointValues;
-import org.apache.lucene.search.MultiTermQuery;
-import org.apache.lucene.util.SloppyMath;
-
-/** Package private implementation for the public facing GeoPointDistanceQuery delegate class.
- *
- * @lucene.experimental
- */
-final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
- private final GeoPointDistanceQuery distanceQuery;
- private final double centerLon;
-
- // optimization, used for detecting axis cross
- final double axisLat;
-
- GeoPointDistanceQueryImpl(final String field, final GeoPointDistanceQuery q,
- final double centerLonUnwrapped, final Rectangle bbox) {
- super(field, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
- distanceQuery = q;
- centerLon = centerLonUnwrapped;
- axisLat = Rectangle.axisLat(distanceQuery.centerLat, distanceQuery.radiusMeters);
- }
-
- @Override
- public void setRewriteMethod(MultiTermQuery.RewriteMethod method) {
- throw new UnsupportedOperationException("cannot change rewrite method");
- }
-
- @Override
- protected CellComparator newCellComparator() {
- return new GeoPointRadiusCellComparator(this);
- }
-
- private final class GeoPointRadiusCellComparator extends CellComparator {
- GeoPointRadiusCellComparator(GeoPointDistanceQueryImpl query) {
- super(query);
- }
-
- @Override
- protected PointValues.Relation relate(final double minLat, final double maxLat, final double minLon, final double maxLon) {
- // bounding box check
- if (cellIntersectsMBR(minLat, maxLat, minLon, maxLon) == false) {
- return PointValues.Relation.CELL_OUTSIDE_QUERY;
- }
- if ((centerLon < minLon || centerLon > maxLon) && (axisLat + Rectangle.AXISLAT_ERROR < minLat
- || axisLat- Rectangle.AXISLAT_ERROR > maxLat)) {
- if (SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, minLat, minLon) > distanceQuery.sortKey &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, minLat, maxLon) > distanceQuery.sortKey &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, maxLat, minLon) > distanceQuery.sortKey &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, maxLat, maxLon) > distanceQuery.sortKey) {
- return PointValues.Relation.CELL_OUTSIDE_QUERY;
- }
- }
-
- if (maxLon - centerLon < 90 && centerLon - minLon < 90 &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, minLat, minLon) <= distanceQuery.sortKey &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, minLat, maxLon) <= distanceQuery.sortKey &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, maxLat, minLon) <= distanceQuery.sortKey &&
- SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, maxLat, maxLon) <= distanceQuery.sortKey) {
- // we are fully enclosed, collect everything within this subtree
- return PointValues.Relation.CELL_INSIDE_QUERY;
- }
-
- return PointValues.Relation.CELL_CROSSES_QUERY;
- }
-
- /**
- * The two-phase query approach. The parent {@link GeoPointTermsEnum} class matches
- * encoded terms that fall within the minimum bounding box of the point-radius circle. Those documents that pass
- * the initial bounding box filter are then post filter compared to the provided distance using the
- * {@link org.apache.lucene.util.SloppyMath#haversinMeters(double, double, double, double)} method.
- */
- @Override
- protected boolean postFilter(final double lat, final double lon) {
- // check bbox
- if (lat < minLat || lat > maxLat || lon < minLon || lon > maxLon) {
- return false;
- }
-
- // first check the partial distance, if its more than that, it can't be <= radiusMeters
- double h1 = SloppyMath.haversinSortKey(distanceQuery.centerLat, centerLon, lat, lon);
- if (h1 <= distanceQuery.sortKey) {
- return true;
- }
-
- return false;
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof GeoPointDistanceQueryImpl)) return false;
- if (!super.equals(o)) return false;
-
- GeoPointDistanceQueryImpl that = (GeoPointDistanceQueryImpl) o;
-
- if (!distanceQuery.equals(that.distanceQuery)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + distanceQuery.hashCode();
- return result;
- }
-
- public double getRadiusMeters() {
- return distanceQuery.getRadiusMeters();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
deleted file mode 100644
index 5bc5861..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java
+++ /dev/null
@@ -1,171 +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.geopoint.search;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.FieldValueQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.geo.GeoUtils;
-
-/** Implements a simple bounding box query on a GeoPoint field. This is implemented using a
- * two phase approach. First, candidate terms are queried using a numeric
- * range based on the morton codes of the min and max lat/lon pairs. Terms
- * passing this initial filter are passed to a final check that verifies whether
- * the decoded lat/lon falls within (or on the boundary) of the query bounding box.
- *
- * NOTES:
- * 1. All latitude/longitude values must be in decimal degrees.
- * 2. Complex computational geometry (e.g., dateline wrapping) is not supported
- * 3. For more advanced GeoSpatial indexing and query operations see spatial module
- * 4. This is well suited for small rectangles, large bounding boxes may result
- * in many terms, depending whether the bounding box falls on the boundary of
- * many cells (degenerate case)
- *
- * @lucene.experimental
- */
-public class GeoPointInBBoxQuery extends Query {
- /** field name */
- protected final String field;
- /** minimum latitude value (in degrees) */
- protected final double minLat;
- /** minimum longitude value (in degrees) */
- protected final double minLon;
- /** maximum latitude value (in degrees) */
- protected final double maxLat;
- /** maximum longitude value (in degrees) */
- protected final double maxLon;
-
- /**
- * Constructs a query for all {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} types that fall within a
- * defined bounding box.
- */
- public GeoPointInBBoxQuery(final String field, final double minLat, final double maxLat, final double minLon, final double maxLon) {
- if (field == null) {
- throw new IllegalArgumentException("field must not be null");
- }
- GeoUtils.checkLatitude(minLat);
- GeoUtils.checkLatitude(maxLat);
- GeoUtils.checkLongitude(minLon);
- GeoUtils.checkLongitude(maxLon);
- this.field = field;
- this.minLat = minLat;
- this.maxLat = maxLat;
- this.minLon = minLon;
- this.maxLon = maxLon;
- }
-
- @Override
- public Query rewrite(IndexReader reader) {
- // short-circuit to match all if specifying the whole map
- if (minLat == GeoUtils.MIN_LAT_INCL && maxLat == GeoUtils.MAX_LAT_INCL &&
- minLon == GeoUtils.MIN_LON_INCL && maxLon == GeoUtils.MAX_LON_INCL) {
- // FieldValueQuery is valid since DocValues are *required* for GeoPointField
- return new FieldValueQuery(field);
- }
-
- if (maxLon < minLon) {
- BooleanQuery.Builder bqb = new BooleanQuery.Builder();
-
- GeoPointInBBoxQueryImpl left = new GeoPointInBBoxQueryImpl(field, minLat, maxLat, -180.0D, maxLon);
- bqb.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
- GeoPointInBBoxQueryImpl right = new GeoPointInBBoxQueryImpl(field, minLat, maxLat, minLon, 180.0D);
- bqb.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
- return bqb.build();
- }
- return new GeoPointInBBoxQueryImpl(field, minLat, maxLat, minLon, maxLon);
- }
-
- @Override
- public String toString(String field) {
- final StringBuilder sb = new StringBuilder();
- sb.append(getClass().getSimpleName());
- sb.append(':');
- if (!this.field.equals(field)) {
- sb.append(" field=");
- sb.append(this.field);
- sb.append(':');
- }
- return sb.append(" Lower Left: [")
- .append(minLat)
- .append(',')
- .append(minLon)
- .append(']')
- .append(" Upper Right: [")
- .append(maxLat)
- .append(',')
- .append(maxLon)
- .append("]")
- .toString();
- }
-
- @Override
- public boolean equals(Object other) {
- return sameClassAs(other) &&
- equalsTo(getClass().cast(other));
- }
-
- private boolean equalsTo(GeoPointInBBoxQuery other) {
- return Double.compare(other.minLat, minLat) == 0 &&
- Double.compare(other.maxLat, maxLat) == 0 &&
- Double.compare(other.minLon, minLon) == 0 &&
- Double.compare(other.maxLon, maxLon) == 0 &&
- field.equals(other.field);
- }
-
- @Override
- public int hashCode() {
- int result = classHash();
- long temp;
- result = 31 * result + field.hashCode();
- temp = Double.doubleToLongBits(minLat);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(maxLat);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(minLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(maxLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- /** getter method for retrieving the field name */
- public final String getField() {
- return this.field;
- }
-
- /** getter method for retrieving the minimum latitude (in degrees) */
- public final double getMinLat() {
- return this.minLat;
- }
-
- /** getter method for retrieving the maximum latitude (in degrees) */
- public final double getMaxLat() {
- return this.maxLat;
- }
-
- /** getter method for retrieving the minimum longitude (in degrees) */
- public final double getMinLon() {
- return this.minLon;
- }
-
- /** getter method for retrieving the maximum longitude (in degrees) */
- public final double getMaxLon() {
- return this.maxLon;
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQueryImpl.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQueryImpl.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQueryImpl.java
deleted file mode 100644
index ee1f8da..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQueryImpl.java
+++ /dev/null
@@ -1,148 +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.geopoint.search;
-
-import org.apache.lucene.index.PointValues.Relation;
-import org.apache.lucene.search.MultiTermQuery;
-import org.apache.lucene.util.SloppyMath;
-import org.apache.lucene.spatial.geopoint.document.GeoPointField;
-import org.apache.lucene.spatial.util.GeoRelationUtils;
-
-/** Package private implementation for the public facing GeoPointInBBoxQuery delegate class.
- *
- * @lucene.experimental
- */
-class GeoPointInBBoxQueryImpl extends GeoPointMultiTermQuery {
- /**
- * Constructs a new GeoBBoxQuery that will match encoded GeoPoint terms that fall within or on the boundary
- * of the bounding box defined by the input parameters
- * @param field the field name
- * @param minLon lower longitude (x) value of the bounding box
- * @param minLat lower latitude (y) value of the bounding box
- * @param maxLon upper longitude (x) value of the bounding box
- * @param maxLat upper latitude (y) value of the bounding box
- */
- GeoPointInBBoxQueryImpl(final String field, final double minLat, final double maxLat, final double minLon, final double maxLon) {
- super(field, minLat, maxLat, minLon, maxLon);
- }
-
- @Override
- public void setRewriteMethod(MultiTermQuery.RewriteMethod method) {
- throw new UnsupportedOperationException("cannot change rewrite method");
- }
-
- @Override
- protected short computeMaxShift() {
- final short shiftFactor;
-
- // compute diagonal radius
- double midLat = (minLat + maxLat) * 0.5;
- double midLon = (minLon + maxLon) * 0.5;
-
- if (SloppyMath.haversinMeters(minLat, minLon, midLat, midLon) > 1000000) {
- shiftFactor = 5;
- } else {
- shiftFactor = 4;
- }
-
- return (short)(GeoPointField.PRECISION_STEP * shiftFactor);
- }
-
- @Override
- protected CellComparator newCellComparator() {
- return new GeoPointInBBoxCellComparator(this);
- }
-
- private final class GeoPointInBBoxCellComparator extends CellComparator {
- GeoPointInBBoxCellComparator(GeoPointMultiTermQuery query) {
- super(query);
- }
-
- @Override
- protected Relation relate(final double minLat, final double maxLat, final double minLon, final double maxLon) {
- if (GeoRelationUtils.rectCrosses(minLat, maxLat, minLon, maxLon, GeoPointInBBoxQueryImpl.this.minLat,
- GeoPointInBBoxQueryImpl.this.maxLat, GeoPointInBBoxQueryImpl.this.minLon, GeoPointInBBoxQueryImpl.this.maxLon)) {
- return Relation.CELL_CROSSES_QUERY;
- } else if (GeoRelationUtils.rectWithin(minLat, maxLat, minLon, maxLon, GeoPointInBBoxQueryImpl.this.minLat,
- GeoPointInBBoxQueryImpl.this.maxLat,
- GeoPointInBBoxQueryImpl.this.minLon, GeoPointInBBoxQueryImpl.this.maxLon)) {
- return Relation.CELL_INSIDE_QUERY;
- }
- return Relation.CELL_OUTSIDE_QUERY;
- }
-
- @Override
- protected boolean postFilter(final double lat, final double lon) {
- return GeoRelationUtils.pointInRectPrecise(lat, lon, minLat, maxLat, minLon, maxLon);
- }
- }
-
- @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;
-
- GeoPointInBBoxQueryImpl that = (GeoPointInBBoxQueryImpl) o;
-
- if (Double.compare(that.minLat, minLat) != 0) return false;
- if (Double.compare(that.maxLat, maxLat) != 0) return false;
- if (Double.compare(that.minLon, minLon) != 0) return false;
- if (Double.compare(that.maxLon, maxLon) != 0) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- long temp;
- temp = Double.doubleToLongBits(minLat);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(maxLat);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(minLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(maxLon);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString(String field) {
- final StringBuilder sb = new StringBuilder();
- sb.append(getClass().getSimpleName());
- sb.append(':');
- if (!getField().equals(field)) {
- sb.append(" field=");
- sb.append(getField());
- sb.append(':');
- }
- return sb.append(" Lower Left: [")
- .append(minLat)
- .append(',')
- .append(minLon)
- .append(']')
- .append(" Upper Right: [")
- .append(maxLat)
- .append(',')
- .append(maxLon)
- .append("]")
- .toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
deleted file mode 100644
index ca61f02..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQuery.java
+++ /dev/null
@@ -1,103 +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.geopoint.search;
-
-import java.util.Arrays;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.geo.Rectangle;
-import org.apache.lucene.geo.Polygon;
-
-/** Implements a simple point in polygon query on a GeoPoint field. This is based on
- * {@code GeoPointInBBoxQueryImpl} and is implemented using a
- * three phase approach. First, like {@code GeoPointInBBoxQueryImpl}
- * candidate terms are queried using a numeric range based on the morton codes
- * of the min and max lat/lon pairs. Terms passing this initial filter are passed
- * to a secondary filter that verifies whether the decoded lat/lon point falls within
- * (or on the boundary) of the bounding box query. Finally, the remaining candidate
- * term is passed to the final point in polygon check.
- *
- * @see Polygon
- * @lucene.experimental
- */
-public final class GeoPointInPolygonQuery extends GeoPointInBBoxQuery {
- /** array of polygons being queried */
- final Polygon[] polygons;
-
- /**
- * Constructs a new GeoPolygonQuery that will match encoded {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} terms
- * that fall within or on the boundary of the polygons defined by the input parameters.
- */
- public GeoPointInPolygonQuery(String field, Polygon... polygons) {
- this(field, Rectangle.fromPolygon(polygons), polygons);
- }
-
- // internal constructor
- private GeoPointInPolygonQuery(String field, Rectangle boundingBox, Polygon... polygons) {
- super(field, boundingBox.minLat, boundingBox.maxLat, boundingBox.minLon, boundingBox.maxLon);
- this.polygons = polygons.clone();
- }
-
- /** throw exception if trying to change rewrite method */
- @Override
- public Query rewrite(IndexReader reader) {
- return new GeoPointInPolygonQueryImpl(field, this, this.minLat, this.maxLat, this.minLon, this.maxLon);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + Arrays.hashCode(polygons);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!super.equals(obj)) return false;
- if (getClass() != obj.getClass()) return false;
- GeoPointInPolygonQuery other = (GeoPointInPolygonQuery) obj;
- if (!Arrays.equals(polygons, other.polygons)) return false;
- return true;
- }
-
- /** print out this polygon query */
- @Override
- public String toString(String field) {
- final StringBuilder sb = new StringBuilder();
- sb.append(getClass().getSimpleName());
- sb.append(':');
- if (!getField().equals(field)) {
- sb.append(" field=");
- sb.append(getField());
- sb.append(':');
- }
- sb.append(" Polygon: ");
- sb.append(Arrays.toString(polygons));
-
- return sb.toString();
- }
-
- /**
- * API utility method for returning copy of the polygon array
- */
- public Polygon[] getPolygons() {
- return polygons.clone();
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQueryImpl.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQueryImpl.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQueryImpl.java
deleted file mode 100644
index 425b40e..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInPolygonQueryImpl.java
+++ /dev/null
@@ -1,94 +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.geopoint.search;
-
-import java.util.Objects;
-
-import org.apache.lucene.search.MultiTermQuery;
-import org.apache.lucene.geo.Polygon2D;
-import org.apache.lucene.index.PointValues.Relation;
-
-/** Package private implementation for the public facing GeoPointInPolygonQuery delegate class.
- *
- * @lucene.experimental
- */
-final class GeoPointInPolygonQueryImpl extends GeoPointInBBoxQueryImpl {
- private final GeoPointInPolygonQuery polygonQuery;
- private final Polygon2D polygons;
-
- GeoPointInPolygonQueryImpl(final String field, final GeoPointInPolygonQuery q,
- final double minLat, final double maxLat, final double minLon, final double maxLon) {
- super(field, minLat, maxLat, minLon, maxLon);
- this.polygonQuery = Objects.requireNonNull(q);
- this.polygons = Polygon2D.create(q.polygons);
- }
-
- @Override
- public void setRewriteMethod(MultiTermQuery.RewriteMethod method) {
- throw new UnsupportedOperationException("cannot change rewrite method");
- }
-
- @Override
- protected CellComparator newCellComparator() {
- return new GeoPolygonCellComparator(this);
- }
-
- /**
- * Custom {@code org.apache.lucene.spatial.geopoint.search.GeoPointMultiTermQuery.CellComparator} that computes morton hash
- * ranges based on the defined edges of the provided polygon.
- */
- private final class GeoPolygonCellComparator extends CellComparator {
- GeoPolygonCellComparator(GeoPointMultiTermQuery query) {
- super(query);
- }
-
- @Override
- protected Relation relate(final double minLat, final double maxLat, final double minLon, final double maxLon) {
- return polygons.relate(minLat, maxLat, minLon, maxLon);
- }
-
- /**
- * The two-phase query approach. The parent
- * {@link org.apache.lucene.spatial.geopoint.search.GeoPointTermsEnum#accept} method is called to match
- * encoded terms that fall within the bounding box of the polygon. Those documents that pass the initial
- * bounding box filter are then compared to the provided polygon using the
- * {@link Polygon2D#contains(double, double)} method.
- */
- @Override
- protected boolean postFilter(final double lat, final double lon) {
- return polygons.contains(lat, lon);
- }
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + polygonQuery.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!super.equals(obj)) return false;
- if (getClass() != obj.getClass()) return false;
- GeoPointInPolygonQueryImpl other = (GeoPointInPolygonQueryImpl) obj;
- if (!polygonQuery.equals(other.polygonQuery)) return false;
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/4fc5a9f0/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
----------------------------------------------------------------------
diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
deleted file mode 100644
index 5117206..0000000
--- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointMultiTermQuery.java
+++ /dev/null
@@ -1,148 +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.geopoint.search;
-
-import java.io.IOException;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.PointValues.Relation;
-import org.apache.lucene.index.Terms;
-import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.MultiTermQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.util.AttributeSource;
-import org.apache.lucene.spatial.geopoint.document.GeoPointField;
-import org.apache.lucene.spatial.util.GeoRelationUtils;
-import org.apache.lucene.util.BitUtil;
-import org.apache.lucene.util.SloppyMath;
-
-/**
- * TermQuery for GeoPointField for overriding {@link org.apache.lucene.search.MultiTermQuery} methods specific to
- * Geospatial operations
- *
- * @lucene.experimental
- */
-abstract class GeoPointMultiTermQuery extends MultiTermQuery {
- // simple bounding box optimization - no objects used to avoid dependencies
- protected final double minLon;
- protected final long minEncoded;
- protected final int minX;
- protected final double minLat;
- protected final int minY;
- protected final double maxLon;
- protected final int maxX;
- protected final double maxLat;
- protected final int maxY;
-
- protected final short maxShift;
- protected final CellComparator cellComparator;
-
- /**
- * Constructs a query matching terms that cannot be represented with a single
- * Term.
- */
- public GeoPointMultiTermQuery(String field, final double minLat, final double maxLat, final double minLon, final double maxLon) {
- super(field);
-
- this.minEncoded = GeoPointField.encodeLatLon(minLat, minLon);
- final long maxEncoded = GeoPointField.encodeLatLon(maxLat, maxLon);
-
- this.minX = (int)BitUtil.deinterleave(minEncoded);
- this.maxX = (int)BitUtil.deinterleave(maxEncoded);
- this.minY = (int)BitUtil.deinterleave(minEncoded >>> 1);
- this.maxY = (int)BitUtil.deinterleave(maxEncoded >>> 1);
-
- this.minLat = minLat;
- this.maxLat = maxLat;
- this.minLon = minLon;
- this.maxLon = maxLon;
-
- this.maxShift = computeMaxShift();
- this.cellComparator = newCellComparator();
-
- this.rewriteMethod = GEO_CONSTANT_SCORE_REWRITE;
- }
-
- public static final RewriteMethod GEO_CONSTANT_SCORE_REWRITE = new RewriteMethod() {
- @Override
- public Query rewrite(IndexReader reader, MultiTermQuery query) {
- return new GeoPointTermQueryConstantScoreWrapper<>((GeoPointMultiTermQuery)query);
- }
- };
-
- @Override @SuppressWarnings("unchecked")
- protected TermsEnum getTermsEnum(final Terms terms, AttributeSource atts) throws IOException {
- return new GeoPointTermsEnum(terms.iterator(), this);
- }
-
- /**
- * Computes the maximum shift based on the diagonal distance of the bounding box
- */
- protected short computeMaxShift() {
- // in this case a factor of 4 brings the detail level to ~0.001/0.002 degrees lat/lon respectively (or ~111m/222m)
- final short shiftFactor;
-
- // compute diagonal distance
- double midLon = (minLon + maxLon) * 0.5;
- double midLat = (minLat + maxLat) * 0.5;
-
- if (SloppyMath.haversinMeters(minLat, minLon, midLat, midLon) > 1000000) {
- shiftFactor = 5;
- } else {
- shiftFactor = 4;
- }
-
- return (short)(GeoPointField.PRECISION_STEP * shiftFactor);
- }
-
- /**
- * Abstract method to construct the class that handles all geo point relations
- * (e.g., GeoPointInPolygon)
- */
- abstract protected CellComparator newCellComparator();
-
- /**
- * Base class for all geo point relation comparators
- */
- static abstract class CellComparator {
- protected final GeoPointMultiTermQuery geoPointQuery;
-
- CellComparator(GeoPointMultiTermQuery query) {
- this.geoPointQuery = query;
- }
-
- /**
- * Primary driver for cells intersecting shape boundaries
- */
- protected boolean cellIntersectsMBR(final double minLat, final double maxLat, final double minLon, final double maxLon) {
- return GeoRelationUtils.rectIntersects(minLat, maxLat, minLon, maxLon, geoPointQuery.minLat, geoPointQuery.maxLat,
- geoPointQuery.minLon, geoPointQuery.maxLon);
- }
-
- /** uses encoded values to check whether quad cell intersects the shape bounding box */
- protected boolean cellIntersectsMBR(final long min, final long max) {
- return !(Integer.compareUnsigned((int)BitUtil.deinterleave(max), geoPointQuery.minX) < 0
- || Integer.compareUnsigned((int)BitUtil.deinterleave(min), geoPointQuery.maxX) > 0
- || Integer.compareUnsigned((int)BitUtil.deinterleave(max >>> 1), geoPointQuery.minY) < 0
- || Integer.compareUnsigned((int)BitUtil.deinterleave(min >>> 1), geoPointQuery.maxY) > 0);
- }
-
- abstract protected Relation relate(final double minLat, final double maxLat, final double minLon, final double maxLon);
-
- abstract protected boolean postFilter(final double lat, final double lon);
- }
-}