public class LuceneGeospatialQueryConverter
extends java.lang.Object
The conversion assumes that each Lucene document optionally has associated with it a geographic
footprint (a geographic region representing the document's area of relevance) in the form of a
box (defined below). A geospatial query takes a query region (also in the form of a box) and
a spatial predicate (e.g., "overlaps
") and returns all documents that 1) have a geographic
footprint that 2) has the predicate relationship to the query region.
Formally, a box is a geographic region defined by north and south bounding coordinates (latitudes expressed in degrees north of the equator and in the range [-90,90]) and east and west bounding coordinates (longitudes expressed in degrees east of the Greenwich meridian and in the range [-180,180]). The north bounding coordinate must be greater than or equal to the south. The west bounding coordinate may be less than, equal to, or greater than the east; in the latter case, a box that crosses the ±180° meridian is described. As a special case, the set of all longitudes is described by a west bounding coordinate of -180 and an east bounding coordinate of 180.
Boxes must be represented in Lucene as four indexed, non-tokenized fields holding the
four bounding coordinates. In addition, in order to emulate numeric comparisons using lexicographic
comparisons, before insertion into Lucene bounding coordinates must be encoded using the encodeLatitude
and encodeLongitude
functions
supplied by this class.
Two limitations: first, this converter assumes that each Lucene document has at most one associated geographic footprint. Second, this converter assumes that no document footprint crosses the ±180° meridian. However, query regions that cross the ±180° meridian are allowed and are handled correctly, as are all discontinuities involving that meridian and the poles.
$Log: LuceneGeospatialQueryConverter.java,v $ Revision 1.5 2010/07/14 00:18:48 jweather -All Lucene-related classes have been upgraded to Lucene v3.0.2. Major changes include: --Search results are now returned in a new ResultDocList Object instead of a ResultDoc[] array. This provides for more efficient searching (does not require an additional loop over results as before) and expandability (methods can be added to the ResultDocList to support future fuctnionality) and better utilizes the built-in Lucene classes for search than before (TopDocs, Sort, etc.) --Uses Lucene Sort class for sorting at search time. Replaces logic that sorted results after the search (deprecated but still supported for backward-compatibility) - Final previous version was tagged in CVS with 'lucene_2_4_final_version' Revision 1.4 2009/01/08 00:40:36 jweather -A geospatial search query can now be conducted in the DDSWS service by supplying the following arguments: geoPredicate, geoBBNorth, geoBBWest, geoBBEast, geoBBSouth, geoClause. Previously, geospatial queries needed to be separately encoded and then supplied as part of the query (q) argument. -Added a 'code' attribute to the error response element in DDSWS 1.1 that indicates the type of error. This makes it possible to determine the reason why a request failed and respond appropriately to users. Error codes include noRecordsMatch, badArgument, badVerb, badQuery, notAuthorized, internalServerError. Note that, while this should not effect consumers of XML response from the service, the structure of the JSON output has changed slightly and my effect clients that use it. -Updated the JSON example client to handle the new error code data format. -If geospatial bounding box footprint extent crosses longitude 180/-180, the indexer now culls the search bounding box to the largest of one side or the other to be compatible with the search algorithm. -More robust error checking is now conducted in the indexer to ensure geospatial bounding box coordinates error free. If a bounding box is non-conformant, it is gracefully dropped from the given record. -In the DDSWS search service, if the query crosses the 180/-180 longitude it is split into two query regions, one on each side, joined by boolean clause. Revision 1.3 2008/05/24 00:44:35 jweather -fixed problem with geospatial tokens for search, introduced with lucene 2.0 upgrade -created EL functions for generating geospatial queries Revision 1.2 2007/07/05 22:29:34 jweather -Upgradded from Lucene v1.4.3 to Lucene v2.2.0 (code merged from lucene-2-upgrade-branch to head) Revision 1.1.6.1 2007/07/05 21:12:24 jweather -Updated Field BooleanQuery method calls to use Lucene 2.0 syntax Revision 1.1 2004/09/07 18:58:16 jweather The Lucene bounding box query converter/encoder, contributed by Greg Jenee at ADL Revision 1.1 2004/08/31 18:16:26 gjanee Initial revision
Modifier and Type | Method and Description |
---|---|
static org.apache.lucene.search.Query |
convertQuery(java.lang.String predicate,
java.lang.String north,
java.lang.String south,
java.lang.String east,
java.lang.String west)
Converts a geospatial query to a Lucene query.
|
static org.apache.lucene.search.Query |
convertQuery(java.lang.String northField,
java.lang.String southField,
java.lang.String eastField,
java.lang.String westField,
java.lang.String predicate,
double north,
double south,
double east,
double west)
Converts a geospatial query to a Lucene query.
|
static java.lang.String |
encodeLatitude(double latitude)
Encodes a latitude to a textual form that supports numeric ordering.
|
static java.lang.String |
encodeLatitude(java.lang.String latitude)
Encodes a latitude to a textual form that supports numeric ordering.
|
static java.lang.String |
encodeLongitude(double longitude)
Encodes a longitude to a textual form that supports numeric ordering.
|
static java.lang.String |
encodeLongitude(java.lang.String longitude)
Encodes a longitude to a textual form that supports numeric ordering.
|
static void |
main(java.lang.String[] args)
Test driver.
|
public static org.apache.lucene.search.Query convertQuery(java.lang.String predicate, java.lang.String north, java.lang.String south, java.lang.String east, java.lang.String west) throws java.lang.IllegalArgumentException, java.lang.NumberFormatException
predicate
- The spatial predicate, which must be "contains
", "overlaps
", or "within
".north
- The north bounding coordinate of the query region.south
- The south bounding coordinate of the query region.east
- The east bounding coordinate of the query region.west
- The west bounding coordinate of the query region.java.lang.NumberFormatException
- If unable to convert bounding coordinate String to doublejava.lang.IllegalArgumentException
- If predicate
is not one of the three supported spatial
predicates; if north
or south
are outside the range [-90,90]; if north
is less than south
; or if east
or west
are outside the range
[-180,180].public static org.apache.lucene.search.Query convertQuery(java.lang.String northField, java.lang.String southField, java.lang.String eastField, java.lang.String westField, java.lang.String predicate, double north, double south, double east, double west) throws java.lang.IllegalArgumentException
northField
- The Lucene field holding north bounding coordinates.southField
- The Lucene field holding south bounding coordinates.eastField
- The Lucene field holding east bounding coordinates.westField
- The Lucene field holding west bounding coordinates.predicate
- The spatial predicate, which must be "contains
", "overlaps
", or "within
".north
- The north bounding coordinate of the query region.south
- The south bounding coordinate of the query region.east
- The east bounding coordinate of the query region.west
- The west bounding coordinate of the query region.java.lang.IllegalArgumentException
- If predicate
is not one of the three supported spatial
predicates; if north
or south
are outside the range [-90,90]; if north
is less than south
; or if east
or west
are outside the range
[-180,180].public static java.lang.String encodeLatitude(double latitude) throws java.lang.IllegalArgumentException
latitude
- The latitude.java.lang.IllegalArgumentException
- If latitude
is outside the range [-90,90].public static java.lang.String encodeLatitude(java.lang.String latitude) throws java.lang.IllegalArgumentException, java.lang.NumberFormatException
latitude
- The latitude.java.lang.NumberFormatException
- If unable to convert latitude String to doublejava.lang.IllegalArgumentException
- If latitude
is outside the range [-90,90].public static java.lang.String encodeLongitude(double longitude) throws java.lang.IllegalArgumentException
longitude
- The longitude.java.lang.IllegalArgumentException
- If longitude
is outside the range [-180,180].public static java.lang.String encodeLongitude(java.lang.String longitude) throws java.lang.IllegalArgumentException, java.lang.NumberFormatException
longitude
- The longitude.java.lang.NumberFormatException
- If unable to convert longitute String to doublejava.lang.IllegalArgumentException
- If longitude
is outside the range [-180,180].public static void main(java.lang.String[] args)
args
- The command line arguments