LUCENE-7328: Remove LegacyNumericEncoding from GeoPointField

This commit is contained in:
Nicholas Knize 2016-06-10 09:50:18 -05:00
parent 816fae9622
commit e4db256d3f
15 changed files with 239 additions and 754 deletions

View File

@ -4,7 +4,14 @@ For more information on past and future Lucene versions, please see:
http://s.apache.org/luceneversions
======================= Lucene 7.0.0 =======================
(No Changes)
Bug Fixes
Improvements
Other
* LUCENE-7328: Remove LegacyNumericEncoding from GeoPointField. (Nick Knize)
======================= Lucene 6.2.0 =======================

View File

@ -46,9 +46,6 @@ import static org.apache.lucene.geo.GeoUtils.MIN_LON_INCL;
* 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}
*
* NOTE: This indexes only high precision encoded terms which may result in visiting a high number
* of terms for large queries. See LUCENE-6481 for a future improvement.
*
* @lucene.experimental
*/
public final class GeoPointField extends Field {
@ -68,81 +65,31 @@ public final class GeoPointField extends Field {
*/
private static final int BUF_SIZE_LONG = 28/8 + 1;
/**
* <b>Expert:</b> Optional flag to select term encoding for GeoPointField types
*/
public enum TermEncoding {
/**
* encodes prefix terms only resulting in a small index and faster queries - use with
* {@code GeoPointTokenStream}
*/
PREFIX,
/**
* @deprecated encodes prefix and full resolution terms - use with
* {@link org.apache.lucene.analysis.LegacyNumericTokenStream}
*/
@Deprecated
NUMERIC
}
/**
* @deprecated Type for a GeoPointField that is not stored:
* normalization factors, frequencies, and positions are omitted.
*/
@Deprecated
public static final FieldType NUMERIC_TYPE_NOT_STORED = new FieldType();
static {
NUMERIC_TYPE_NOT_STORED.setTokenized(false);
NUMERIC_TYPE_NOT_STORED.setOmitNorms(true);
NUMERIC_TYPE_NOT_STORED.setIndexOptions(IndexOptions.DOCS);
NUMERIC_TYPE_NOT_STORED.setDocValuesType(DocValuesType.SORTED_NUMERIC);
NUMERIC_TYPE_NOT_STORED.setNumericType(FieldType.LegacyNumericType.LONG);
NUMERIC_TYPE_NOT_STORED.setNumericPrecisionStep(PRECISION_STEP);
NUMERIC_TYPE_NOT_STORED.freeze();
}
/**
* @deprecated Type for a stored GeoPointField:
* normalization factors, frequencies, and positions are omitted.
*/
@Deprecated
public static final FieldType NUMERIC_TYPE_STORED = new FieldType();
static {
NUMERIC_TYPE_STORED.setTokenized(false);
NUMERIC_TYPE_STORED.setOmitNorms(true);
NUMERIC_TYPE_STORED.setIndexOptions(IndexOptions.DOCS);
NUMERIC_TYPE_STORED.setDocValuesType(DocValuesType.SORTED_NUMERIC);
NUMERIC_TYPE_STORED.setNumericType(FieldType.LegacyNumericType.LONG);
NUMERIC_TYPE_STORED.setNumericPrecisionStep(PRECISION_STEP);
NUMERIC_TYPE_STORED.setStored(true);
NUMERIC_TYPE_STORED.freeze();
}
/**
* Type for a GeoPointField that is not stored:
* normalization factors, frequencies, and positions are omitted.
*/
public static final FieldType PREFIX_TYPE_NOT_STORED = new FieldType();
public static final FieldType TYPE_NOT_STORED = new FieldType();
static {
PREFIX_TYPE_NOT_STORED.setTokenized(false);
PREFIX_TYPE_NOT_STORED.setOmitNorms(true);
PREFIX_TYPE_NOT_STORED.setIndexOptions(IndexOptions.DOCS);
PREFIX_TYPE_NOT_STORED.setDocValuesType(DocValuesType.SORTED_NUMERIC);
PREFIX_TYPE_NOT_STORED.freeze();
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 PREFIX_TYPE_STORED = new FieldType();
public static final FieldType TYPE_STORED = new FieldType();
static {
PREFIX_TYPE_STORED.setTokenized(false);
PREFIX_TYPE_STORED.setOmitNorms(true);
PREFIX_TYPE_STORED.setIndexOptions(IndexOptions.DOCS);
PREFIX_TYPE_STORED.setDocValuesType(DocValuesType.SORTED_NUMERIC);
PREFIX_TYPE_STORED.setStored(true);
PREFIX_TYPE_STORED.freeze();
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
@ -156,28 +103,13 @@ public final class GeoPointField extends Field {
this(name, latitude, longitude, getFieldType(stored));
}
/** Creates a stored or un-stored GeoPointField using the specified {@link TermEncoding} method
* @param name field name
* @param latitude latitude double value [-90.0 : 90.0]
* @param longitude longitude double value [-180.0 : 180.0]
* @param termEncoding encoding type to use ({@link TermEncoding#NUMERIC} Terms, or {@link TermEncoding#PREFIX} only Terms)
* @param stored Store.YES if the content should also be stored
* @throws IllegalArgumentException if the field name is null.
*/
@Deprecated
public GeoPointField(String name, double latitude, double longitude, TermEncoding termEncoding, Store stored) {
this(name, latitude, longitude, getFieldType(termEncoding, 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: must have {@link FieldType#numericType()}
* of {@link org.apache.lucene.document.FieldType.LegacyNumericType#LONG}.
* @throws IllegalArgumentException if the field name or type is null, or
* if the field type does not have a LONG numericType()
* @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);
@ -193,12 +125,6 @@ public final class GeoPointField extends Field {
if (type.docValuesType() != DocValuesType.SORTED_NUMERIC) {
throw new IllegalArgumentException("type.docValuesType() must be SORTED_NUMERIC but got " + type.docValuesType());
}
if (type.numericType() != null) {
// make sure numericType is a LONG
if (type.numericType() != FieldType.LegacyNumericType.LONG) {
throw new IllegalArgumentException("type.numericType() must be LONG but got " + type.numericType());
}
}
} else {
throw new IllegalArgumentException("type.indexOptions() must be one of NONE or DOCS but got " + type.indexOptions());
}
@ -207,20 +133,14 @@ public final class GeoPointField extends Field {
fieldsData = encodeLatLon(latitude, longitude);
}
private static FieldType getFieldType(Store stored) {
return getFieldType(TermEncoding.PREFIX, stored);
}
/**
* @deprecated
* Static helper method for returning a valid FieldType based on termEncoding and stored options
*/
@Deprecated
private static FieldType getFieldType(TermEncoding termEncoding, Store stored) {
private static FieldType getFieldType(Store stored) {
if (stored == Store.YES) {
return termEncoding == TermEncoding.PREFIX ? PREFIX_TYPE_STORED : NUMERIC_TYPE_STORED;
return TYPE_STORED;
} else if (stored == Store.NO) {
return termEncoding == TermEncoding.PREFIX ? PREFIX_TYPE_NOT_STORED : NUMERIC_TYPE_NOT_STORED;
return TYPE_NOT_STORED;
} else {
throw new IllegalArgumentException("stored option must be NO or YES but got " + stored);
}
@ -233,12 +153,6 @@ public final class GeoPointField extends Field {
return null;
}
// if numericType is set
if (type.numericType() != null) {
// return numeric encoding
return super.tokenStream(analyzer, reuse);
}
if (reuse instanceof GeoPointTokenStream == false) {
reuse = new GeoPointTokenStream();
}

View File

@ -35,28 +35,17 @@ import static org.apache.lucene.spatial.geopoint.document.GeoPointField.PRECISIO
/**
* <b>Expert:</b> This class provides a {@link TokenStream} used by {@link GeoPointField}
* for encoding {@link GeoPointField.TermEncoding#PREFIX} only GeoPointTerms.
* for encoding GeoPoint terms.
*
* <p><i>NOTE: This is used as the default encoding unless
* {@code GeoPointField.setNumericType(FieldType.LegacyNumericType.LONG)} is set</i></p>
*
* This class is similar to {@link org.apache.lucene.analysis.LegacyNumericTokenStream} but encodes terms up to a
* a maximum of {@link #MAX_SHIFT} using a fixed precision step defined by
* 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).
*
* <p>For best performance use the provided {@link GeoPointField#PREFIX_TYPE_NOT_STORED} or
* {@link GeoPointField#PREFIX_TYPE_STORED}</p>
*
* <p>If prefix terms are used then the default GeoPoint query constructors may be used, but if
* {@link org.apache.lucene.analysis.LegacyNumericTokenStream} is used, then be sure to pass
* {@link GeoPointField.TermEncoding#NUMERIC} to all GeoPointQuery constructors</p>
*
* Here's an example usage:
*
* <pre class="prettyprint">
* // using prefix terms
* GeoPointField geoPointField = new GeoPointField(fieldName1, lat, lon, GeoPointField.PREFIX_TYPE_NOT_STORED);
* GeoPointField geoPointField = new GeoPointField(fieldName1, lat, lon, GeoPointField.TYPE_NOT_STORED);
* document.add(geoPointField);
*
* // query by bounding box (default uses TermEncoding.PREFIX)

View File

@ -20,7 +20,6 @@ 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.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.geo.GeoUtils;
@ -70,21 +69,12 @@ public class GeoPointDistanceQuery extends GeoPointInBBoxQuery {
* distance (in meters) from a given point
**/
public GeoPointDistanceQuery(final String field, final double centerLat, final double centerLon, final double radiusMeters) {
this(field, TermEncoding.PREFIX, checkLatitude(centerLat), checkLongitude(centerLon), checkRadius(radiusMeters));
this(field, Rectangle.fromPointDistance(centerLat, centerLon, checkRadius(radiusMeters)), centerLat, centerLon, radiusMeters);
}
/**
* Constructs a Query for all {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} types within a
* distance (in meters) from a given point. Accepts optional
* {@link org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding} parameter
**/
public GeoPointDistanceQuery(final String field, final TermEncoding termEncoding, final double centerLat, final double centerLon, final double radiusMeters) {
this(field, termEncoding, Rectangle.fromPointDistance(centerLat, centerLon, checkRadius(radiusMeters)), centerLat, centerLon, radiusMeters);
}
private GeoPointDistanceQuery(final String field, final TermEncoding termEncoding, final Rectangle bbox,
private GeoPointDistanceQuery(final String field, final Rectangle bbox,
final double centerLat, final double centerLon, final double radiusMeters) {
super(field, termEncoding, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
super(field, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
this.centerLat = centerLat;
this.centerLon = centerLon;
@ -103,7 +93,7 @@ public class GeoPointDistanceQuery extends GeoPointInBBoxQuery {
// unwrap left
unwrappedLon += -360.0D;
}
GeoPointDistanceQueryImpl left = new GeoPointDistanceQueryImpl(field, termEncoding, this, unwrappedLon,
GeoPointDistanceQueryImpl left = new GeoPointDistanceQueryImpl(field, this, unwrappedLon,
new Rectangle(minLat, maxLat, GeoUtils.MIN_LON_INCL, maxLon));
bqb.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
@ -111,13 +101,13 @@ public class GeoPointDistanceQuery extends GeoPointInBBoxQuery {
// unwrap right
unwrappedLon += 360.0D;
}
GeoPointDistanceQueryImpl right = new GeoPointDistanceQueryImpl(field, termEncoding, this, unwrappedLon,
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, termEncoding, this, centerLon,
return new GeoPointDistanceQueryImpl(field, this, centerLon,
new Rectangle(this.minLat, this.maxLat, this.minLon, this.maxLon));
}

View File

@ -18,7 +18,6 @@ package org.apache.lucene.spatial.geopoint.search;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.util.SloppyMath;
/** Package private implementation for the public facing GeoPointDistanceQuery delegate class.
@ -35,9 +34,9 @@ final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
// optimization, used for detecting axis cross
final double axisLat;
GeoPointDistanceQueryImpl(final String field, final TermEncoding termEncoding, final GeoPointDistanceQuery q,
GeoPointDistanceQueryImpl(final String field, final GeoPointDistanceQuery q,
final double centerLonUnwrapped, final Rectangle bbox) {
super(field, termEncoding, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
super(field, bbox.minLat, bbox.maxLat, bbox.minLon, bbox.maxLon);
distanceQuery = q;
centerLon = centerLonUnwrapped;

View File

@ -20,13 +20,10 @@ 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.LegacyNumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.geo.GeoUtils;
/** Implements a simple bounding box query on a GeoPoint field. This is inspired by
* {@link LegacyNumericRangeQuery} and is implemented using a
/** 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
@ -53,28 +50,15 @@ public class GeoPointInBBoxQuery extends Query {
protected final double maxLat;
/** maximum longitude value (in degrees) */
protected final double maxLon;
/** term encoding enum to define how the points are encoded (PREFIX or NUMERIC) */
protected final TermEncoding termEncoding;
/**
* Constructs a query for all {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} types that fall within a
* defined bounding box
* defined bounding box.
*/
public GeoPointInBBoxQuery(final String field, final double minLat, final double maxLat, final double minLon, final double maxLon) {
this(field, TermEncoding.PREFIX, minLat, maxLat, minLon, maxLon);
}
/**
* Constructs a query for all {@link org.apache.lucene.spatial.geopoint.document.GeoPointField} types that fall within a
* defined bounding box. Accepts optional {@link org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding} parameter
*/
public GeoPointInBBoxQuery(final String field, final TermEncoding termEncoding, final double minLat, final double maxLat, final double minLon, final double maxLon) {
if (field == null) {
throw new IllegalArgumentException("field must not be null");
}
if (termEncoding == null) {
throw new IllegalArgumentException("termEncoding must not be null");
}
GeoUtils.checkLatitude(minLat);
GeoUtils.checkLatitude(maxLat);
GeoUtils.checkLongitude(minLon);
@ -84,7 +68,6 @@ public class GeoPointInBBoxQuery extends Query {
this.maxLat = maxLat;
this.minLon = minLon;
this.maxLon = maxLon;
this.termEncoding = termEncoding;
}
@Override
@ -99,13 +82,13 @@ public class GeoPointInBBoxQuery extends Query {
if (maxLon < minLon) {
BooleanQuery.Builder bqb = new BooleanQuery.Builder();
GeoPointInBBoxQueryImpl left = new GeoPointInBBoxQueryImpl(field, termEncoding, minLat, maxLat, -180.0D, maxLon);
GeoPointInBBoxQueryImpl left = new GeoPointInBBoxQueryImpl(field, minLat, maxLat, -180.0D, maxLon);
bqb.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
GeoPointInBBoxQueryImpl right = new GeoPointInBBoxQueryImpl(field, termEncoding, minLat, maxLat, minLon, 180.0D);
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, termEncoding, minLat, maxLat, minLon, maxLon);
return new GeoPointInBBoxQueryImpl(field, minLat, maxLat, minLon, maxLon);
}
@Override

View File

@ -19,7 +19,6 @@ package org.apache.lucene.spatial.geopoint.search;
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.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.spatial.util.GeoRelationUtils;
/** Package private implementation for the public facing GeoPointInBBoxQuery delegate class.
@ -36,8 +35,8 @@ class GeoPointInBBoxQueryImpl extends GeoPointMultiTermQuery {
* @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 TermEncoding termEncoding, final double minLat, final double maxLat, final double minLon, final double maxLon) {
super(field, termEncoding, minLat, maxLat, minLon, maxLon);
GeoPointInBBoxQueryImpl(final String field, final double minLat, final double maxLat, final double minLon, final double maxLon) {
super(field, minLat, maxLat, minLon, maxLon);
}
@Override

View File

@ -20,8 +20,6 @@ import java.util.Arrays;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.geo.Polygon;
@ -46,47 +44,19 @@ public final class GeoPointInPolygonQuery extends GeoPointInBBoxQuery {
* that fall within or on the boundary of the polygons defined by the input parameters.
*/
public GeoPointInPolygonQuery(String field, Polygon... polygons) {
this(field, TermEncoding.PREFIX, 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 polygon defined by the input parameters.
* @deprecated Use {@link #GeoPointInPolygonQuery(String, Polygon[])}.
*/
@Deprecated
public GeoPointInPolygonQuery(final String field, final double[] polyLats, final double[] polyLons) {
this(field, TermEncoding.PREFIX, polyLats, polyLons);
}
/**
* 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 polygon defined by the input parameters.
* @deprecated Use {@link #GeoPointInPolygonQuery(String, GeoPointField.TermEncoding, Polygon[])} instead.
*/
@Deprecated
public GeoPointInPolygonQuery(final String field, final TermEncoding termEncoding, final double[] polyLats, final double[] polyLons) {
this(field, termEncoding, new Polygon(polyLats, polyLons));
}
/**
* 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, TermEncoding termEncoding, Polygon... polygons) {
this(field, termEncoding, Rectangle.fromPolygon(polygons), polygons);
this(field, Rectangle.fromPolygon(polygons), polygons);
}
// internal constructor
private GeoPointInPolygonQuery(String field, TermEncoding termEncoding, Rectangle boundingBox, Polygon... polygons) {
super(field, termEncoding, boundingBox.minLat, boundingBox.maxLat, boundingBox.minLon, boundingBox.maxLon);
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, termEncoding, this, this.minLat, this.maxLat, this.minLon, this.maxLon);
return new GeoPointInPolygonQueryImpl(field, this, this.minLat, this.maxLat, this.minLon, this.maxLon);
}
@Override

View File

@ -19,7 +19,6 @@ package org.apache.lucene.spatial.geopoint.search;
import java.util.Objects;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.geo.Polygon2D;
import org.apache.lucene.index.PointValues.Relation;
@ -31,9 +30,9 @@ final class GeoPointInPolygonQueryImpl extends GeoPointInBBoxQueryImpl {
private final GeoPointInPolygonQuery polygonQuery;
private final Polygon2D polygons;
GeoPointInPolygonQueryImpl(final String field, final TermEncoding termEncoding, final GeoPointInPolygonQuery q,
GeoPointInPolygonQueryImpl(final String field, final GeoPointInPolygonQuery q,
final double minLat, final double maxLat, final double minLon, final double maxLon) {
super(field, termEncoding, minLat, maxLat, minLon, maxLon);
super(field, minLat, maxLat, minLon, maxLon);
this.polygonQuery = Objects.requireNonNull(q);
this.polygons = Polygon2D.create(q.polygons);
}

View File

@ -26,7 +26,6 @@ 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.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.spatial.util.GeoRelationUtils;
import org.apache.lucene.geo.GeoUtils;
import org.apache.lucene.util.SloppyMath;
@ -45,14 +44,13 @@ abstract class GeoPointMultiTermQuery extends MultiTermQuery {
protected final double maxLat;
protected final short maxShift;
protected final TermEncoding termEncoding;
protected final CellComparator cellComparator;
/**
* Constructs a query matching terms that cannot be represented with a single
* Term.
*/
public GeoPointMultiTermQuery(String field, final TermEncoding termEncoding, final double minLat, final double maxLat, final double minLon, final double maxLon) {
public GeoPointMultiTermQuery(String field, final double minLat, final double maxLat, final double minLon, final double maxLon) {
super(field);
GeoUtils.checkLatitude(minLat);
@ -66,7 +64,6 @@ abstract class GeoPointMultiTermQuery extends MultiTermQuery {
this.maxLon = maxLon;
this.maxShift = computeMaxShift();
this.termEncoding = termEncoding;
this.cellComparator = newCellComparator();
this.rewriteMethod = GEO_CONSTANT_SCORE_REWRITE;
@ -81,7 +78,7 @@ abstract class GeoPointMultiTermQuery extends MultiTermQuery {
@Override @SuppressWarnings("unchecked")
protected TermsEnum getTermsEnum(final Terms terms, AttributeSource atts) throws IOException {
return GeoPointTermsEnum.newInstance(terms.iterator(), this);
return new GeoPointTermsEnum(terms.iterator(), this);
}
/**

View File

@ -1,162 +0,0 @@
package org.apache.lucene.spatial.geopoint.search;
/*
* 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.
*/
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.LegacyNumericUtils;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.BITS;
/**
* Decomposes a given {@link GeoPointMultiTermQuery} into a set of terms that represent the query criteria using
* {@link org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding#NUMERIC} method defined by
* {@link org.apache.lucene.analysis.LegacyNumericTokenStream}. The terms are then enumerated by the
* {@link GeoPointTermQueryConstantScoreWrapper} and all docs whose GeoPoint fields match the prefix terms or
* pass the {@link GeoPointMultiTermQuery.CellComparator#postFilter} criteria are returned in the resulting DocIdSet.
*
* @lucene.experimental
*/
@Deprecated
final class GeoPointNumericTermsEnum extends GeoPointTermsEnum {
private final List<Range> rangeBounds = new LinkedList<>();
// detail level should be a factor of PRECISION_STEP limiting the depth of recursion (and number of ranges)
private final short DETAIL_LEVEL;
GeoPointNumericTermsEnum(final TermsEnum tenum, final GeoPointMultiTermQuery query) {
super(tenum, query);
DETAIL_LEVEL = (short)(((BITS<<1)-this.maxShift)/2);
computeRange(0L, (short) (((BITS) << 1) - 1));
assert rangeBounds.isEmpty() == false;
Collections.sort(rangeBounds);
}
/**
* entry point for recursively computing ranges
*/
private final void computeRange(long term, final short shift) {
final long split = term | (0x1L<<shift);
assert shift < 64;
final long upperMax;
if (shift < 63) {
upperMax = term | ((1L << (shift+1))-1);
} else {
upperMax = 0xffffffffffffffffL;
}
final long lowerMax = split-1;
relateAndRecurse(term, lowerMax, shift);
relateAndRecurse(split, upperMax, shift);
}
/**
* recurse to higher level precision cells to find ranges along the space-filling curve that fall within the
* query box
*
* @param start starting value on the space-filling curve for a cell at a given res
* @param end ending value on the space-filling curve for a cell at a given res
* @param res spatial res represented as a bit shift (MSB is lower res)
*/
private void relateAndRecurse(final long start, final long end, final short res) {
final double minLon = GeoPointField.decodeLongitude(start);
final double minLat = GeoPointField.decodeLatitude(start);
final double maxLon = GeoPointField.decodeLongitude(end);
final double maxLat = GeoPointField.decodeLatitude(end);
final short level = (short)((BITS<<1)-res>>>1);
// if cell is within and a factor of the precision step, or it crosses the edge of the shape add the range
final boolean within = res % GeoPointField.PRECISION_STEP == 0 && relationImpl.cellWithin(minLat, maxLat, minLon, maxLon);
if (within || (level == DETAIL_LEVEL && relationImpl.cellIntersectsShape(minLat, maxLat, minLon, maxLon))) {
final short nextRes = (short)(res-1);
if (nextRes % GeoPointField.PRECISION_STEP == 0) {
rangeBounds.add(new Range(start, nextRes, !within));
rangeBounds.add(new Range(start|(1L<<nextRes), nextRes, !within));
} else {
rangeBounds.add(new Range(start, res, !within));
}
} else if (level < DETAIL_LEVEL && relationImpl.cellIntersectsMBR(minLat, maxLat, minLon, maxLon)) {
computeRange(start, (short) (res - 1));
}
}
@Override
protected final BytesRef peek() {
rangeBounds.get(0).fillBytesRef(this.nextSubRangeBRB);
return nextSubRangeBRB.get();
}
@Override
protected void nextRange() {
currentRange = rangeBounds.remove(0);
super.nextRange();
}
@Override
protected final BytesRef nextSeekTerm(BytesRef term) {
while (hasNext()) {
if (currentRange == null) {
nextRange();
}
// if the new upper bound is before the term parameter, the sub-range is never a hit
if (term != null && term.compareTo(currentCell) > 0) {
nextRange();
if (!rangeBounds.isEmpty()) {
continue;
}
}
// never seek backwards, so use current term if lower bound is smaller
return (term != null && term.compareTo(currentCell) > 0) ? term : currentCell;
}
// no more sub-range enums available
assert rangeBounds.isEmpty();
return null;
}
@Override
protected final boolean hasNext() {
return rangeBounds.isEmpty() == false;
}
/**
* Internal class to represent a range along the space filling curve
*/
protected final class Range extends BaseRange {
Range(final long lower, final short shift, boolean boundary) {
super(lower, shift, boundary);
}
/**
* Encode as a BytesRef using a reusable object. This allows us to lazily create the BytesRef (which is
* quite expensive), only when we need it.
*/
@Override
protected void fillBytesRef(BytesRefBuilder result) {
assert result != null;
LegacyNumericUtils.longToPrefixCoded(start, shift, result);
}
}
}

View File

@ -1,235 +0,0 @@
package org.apache.lucene.spatial.geopoint.search;
/*
* 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.
*/
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.geoCodedToPrefixCoded;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.prefixCodedToGeoCoded;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.getPrefixCodedShift;
/**
* Decomposes a given {@link GeoPointMultiTermQuery} into a set of terms that represent the query criteria using
* {@link org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding#PREFIX} method defined by
* {@link GeoPointField}. The terms are then enumerated by the
* {@link GeoPointTermQueryConstantScoreWrapper} and all docs whose GeoPoint fields match the prefix terms or pass
* the {@link GeoPointMultiTermQuery.CellComparator#postFilter} criteria are returned in the
* resulting DocIdSet.
*
* @lucene.experimental
*/
final class GeoPointPrefixTermsEnum extends GeoPointTermsEnum {
private final long start;
private short shift;
// current range as long
private long currStart;
private long currEnd;
private final Range nextRange = new Range(-1, shift, true);
private boolean hasNext = false;
private boolean withinOnly = false;
private long lastWithin;
public GeoPointPrefixTermsEnum(final TermsEnum tenum, final GeoPointMultiTermQuery query) {
super(tenum, query);
this.start = GeoPointField.encodeLatLon(query.minLat, query.minLon);
this.currentRange = new Range(0, shift, true);
// start shift at maxShift value (from computeMaxShift)
this.shift = maxShift;
final long mask = (1L << shift) - 1;
this.currStart = start & ~mask;
this.currEnd = currStart | mask;
}
private boolean within(final double minLat, final double maxLat, final double minLon, final double maxLon) {
return relationImpl.cellWithin(minLat, maxLat, minLon, maxLon);
}
private boolean boundary(final double minLat, final double maxLat, final double minLon, final double maxLon) {
return shift == maxShift && relationImpl.cellIntersectsShape(minLat, maxLat, minLon, maxLon);
}
private boolean nextWithin() {
if (withinOnly == false) {
return false;
}
currStart += (1L << shift);
setNextRange(false);
currentRange.set(nextRange);
hasNext = true;
withinOnly = lastWithin != currStart;
if (withinOnly == false) advanceVariables();
return true;
}
private void nextRelation() {
double minLon = GeoPointField.decodeLongitude(currStart);
double minLat = GeoPointField.decodeLatitude(currStart);
double maxLon;
double maxLat;
boolean isWithin;
do {
maxLon = GeoPointField.decodeLongitude(currEnd);
maxLat = GeoPointField.decodeLatitude(currEnd);
isWithin = false;
// within or a boundary
if (boundary(minLat, maxLat, minLon, maxLon) == true) {
isWithin = within(minLat, maxLat, minLon, maxLon);
final int m;
if (isWithin == false || (m = shift % GeoPointField.PRECISION_STEP) == 0) {
setNextRange(isWithin == false);
advanceVariables();
break;
} else if (shift < 54) {
withinOnly = true;
shift = (short)(shift - m);
lastWithin = currEnd & ~((1L << shift) - 1);
setNextRange(false);
break;
}
}
// within cell but not at a depth factor of PRECISION_STEP
if (isWithin == true || (relationImpl.cellIntersectsMBR(minLat, maxLat, minLon, maxLon) == true && shift != maxShift)) {
// descend: currStart need not change since shift handles end of range
currEnd = currStart | (1L<<--shift) - 1;
} else {
advanceVariables();
minLon = GeoPointField.decodeLongitude(currStart);
minLat = GeoPointField.decodeLatitude(currStart);
}
} while(shift < 63);
}
private void setNextRange(final boolean boundary) {
nextRange.start = currStart;
nextRange.shift = shift;
nextRange.boundary = boundary;
}
private void advanceVariables() {
/** set next variables */
long shiftMask = 1L << shift;
// pop-up if shift bit is set
while ( (currStart & shiftMask) == shiftMask) {
shiftMask = 1L << ++shift;
}
final long shiftMOne = shiftMask - 1;
currStart = currStart & ~shiftMOne | shiftMask;
currEnd = currStart | shiftMOne;
}
@Override
protected final BytesRef peek() {
nextRange.fillBytesRef(nextSubRangeBRB);
return super.peek();
}
protected void seek(long term, short res) {
if (term < currStart && res < maxShift) {
throw new IllegalArgumentException("trying to seek backwards");
} else if (term == currStart) {
return;
}
shift = res;
currStart = term;
currEnd = currStart | ((1L<<shift)-1);
withinOnly = false;
}
@Override
protected void nextRange() {
hasNext = false;
super.nextRange();
}
@Override
protected final boolean hasNext() {
if (hasNext == true || nextWithin()) {
return true;
}
nextRelation();
if (currentRange.compareTo(nextRange) != 0) {
currentRange.set(nextRange);
return (hasNext = true);
}
return false;
}
@Override
protected final BytesRef nextSeekTerm(BytesRef term) {
while (hasNext()) {
nextRange();
if (term == null) {
return currentCell;
}
final int comparison = term.compareTo(currentCell);
if (comparison > 0) {
seek(prefixCodedToGeoCoded(term), (short)(64 - getPrefixCodedShift(term)));
continue;
}
return currentCell;
}
// no more sub-range enums available
return null;
}
@Override
protected AcceptStatus accept(BytesRef term) {
// range < term or range is null
while (currentCell == null || term.compareTo(currentCell) > 0) {
// no more ranges, be gone
if (hasNext() == false) {
return AcceptStatus.END;
}
// peek next range, if the range > term then seek
final int peekCompare = term.compareTo(peek());
if (peekCompare < 0) {
return AcceptStatus.NO_AND_SEEK;
} else if (peekCompare > 0) {
seek(prefixCodedToGeoCoded(term), (short)(64 - getPrefixCodedShift(term)));
}
nextRange();
}
return AcceptStatus.YES;
}
protected final class Range extends BaseRange {
public Range(final long start, final short res, final boolean boundary) {
super(start, res, boundary);
}
@Override
protected void fillBytesRef(BytesRefBuilder result) {
assert result != null;
geoCodedToPrefixCoded(start, shift, result);
}
}
}

View File

@ -1,3 +1,5 @@
package org.apache.lucene.spatial.geopoint.search;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@ -14,64 +16,189 @@
* 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.FilteredTermsEnum;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.spatial.geopoint.search.GeoPointMultiTermQuery.CellComparator;
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.geoCodedToPrefixCoded;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.prefixCodedToGeoCoded;
import static org.apache.lucene.spatial.geopoint.document.GeoPointField.getPrefixCodedShift;
/**
* Base class for {@link GeoPointNumericTermsEnum} and {@link GeoPointPrefixTermsEnum} which compares
* candidate GeoPointField encoded terms against terms matching the defined query criteria.
* Decomposes a given {@link GeoPointMultiTermQuery} into a set of terms that represent the query criteria. The terms
* are then enumerated by the {@link GeoPointTermQueryConstantScoreWrapper} and all docs whose GeoPoint fields match
* the prefix terms or pass the {@link GeoPointMultiTermQuery.CellComparator#postFilter} criteria are returned in the
* resulting DocIdSet.
*
* @lucene.experimental
*/
abstract class GeoPointTermsEnum extends FilteredTermsEnum {
protected final short maxShift;
final class GeoPointTermsEnum extends FilteredTermsEnum {
private final short maxShift;
private final BytesRefBuilder currentCellBRB = new BytesRefBuilder();
private final BytesRefBuilder nextSubRangeBRB = new BytesRefBuilder();
private final GeoPointMultiTermQuery.CellComparator relationImpl;
protected BaseRange currentRange;
protected BytesRef currentCell;
protected final BytesRefBuilder currentCellBRB = new BytesRefBuilder();
protected final BytesRefBuilder nextSubRangeBRB = new BytesRefBuilder();
private short shift; // shift mask
private long currStart; // range start as encoded long
private long currEnd; // range end as encoded long
protected final CellComparator relationImpl;
private final Range currentRange = new Range(-1, shift, true);;
private final Range nextRange = new Range(-1, shift, true);
private BytesRef currentCell;
GeoPointTermsEnum(final TermsEnum tenum, final GeoPointMultiTermQuery query) {
private boolean hasNext = false;
private boolean withinOnly = false;
private long lastWithin;
public GeoPointTermsEnum(final TermsEnum tenum, final GeoPointMultiTermQuery query) {
super(tenum);
this.maxShift = query.maxShift;
this.relationImpl = query.cellComparator;
// start shift at maxShift value (from computeMaxShift)
this.shift = maxShift;
final long mask = (1L << shift) - 1;
this.currStart = GeoPointField.encodeLatLon(query.minLat, query.minLon) & ~mask;
this.currEnd = currStart | mask;
}
static GeoPointTermsEnum newInstance(final TermsEnum terms, final GeoPointMultiTermQuery query) {
if (query.termEncoding == TermEncoding.PREFIX) {
return new GeoPointPrefixTermsEnum(terms, query);
} else if (query.termEncoding == TermEncoding.NUMERIC) {
return new GeoPointNumericTermsEnum(terms, query);
private boolean within(final double minLat, final double maxLat, final double minLon, final double maxLon) {
return relationImpl.cellWithin(minLat, maxLat, minLon, maxLon);
}
private boolean boundary(final double minLat, final double maxLat, final double minLon, final double maxLon) {
return shift == maxShift && relationImpl.cellIntersectsShape(minLat, maxLat, minLon, maxLon);
}
private boolean nextWithin() {
if (withinOnly == false) {
return false;
}
throw new IllegalArgumentException("Invalid GeoPoint TermEncoding " + query.termEncoding);
currStart += (1L << shift);
setNextRange(false);
currentRange.set(nextRange);
hasNext = true;
withinOnly = lastWithin != currStart;
if (withinOnly == false) advanceVariables();
return true;
}
public boolean boundaryTerm() {
if (currentCell == null) {
throw new IllegalStateException("GeoPointTermsEnum empty or not initialized");
private void nextRelation() {
double minLon = GeoPointField.decodeLongitude(currStart);
double minLat = GeoPointField.decodeLatitude(currStart);
double maxLon;
double maxLat;
boolean isWithin;
do {
maxLon = GeoPointField.decodeLongitude(currEnd);
maxLat = GeoPointField.decodeLatitude(currEnd);
isWithin = false;
// within or a boundary
if (boundary(minLat, maxLat, minLon, maxLon) == true) {
isWithin = within(minLat, maxLat, minLon, maxLon);
final int m;
if (isWithin == false || (m = shift % GeoPointField.PRECISION_STEP) == 0) {
setNextRange(isWithin == false);
advanceVariables();
break;
} else if (shift < 54) {
withinOnly = true;
shift = (short)(shift - m);
lastWithin = currEnd & ~((1L << shift) - 1);
setNextRange(false);
break;
}
}
// within cell but not at a depth factor of PRECISION_STEP
if (isWithin == true || (relationImpl.cellIntersectsMBR(minLat, maxLat, minLon, maxLon) == true && shift != maxShift)) {
// descend: currStart need not change since shift handles end of range
currEnd = currStart | (1L<<--shift) - 1;
} else {
advanceVariables();
minLon = GeoPointField.decodeLongitude(currStart);
minLat = GeoPointField.decodeLatitude(currStart);
}
} while(shift < 63);
}
private void setNextRange(final boolean boundary) {
nextRange.start = currStart;
nextRange.shift = shift;
nextRange.boundary = boundary;
}
private void advanceVariables() {
/** set next variables */
long shiftMask = 1L << shift;
// pop-up if shift bit is set
while ( (currStart & shiftMask) == shiftMask) {
shiftMask = 1L << ++shift;
}
return currentRange.boundary;
final long shiftMOne = shiftMask - 1;
currStart = currStart & ~shiftMOne | shiftMask;
currEnd = currStart | shiftMOne;
}
protected BytesRef peek() {
protected final BytesRef peek() {
nextRange.fillBytesRef(nextSubRangeBRB);
return nextSubRangeBRB.get();
}
abstract protected boolean hasNext();
protected void seek(long term, short res) {
if (term < currStart && res < maxShift) {
throw new IllegalArgumentException("trying to seek backwards");
} else if (term == currStart) {
return;
}
shift = res;
currStart = term;
currEnd = currStart | ((1L<<shift)-1);
withinOnly = false;
}
protected void nextRange() {
hasNext = false;
currentRange.fillBytesRef(currentCellBRB);
currentCell = currentCellBRB.get();
}
protected final boolean hasNext() {
if (hasNext == true || nextWithin()) {
return true;
}
nextRelation();
if (currentRange.compareTo(nextRange) != 0) {
currentRange.set(nextRange);
return (hasNext = true);
}
return false;
}
@Override
protected final BytesRef nextSeekTerm(BytesRef term) {
while (hasNext()) {
nextRange();
if (term == null) {
return currentCell;
}
final int comparison = term.compareTo(currentCell);
if (comparison > 0) {
seek(prefixCodedToGeoCoded(term), (short)(64 - getPrefixCodedShift(term)));
continue;
}
return currentCell;
}
// no more sub-range enums available
return null;
}
/**
* The two-phase query approach. {@link #nextSeekTerm} is called to obtain the next term that matches a numeric
* range of the bounding box. Those terms that pass the initial range filter are then compared against the
@ -82,48 +209,60 @@ abstract class GeoPointTermsEnum extends FilteredTermsEnum {
*/
@Override
protected AcceptStatus accept(BytesRef term) {
// validate value is in range
// range < term or range is null
while (currentCell == null || term.compareTo(currentCell) > 0) {
// no more ranges, be gone
if (hasNext() == false) {
return AcceptStatus.END;
}
// peek next sub-range, only seek if the current term is smaller than next lower bound
if (term.compareTo(peek()) < 0) {
// peek next range, if the range > term then seek
final int peekCompare = term.compareTo(peek());
if (peekCompare < 0) {
return AcceptStatus.NO_AND_SEEK;
} else if (peekCompare > 0) {
seek(prefixCodedToGeoCoded(term), (short)(64 - getPrefixCodedShift(term)));
}
// step forward to next range without seeking, as next range is less or equal current term
nextRange();
}
return AcceptStatus.YES;
}
/**
* Returns true if the current range term is a boundary of the query shape
*/
public boolean boundaryTerm() {
if (currentCell == null) {
throw new IllegalStateException("GeoPointTermsEnum empty or not initialized");
}
return currentRange.boundary;
}
protected boolean postFilter(final double lat, final double lon) {
return relationImpl.postFilter(lat, lon);
}
/**
* Internal class to represent a range along the space filling curve
*/
abstract class BaseRange implements Comparable<BaseRange> {
protected short shift;
protected long start;
protected boolean boundary;
protected final class Range implements Comparable<Range> {
private short shift;
private long start;
private boolean boundary;
BaseRange(final long lower, final short shift, boolean boundary) {
public Range(final long start, final short shift, final boolean boundary) {
this.boundary = boundary;
this.start = lower;
this.shift = shift;
}
this.start = start;
this.shift = shift; }
/**
* Encode as a BytesRef using a reusable object. This allows us to lazily create the BytesRef (which is
* quite expensive), only when we need it.
*/
abstract protected void fillBytesRef(BytesRefBuilder result);
protected void fillBytesRef(BytesRefBuilder result) {
assert result != null;
geoCodedToPrefixCoded(start, shift, result);
}
@Override
public int compareTo(BaseRange other) {
public int compareTo(Range other) {
final int result = Short.compare(this.shift, other.shift);
if (result == 0) {
return Long.compare(this.start, other.start);
@ -131,7 +270,7 @@ abstract class GeoPointTermsEnum extends FilteredTermsEnum {
return result;
}
protected void set(BaseRange other) {
protected void set(Range other) {
this.start = other.start;
this.shift = other.shift;
this.boundary = other.boundary;

View File

@ -22,7 +22,6 @@ import org.apache.lucene.geo.BaseGeoPointTestCase;
import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
/**
* random testing for GeoPoint query logic
@ -43,22 +42,22 @@ public class TestGeoPointQuery extends BaseGeoPointTestCase {
@Override
protected void addPointToDoc(String field, Document doc, double lat, double lon) {
doc.add(new GeoPointField(field, lat, lon, GeoPointField.PREFIX_TYPE_NOT_STORED));
doc.add(new GeoPointField(field, lat, lon, GeoPointField.TYPE_NOT_STORED));
}
@Override
protected Query newRectQuery(String field, double minLat, double maxLat, double minLon, double maxLon) {
return new GeoPointInBBoxQuery(field, TermEncoding.PREFIX, minLat, maxLat, minLon, maxLon);
return new GeoPointInBBoxQuery(field, minLat, maxLat, minLon, maxLon);
}
@Override
protected Query newDistanceQuery(String field, double centerLat, double centerLon, double radiusMeters) {
return new GeoPointDistanceQuery(field, TermEncoding.PREFIX, centerLat, centerLon, radiusMeters);
return new GeoPointDistanceQuery(field, centerLat, centerLon, radiusMeters);
}
@Override
protected Query newPolygonQuery(String field, Polygon... polygons) {
return new GeoPointInPolygonQuery(field, TermEncoding.PREFIX, polygons);
return new GeoPointInPolygonQuery(field, polygons);
}
// TODO: remove these once we get tests passing!

View File

@ -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 org.apache.lucene.document.Document;
import org.apache.lucene.search.Query;
import org.apache.lucene.geo.BaseGeoPointTestCase;
import org.apache.lucene.geo.Polygon;
import org.apache.lucene.geo.Rectangle;
import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import org.apache.lucene.spatial.geopoint.document.GeoPointField.TermEncoding;
import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
/**
* random testing for GeoPoint query logic (with deprecated numeric encoding)
* @deprecated remove this when TermEncoding.NUMERIC is removed
*/
@Deprecated
@SuppressCodecs("Direct") // can easily create too many postings and blow direct sky high
public class TestLegacyGeoPointQuery extends BaseGeoPointTestCase {
@Override
protected double quantizeLat(double lat) {
return GeoPointField.decodeLatitude(GeoPointField.encodeLatLon(lat, 0));
}
@Override
protected double quantizeLon(double lon) {
return GeoPointField.decodeLongitude(GeoPointField.encodeLatLon(0, lon));
}
@Override
protected void addPointToDoc(String field, Document doc, double lat, double lon) {
doc.add(new GeoPointField(field, lat, lon, GeoPointField.NUMERIC_TYPE_NOT_STORED));
}
@Override
protected Query newRectQuery(String field, double minLat, double maxLat, double minLon, double maxLon) {
return new GeoPointInBBoxQuery(field, TermEncoding.NUMERIC, minLat, maxLat, minLon, maxLon);
}
@Override
protected Query newDistanceQuery(String field, double centerLat, double centerLon, double radiusMeters) {
return new GeoPointDistanceQuery(field, TermEncoding.NUMERIC, centerLat, centerLon, radiusMeters);
}
@Override
protected Query newPolygonQuery(String field, Polygon... polygons) {
return new GeoPointInPolygonQuery(field, TermEncoding.NUMERIC, polygons);
}
// legacy encoding is too slow somehow for this random test, its not up to the task.
@Override
public void testRandomDistance() throws Exception {
assumeTrue("legacy encoding is too slow/hangs on this test", false);
}
@Override
public void testRandomDistanceHuge() throws Exception {
assumeTrue("legacy encoding is too slow/hangs on this test", false);
}
@Override
public void testSamePointManyTimes() throws Exception {
assumeTrue("legacy encoding goes OOM on this test", false);
}
// TODO: remove these once we get tests passing!
@Override
protected double nextLongitude() {
return GeoPointTestUtil.nextLongitude();
}
@Override
protected double nextLatitude() {
return GeoPointTestUtil.nextLatitude();
}
@Override
protected Rectangle nextBox() {
return GeoPointTestUtil.nextBox();
}
@Override
protected Polygon nextPolygon() {
return GeoPointTestUtil.nextPolygon();
}
}